设计模式21---设计模式之享元模式(Flyweight)(结构型)
1.讲解享元模式(结构型)
1.1享元模式定义
运用共享技术有效地支持大量细粒度对象.
享元:把内部状态共享出来
1.2享元模式要点
重点在于分离变与不变。
把一个对象的状态分为内部状态和外部状态,内部状态不变,外部状态可变。
内部状态就是在对象里通过内部方法管理,而外部信息可以在通过外部删除或者保存。
1.3享元模式的结构图以及说明
享元模式所涉及的角色有抽象享元角色、具体(单纯)享元角色、复合享元角色、享员工厂角色,以及客户端角色等。
抽象享元角色(Flyweight):此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口或抽象类。那些需要外蕴状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。
复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。这个角色一般很少使用。
享元工厂(FlyweightFactoiy)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。
客户端(Client)角色:本角色还需要自行存储所有享元对象的外蕴状态。
1.4享元模式的示例代码
package demo19.flyweight.example2; /***
* 享元接口,通过这个接口享元可以接受并作用于外部状态
*/
public interface Flyweight {
/**
* 示例操作,传入外部状态
*
* @param extrinsicState
* 示例参数,外部状态
*/
public void operation(String extrinsicState);
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* 享元对象
*/
public class ConcreteFlyweight implements Flyweight {
/**
* 示例,描述内部状态
*/
private String intrinsicState; /**
* 构造方法,传入享元对象的内部状态的数据
*
* @param state
* 享元对象的内部状态的数据
*/
public ConcreteFlyweight(String state) {
this.intrinsicState = state;
} public void operation(String extrinsicState) {
// 具体的功能处理,可能会用到享元内部、外部的状态
}
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* 不需要共享的Flyweight对象, 通常是将被共享的享元对象作为子节点,组合出来的对象
*/
public class UnsharedConcreteFlyweight implements Flyweight {
/**
* 示例,描述对象的状态
*/
private String allState; public void operation(String extrinsicState) {
// 具体的功能处理
}
}
**************************************************************************************************
package demo19.flyweight.example2; import java.util.HashMap;
import java.util.Map; /**
* 享元工厂
*/
public class FlyweightFactory {
/**
* 缓存多个flyweight对象,这里只是示意一下
*/
private Map<String, Flyweight> fsMap = new HashMap<String, Flyweight>(); /**
* 获取key对应的享元对象
*
* @param key
* 获取享元对象的key,只是示意
* @return key对应的享元对象
*/
public Flyweight getFlyweight(String key) {
// 这个方法里面基本的实现步骤如下:
// 1:先从缓存里面查找,是否存在key对应的Flyweight对象
Flyweight f = fsMap.get(key);
// 2:如果存在,就返回相对应的Flyweight对象
if (f == null) {
// 3:如果不存在
// 3.1:创建一个新的Flyweight对象
f = new ConcreteFlyweight(key);
// 3.2:把这个新的Flyweight对象添加到缓存里面
fsMap.put(key, f);
// 3.3:然后返回这个新的Flyweight对象
}
return f;
}
}
**************************************************************************************************
package demo19.flyweight.example2; /**
* Client对象,通常会维持一个对flyweight的引用, 计算或存储一个或多个flyweight的外部状态
*/
public class Client {
// 具体的功能处理
}
1.5享元模式的本质
分离与共享
1.6享元模式的优缺点
优点:减少对象数量,节省内存空间
缺点:维护共享对象,需要额外开销
1.7何时选用?
1.7.1如果一个程序大量使用了细粒度对象
1.7.2如果对象的大多数状态都可以变为外部状态(比如可以通过计算得到),或是从外部传入等,可以使用享元模式进行内部状态和外部状态的分离。
2.使用享元模式解决的案例
比如围棋有300颗棋子,用一般的设计模式,创建一个类,每个棋子都用一个对象的话,那就会非常麻烦,并且各自定义各自在棋盘的位置.....等等,而使用 亨元模式 来实现的话,就用两个对象 :一个黑,一个白。这样就可以了,至于棋子的方位不同,那只是对象的不同的外部表现形式或者说是外部状态。这样三百多个对象就减到了两个对象。享元模式以共享的方式高效地支持大量的细粒度对象,说的再具体一些是将所有具有相同状态的对象指向同一个引用,从而解决了系统在创建大量对象时所带来的内存压力。
示例代码如下
2.1享元接口,通过这个接口享元可以接受并作用于外部状态
package demo19.flyweight.example1; /**
* 抽象棋子的接口
*
* @author 王玉超
* @date 2013-7-31
*/
public interface IChessFlyWeight {
public String getColor(); public void show(Point point);
}
2.2享元对象
package demo19.flyweight.example1; /**
* 具体棋子对象的实现类
*
* @author 王玉超
* @date 2013-7-31
*/
public class ConcreteChessFlyWeight implements IChessFlyWeight { private String color; public String getColor() {
return color;
} public ConcreteChessFlyWeight(String color) {
this.color = color;
} public void show(Point point) {
System.out.println("This Chess is " + color + ",Point X:" + point.getX() + " Y:" + point.getY());
}
}
2.3不需要共享的对象,即外部动态该变量
package demo19.flyweight.example1; /**
* 棋子外部动态变动的属性
*
* @author 王玉超
* @date 2013-7-31
*/
public class Point {
private int x;
private int y; public Point(int x, int y) {
this.x = x;
this.y = y;
} public int getX() {
return x;
} public int getY() {
return y;
} @Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
2.4享元模型对象工厂
package demo19.flyweight.example1; import java.util.HashMap;
import java.util.Map; /**
* 享元模型对象工厂
*
* @author 王玉超
* @date 2013-7-31
*/
public class ChessFlyWeightFactory { private Map<String, IChessFlyWeight> chessMap = new HashMap<String, IChessFlyWeight>(); public IChessFlyWeight getChess(String key) {
if (!chessMap.containsKey(key)) {
chessMap.put(key, new ConcreteChessFlyWeight(key));
} return chessMap.get(key);
}
}
2.5客户端调用
package demo19.flyweight.example1; public class Client {
public static void main(String[] args) {
ChessFlyWeightFactory factory = new ChessFlyWeightFactory();
Point point; String white = "白";
String black = "黑"; point = new Point(0, 0);
factory.getChess(white).show(point); point = new Point(10, 10);
factory.getChess(white).show(point); point = new Point(100, 100);
factory.getChess(black).show(point); point = new Point(200, 200);
factory.getChess(black).show(point);
}
}
代码仔细对应示例代码以后,发现没有【不需要共享的Flyweight对象】实际上,就是Point类,只不过,Point类没有继承Flyweight接口而已。那个不需要共享的对象一般很少用。
设计模式21---设计模式之享元模式(Flyweight)(结构型)的更多相关文章
- 享元模式 FlyWeight 结构型 设计模式(十五)
享元模式(FlyWeight) “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...
- 设计模式(十)享元模式Flyweight(结构型)
设计模式(十)享元模式Flyweight(结构型) 说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释 ...
- 设计模式11: Flyweight 享元模式(结构型模式)
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
- Java设计模式15:常用设计模式之享元模式(结构型模式)
1. Java之享元模式(Flyweight Pattern) (1)概述: 享元模式是对象池的一种实现,英文名为"Flyweight",代表轻量级的意思.享元模式用来 ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- 设计模式 笔记 享元模式 Flyweight
//---------------------------15/04/20---------------------------- //Flyweight 享元模式------对象结构型模式 /* 1 ...
- 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...
- 设计模式-11享元模式(Flyweight Pattern)
1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...
- 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 二十四种设计模式:享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...
随机推荐
- 神秘链接__proto__是什么鬼
_proto_实际上是某个实例对象的隐藏属性,而prototype是其构造器函数(或者说‘类’)的原型属性; function Mine() {} var hi = new Function(), ...
- Jsoup库 解析DOM文档
DOM文档包括 HTML, XML等等 下载: http://jsoup.org/download Jsoup 获取数据的方式 //html 文本, url, 本地html String html = ...
- UFLDL实验报告3:Self-taught
Self-taught 自我学习器实验报告 1.Self-taught 自我学习实验描述 自我学习是无监督特征学习算法,自我学习意味着算法能够从未标注数据中学习,从而使机器学习算法能够获得更大数量的数 ...
- 简单学C——第一天
基本功 一.数据类型: 在C语言中,有数据类型这一说法.为何有这一说法?是因为在现实生活中存在着不同的数据,(例如整数,小数,字符即a b c d , . ; " 之类).由于计算机中所有 ...
- Egret 纹理、计时器
1. 九宫切 典型例子就是圆角矩形的拉伸问题. 先去P一张绿色的圆角矩形. private createGameScene():void { var box:egret.Bitmap = new eg ...
- Cow Exhibition
poj2184:http://poj.org/problem?id=2184 题意:给你n头牛,每头牛有一个S值和一个F值,现在的问题是,要你选出其中的一些牛求出S+T的最大值.但是要保证总的s> ...
- C 和 OC 字符串转换 NSString 和 char * 转换 const char* 与 char *
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { char *s = "He ...
- vsphere 出现“在主机的当前连接状况下不允许执行该操作”
问题: 登录vsphere client启动虚拟机出现“在主机的当前连接状况下不允许执行该操作” 解决方法: 1.选择主机->右键->断开 2.选择主机->右键->连接 3.在 ...
- PSoC电容式触摸感应技术
PSoC是由Cypress半导体公司推出的具有数字和模拟混合处理能力的可编程片上系统芯片,某些系列的PSoC(如CY8C21X34系列),由于其内部配备的特殊资源,使得它可以很容易地实现电容式触摸感应 ...
- JPA概要
1 JPA概述 JPA(Java Persistence API,Java持久化API),定义了对象-关系映射(ORM)以及实体对象持久化的标准接口. JPA是JSR-220(EJB3.0)规范的一部 ...