设计模式-享元模式
设计模式-享元模式
1、概念
在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建
2、优点大大减少对象的创建,降低系统的内存,使效率提高
3、缺点提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱
4、使用场景
1、系统中有大量对象。
2、这些对象消耗大量内存。
3、这些对象的状态大部分可以外部化。
4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象中剔除出来时,每一组对象都可以用一个对象来代替。
5、系统不依赖于这些对象身份,这些对象是不可分辨的。
5、角色
(1) 抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当。
(2) 具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。
(3) 享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键!
6、案例描述
本次采用象棋作为案例:象棋通常有两种颜色,如白色和黑色,每种颜色有16个棋子。这里可以分析棋子一种颜色的字是不一样的
(外部状态),颜色是一样的(内部状态),下面就来实现下
抽象享元角色:
/** * Created by laizhiyuan on 2017/7/28. * * <p> * 设计模式 - 享元模式 - 抽象享元角色(棋子抽象) * </p> */ public abstract class AbstractChess { /** * 颜色 内部状态(多个对象相同部分) */ private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } /** * 这里传入外部状态 * @param font */ public void string(String font) { System.out.println("我是象棋" + color + " " +font); } }
具体享元角色:
/** * Created by laizhiyuan on 2017/7/28. * * 设计模式 - 享元模式 - 享元具体角色(棋子) */ public class ConcreteChess extends AbstractChess{ }享元工厂角色:
/** * Created by laizhiyuan on 2017/7/28. * * <p> * 设计模式 - 享元模式 - 享元工厂角色(生成棋子工厂) * </p> */ public class ChessFlyweightFactory { private Map<String, AbstractChess> chessMap = new HashMap<String, AbstractChess>(); public AbstractChess build(String color, Font font){ AbstractChess chess = chessMap.get(color); if (chess == null){ chess = new ConcreteChess(); chess.setColor(color); chessMap.put(chess.getColor(), chess); } chess.string(font.getFont()); return chess; } public int getCount(){ return chessMap.size(); } }
外部状态辅助类:
/** * Created by laizhiyuan on 2017/7/28. * * 设计模式 - 享元模式 - 外部状态 */ public class Font { private String font; public Font(String font) { this.font = font; } public String getFont() { return font; } }
9、测试
/** * Created by laizhiyuan on 2017/7/28. * * 设计模式 - 享元模式 - 测试 */ public class Main { public static void main(String[] args) { Font font = new Font("将"); Font font1 = new Font("車"); Font font2 = new Font("马"); Font font3 = new Font("象"); ChessFlyweightFactory flyweightFactory = new ChessFlyweightFactory(); AbstractChess chess = flyweightFactory.build("白色", font); AbstractChess chess1 = flyweightFactory.build("白色", font1); AbstractChess chess2 = flyweightFactory.build("白色", font2); AbstractChess chess3 = flyweightFactory.build("白色", font3); AbstractChess chess4 = flyweightFactory.build("黑色", font); AbstractChess chess5 = flyweightFactory.build("黑色", font1); AbstractChess chess6 = flyweightFactory.build("黑色", font2); AbstractChess chess7 = flyweightFactory.build("黑色", font3); System.out.println("总共生成对象为" + flyweightFactory.getCount()); } }
10、控制台输出