设计模式之22享元模式(笔记)
2012-05-20 15:26
246 查看
1 定义:
1.1 定义:Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可以有效地支持大量的细粒度的对象。)
细粒度对象:不可避免地使得对象数量多且性质相近,可将这些对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。
内部状态:对象可共享出来的信息,存储在享元对象的内部并且不会随环境改变而改变。
外部状态:对象得以依赖的一个标记:随环境改变而改变、不可以共享的状态,享元对象的外蕴状态必须由由端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。
(原书在此点的解释和举例,让人很纠结:举例不当,而且此点解释令人生疑。)
(理解举例:享元模式在编辑器系统中大量使用。一个文编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字体风格等其他信息则是外蕴状态。比如,字母a可以出现在文本的很多地方,虽然这些字母a的位置和字体风格不同,但是所有这些地方使用的都是同一个字母对象。这样一来,字母对象就可以在整个系统中共享。)
1.2 通用类图:
Flyweight——抽象享元角色
一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
ConcreteFlyweight——具体享元角色
实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态,这是不允许的。
UnsharedConcreteFlyweight——不可共享的享元角色
不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
FlyweightFactory——享元工厂
职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方式。
1.3 通用代码:
错误举例:
结果:
Pos: line=10, col=20, color = RED 1234567890
Pos: line=20, col=20, color = BLUE 1234567890
池中数量为:1
注意上述是一个误用(错例)。
享元模式只是想将对象细粒度化,将可共享部分缓存起来,以复用。而上例中将对象的共享部分与非共享部分融合在一起是错误的,因为这样则会导致整体的复用,在一个对象未被消费时,其会被另一次复用覆盖。而这并非复用的本质。
下例正确:
2 优点
2.1 大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能;
3 缺点
3.1 提高了系统的复杂性:需要分离出外部状态和内部状态;
4 应用场景
4.1 系统存在大量的相似对象;
4.2 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份;
4.3 需要缓冲池的场景。
5 注意事项
暂无
6 扩展
暂无
7 范例
暂无
1.1 定义:Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可以有效地支持大量的细粒度的对象。)
细粒度对象:不可避免地使得对象数量多且性质相近,可将这些对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。
内部状态:对象可共享出来的信息,存储在享元对象的内部并且不会随环境改变而改变。
外部状态:对象得以依赖的一个标记:随环境改变而改变、不可以共享的状态,享元对象的外蕴状态必须由由端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。
(原书在此点的解释和举例,让人很纠结:举例不当,而且此点解释令人生疑。)
(理解举例:享元模式在编辑器系统中大量使用。一个文编辑器往往会提供很多种字体,而通常的做法就是将每一个字母做成一个享元对象。享元对象的内蕴状态就是这个字母,而字母在文本中的位置和字体风格等其他信息则是外蕴状态。比如,字母a可以出现在文本的很多地方,虽然这些字母a的位置和字体风格不同,但是所有这些地方使用的都是同一个字母对象。这样一来,字母对象就可以在整个系统中共享。)
1.2 通用类图:
Flyweight——抽象享元角色
一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
ConcreteFlyweight——具体享元角色
实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态,这是不允许的。
UnsharedConcreteFlyweight——不可共享的享元角色
不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
FlyweightFactory——享元工厂
职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方式。
1.3 通用代码:
错误举例:
package _22_Flyweight; public abstract class Flyweight { private String intrinsic; protected String extrinsic; public Flyweight(String intrinsic) { this.intrinsic = intrinsic; } public String getIntrinsic() { return intrinsic; } public abstract void operate(); public String getExtrinsic() { return extrinsic; } public void setExtrinisic(String extrinsic) { this.extrinsic = extrinsic; } } public class ConcreteFlyweight1 extends Flyweight { public ConcreteFlyweight1(String intrinsic) { super(intrinsic); } public void operate() { } } public class ConcreteFlyweight2 extends Flyweight { public ConcreteFlyweight2(String intrinsic) { super(intrinsic); } public void operate() { } } public class FlyweightFactory { private static HashMap<String, Flyweight> pool = new HashMap<String, Flyweight>(); public static Flyweight getFlyweight1(String Intrinsic) { // 需要返回的对象 Flyweight flyweight = pool.get(Intrinsic); if (flyweight == null) { flyweight = new ConcreteFlyweight1(Intrinsic); pool.put(Intrinsic, flyweight); } return flyweight; } public static int getSize() { return pool.size(); } } public class Client { public static void main(String args[]) { Flyweight fly1 = FlyweightFactory.getFlyweight1("1234567890"); fly1.setExtrinisic("Pos: line=10, col=20, color = RED"); System.out.println(fly1.getExtrinsic() + " " + fly1.getIntrinsic()); Flyweight fly2 = FlyweightFactory.getFlyweight1("1234567890"); fly2.setExtrinisic("Pos: line=20, col=20, color = BLUE"); System.out.println(fly2.getExtrinsic() + " " + fly2.getIntrinsic()); System.out.println("池中数量为:" + FlyweightFactory.getSize()); } }
结果:
Pos: line=10, col=20, color = RED 1234567890
Pos: line=20, col=20, color = BLUE 1234567890
池中数量为:1
注意上述是一个误用(错例)。
享元模式只是想将对象细粒度化,将可共享部分缓存起来,以复用。而上例中将对象的共享部分与非共享部分融合在一起是错误的,因为这样则会导致整体的复用,在一个对象未被消费时,其会被另一次复用覆盖。而这并非复用的本质。
下例正确:
package _22_Flyweight.right; public abstract class Flyweight { private String intrinsic; public Flyweight(String intrinsic) { this.intrinsic = intrinsic; } public String getIntrinsic() { return intrinsic; } public abstract void operate(); } public class ConcreteFlyweightContent extends Flyweight { public ConcreteFlyweightContent(String intrinsic) { super(intrinsic); } public void operate() { } } public class FlyweightFactory { private static HashMap<String, Flyweight> pool = new HashMap<String, Flyweight>(); public static Flyweight getFlyweight1(String Intrinsic) { // 需要返回的对象 Flyweight flyweight = pool.get(Intrinsic); if (flyweight == null) { flyweight = new ConcreteFlyweightContent(Intrinsic); pool.put(Intrinsic, flyweight); } return flyweight; } public static int getSize() { return pool.size(); } } public class WPS { Flyweight fly; List<String> formats = new ArrayList<String>(); List<Flyweight> contents = new ArrayList<Flyweight>(); public void addLine(String format, Flyweight content) { formats.add(format); contents.add(content); } public void show() { for (int i = 0; i < formats.size(); i++) { System.out.print(formats.get(i) + "\t\t"); System.out.println(contents.get(i).getIntrinsic()); } } } public class Client { public static void main(String args[]) { WPS mydoc = new WPS(); mydoc.addLine("Pos: line=1, col=20, color = RED", FlyweightFactory.getFlyweight1("1234567890")); mydoc.addLine("Pos: line=2, col=20, color = GREEN", FlyweightFactory.getFlyweight1("1234567890")); mydoc.addLine("Pos: line=3, col=20, color = BLUE", FlyweightFactory.getFlyweight1("1234567890")); mydoc.show(); System.out.println("池中数量为:" + FlyweightFactory.getSize()); } }
2 优点
2.1 大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能;
3 缺点
3.1 提高了系统的复杂性:需要分离出外部状态和内部状态;
4 应用场景
4.1 系统存在大量的相似对象;
4.2 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份;
4.3 需要缓冲池的场景。
5 注意事项
暂无
6 扩展
暂无
7 范例
暂无
相关文章推荐
- 设计模式学习笔记(十二)——Flyweight享元模式
- 设计模式笔记(22)---状态模式(行为型)
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- 设计模式学习笔记——享元模式
- 设计模式学习笔记八:享元模式
- 设计模式笔记(22)---状态模式(行为型)
- HeadFirst 设计模式学习笔记16--享元模式拾零
- 设计模式学习笔记--Flyweight享元模式
- 设计模式学习笔记(二十二)—FlyWeight享元模式
- 设计模式学习笔记八:享元模式
- 设计模式学习笔记(二十:享元模式)
- 【HeadFirst 设计模式学习笔记】15 享元模式拾零
- 设计模式复习笔记 (11)结构型模式:享元模式
- 【js设计模式笔记---享元模式】
- 设计模式学习笔记——享元模式
- [设计模式笔记]二. 结构型模式--12.Flyweight模式(享元模式)(一)
- 设计模式学习笔记(十二)——Flyweight享元模式
- 设计模式笔记--享元模式
- 设计模式利剑22--享元模式
- 【学习笔记javascript设计模式与开发实践(享元模式)----12】