享元模式
场景:内存属于稀缺资源,不要随便浪费。如果有很多完全相同或相似的对象,
我们可以通过享元模式,节省内存。
核心:享元模式以共享的方式高效地支持大量细粒度对象的重用
享元对象能做到共享的关键是区分了内部状态和外部状态
内部状态:可以共享,不会随环境变化而变化
外部状态:不可以共享,会随环境变换而变化
享元模式实现:
FlyweightFactory享元工厂类
创建并管理享元对象,享元池一般设计成键值对
FlyWeight抽象享元类
通常是一个接口或抽象类,声明公共方法,这些方法可以
向外界提供对象的内部状态,设置外部状态
ConcreteFlyWeight具体享元类
为内部状态提供成员变量进行存储
UnsharedConcreteFlyWeight非共享享元类
不能被共享的子类可以设计为非共享享元类
优点:
极大减少内存中对象的数量
相同或相似对象内存中只存一份,极大的节约资源,提高系统性能
外部状态相对独立,不影响内部状态
缺点:
模式较复杂,使程序逻辑复杂化
为了节省内存,共享了内部状态,分离出外部状态,而读取外部
状态使运行时间变长,用时间换空间。
1 package com.luruixiao.pattern.flyweight; 2 /** 3 * 享元类 4 * @author lenovo 5 *FlyWeight抽象享元类 6 通常是一个接口或抽象类,声明公共方法,这些方法可以 7 向外界提供对象的内部状态,设置外部状态 8 */ 9 public interface ChessFlyWeight { 10 void setColor(String c); 11 String getColor(); 12 void display(Coordinate c); 13 } 14 15 /** 16 * ConcreteFlyWeight具体享元类 17 为内部状态提供成员变量进行存储 color 18 * @author lenovo 19 * 20 */ 21 class ConcreteChess implements ChessFlyWeight{ 22 private String color; 23 24 public ConcreteChess() { 25 super(); 26 } 27 public ConcreteChess(String color) { 28 super(); 29 this.color = color; 30 } 31 @Override 32 public void setColor(String c) { 33 this.color = c; 34 } 35 36 @Override 37 public String getColor() { 38 return this.color; 39 } 40 41 @Override 42 public void display(Coordinate c) { 43 System.out.println("棋子的颜色:"+this.color); 44 System.out.println("棋子的位置:"+ c.getX() + " " + c.getY()); 45 } 46 } 47 48 package com.luruixiao.pattern.flyweight; 49 /** 50 * UnsharedConcreteFlyWeight非共享享元类 51 不能被共享的子类可以设计为非共享享元类 52 * @author lenovo 53 * 54 */ 55 public class Coordinate { 56 private int x; 57 private int y; 58 public Coordinate(int x, int y) { 59 super(); 60 this.x = x; 61 this.y = y; 62 } 63 public Coordinate() { 64 super(); 65 } 66 public int getX() { 67 return x; 68 } 69 public void setX(int x) { 70 this.x = x; 71 } 72 public int getY() { 73 return y; 74 } 75 public void setY(int y) { 76 this.y = y; 77 } 78 79 } 80 81 package com.luruixiao.pattern.flyweight; 82 83 import java.util.HashMap; 84 import java.util.Map; 85 /** 86 * 享元工厂(很重要) 87 * FlyweightFactory享元工厂类 88 创建并管理享元对象,享元池一般设计成键值对 89 * @author lenovo 90 * 91 */ 92 public class ChessFlyWeightFactory { 93 private static Map<String, ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>(); 94 95 public static ChessFlyWeight getChess(String color) { 96 if(map.get(color)!=null) { 97 return map.get(color); 98 }else { 99 ChessFlyWeight chess = new ConcreteChess(color); 100 map.put(color, chess); 101 return chess; 102 } 103 } 104 } 105 106 package com.luruixiao.pattern.flyweight; 107 108 public class Client { 109 public static void main(String[] args) { 110 ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色"); 111 ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色"); 112 chess1.display(new Coordinate(20,23)); 113 chess2.display(new Coordinate(10,23)); 114 System.out.println(chess1); 115 System.out.println(chess2); 116 } 117 }