设计模式——享元模式
享元模式: 场景:内存属于稀缺资源,如果有很多个完全相同或相似的对象,我们可以通过享元模式来节省内存。
核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。 享元对象能做到共享的关键字是区分了内部状态和外部状态。
内部状态:可以共享,不会随着环境变化而改变。
外部状态:不可以共享,会随着环境变化而改变。
享元模式的实现:
1.FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对
2.FlyWeight抽象享元类:通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置对象的外部状态。
3.ConcreteFlyweight具体享元类:为内部状态提供的成员变量进行存储。
4.UnsharedConcreteFlyWeight非共享享元类:不能被共享的子类可以设计成为非共享享元类。
应用场景:线程池、数据库连接池、String类的设计。
优点:极大的减少内存中对象的数量。相同或相似的对象内存中只有一份,一个实例可以提供许多虚拟实例,极大的节约资源,提高系统的性能。
外部状态相对独立,不影响内部状态。
缺点:模式较复杂。使程序的逻辑复杂化,每次读取外部状态使运行时间变长,用时间换取了空间。
一旦实现了享元模式,单个逻辑实例将无法拥有独立的行为。
看一个简单明了的Demo:
/** * 享元类 * @author wxisme * */ public interface FlyWeight { void setSex(String sex); String getSex(); void display(Character c); } /** * 具体享元类 获取内部状态、设置外部状态 * @author wxisme * */ class HumanFlyWeight implements FlyWeight { private String sex; public HumanFlyWeight(String sex) { super(); this.sex = sex; } @Override public void setSex(String sex) { this.sex = sex; } @Override public String getSex() { return sex; } @Override public void display(Character c) { System.out.println(c.getCharacter() + "的" + sex + "。"); } } /** * 外部状态 * @author wxisme * */ public class Character { private String character; public Character(String character) { super(); this.character = character; } public String getCharacter() { return character; } public void setCharacter(String character) { this.character = character; } } import java.util.HashMap; import java.util.Map; /** * 享元工厂类 * @author wxisme * */ public class HumanFlyWeightFactory { static Map<String, FlyWeight> map = new HashMap<>(); public static FlyWeight getHuman(String sex) { if(map.get(sex) != null) { return map.get(sex); } else { FlyWeight h = new HumanFlyWeight(sex); map.put(sex, h); return h; } } } public class Client { public static void main(String[] args) { HumanFlyWeightFactory factory = new HumanFlyWeightFactory(); //实质是共享相同的内部状态,封装变化的外部状态,节省资源。 FlyWeight flyweight1 = factory.getHuman("女人"); FlyWeight flyweight2 = factory.getHuman("女人"); //两个只包含相同内部状态的对象其实是一个对象。 System.out.println(flyweight1); System.out.println(flyweight2); //设置变化的外部状态。 flyweight1.display(new Character("性感")); flyweight2.display(new Character("漂亮")); } }
运行结果:
com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
性感的女人。
漂亮的女人。
作者:Pickle
声明:对于转载分享我是没有意见的,出于对博客园社区和作者的尊重一定要保留原文地址哈。
致读者:坚持写博客不容易,写高质量博客更难,我也在不断的学习和进步,希望和所有同路人一道用技术来改变生活。觉得有点用就点个赞哈。