七种常见结构型模式的描述总结与代码分析 (6)

「Client」:电源键,可控制开机、关机

public class Client { Computer computer = new Computer(); @Test public void boot(){ computer.boot(); } @Test public void shutdown(){ computer.shutdown(); } } 模式分析

优点:

实现了客户端与子系统的低耦合,使得子系统的变化不会影响客户端,只需要调整外观类即可。

对客户端屏蔽子系统,减少了客户端处理的对象数目,操作变得更简单。

降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。

缺点:

不能很好的限制客户端对子系统的使用,如果对其做了太多限制会降低可变性和灵活性。

在不引入「抽象外观类」的情况下,如果增加新的子系统,需要修改外观类代码,违背了「开闭原则」

适用场景

当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。

客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。

在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。

六、享元模式(Flyweight) 基本介绍

享元模式(Flyweight Pattern)也叫蝇量模式,运用共享技术有效地支持大量细粒度对象的复用。常用于系统底层开发,解决系统性能问题。例如数据库连接池,里面都是创建好的连接对象,如果有我们需要的,直接拿来用,避免重新创建,可以解决重复对象对内存造成浪费的问题

内部状态和外部状态

享元模式提出了细粒度和共享对象,这里就涉及了内部状态和外部状态的概念,即可以把对象的信息分为两个部分:内部状态和外部状态

内部状态(Intrinsic State):可以共享的相同内容

外部状态(Extrinsic State):需要外部环境来设置的不能共享的内容

举个栗子,围棋理论上有 361 个位置可以放棋子,每盘棋可能会产生两三百个棋子对象,由于内存有限,一台服务器很难支持更多玩家进行围棋对战,如果用享元模式来处理棋子,将棋子的颜色(黑与白)作为内部状态,棋子的位置(不确定)作为外部状态,就可以将棋子对象减少到两个实例(黑棋、白棋),这样就可以很好的解决内存开销问题。

模式结构

七种常见结构型模式的描述总结与代码分析

Flyweight:抽象享元类

ConcreteFlyweight:具体享元类

UnsharedConcreteFlyweight:非共享具体享元类

FlyweightFactory:享元工厂类

举例说明

一个开发团队接了这样的项目,客户希望做一个产品展示网站,但网站需要有多种发布形式,每个用户可以以新闻形式发布、以博客形式发布、以微信公众号形式发布...

「抽象享元类」

public abstract class AbstractWebsite { public abstract void publish(User user); }

「非共享具体享元类」

public class User { private String name; public User(String name) { this.name = name; } public String getName() { return name; } }

「具体享元类」

public class ConcreteWebsite extends AbstractWebsite { /** * 发布类型 */ private String type = ""; public ConcreteWebsite(String type) { this.type = type; } /** * 发布 */ @Override public void publish(User user) { System.out.println("用户「"+user.getName()+"」发布的网站形式为「" + type+"」"); } }

「享元工厂类」

public class WebsiteFactory { /** * 以 HashMap 作为对象池 */ private Map<String, ConcreteWebsite> pool = new HashMap<>(); /** * 从对象池中返回指定类型的对象,没有则创建 */ public AbstractWebsite getWebsite(String type) { if (!pool.containsKey(type)) { pool.put(type, new ConcreteWebsite(type)); } return pool.get(type); } /** * 计算对象池中对象的个数 */ public int count() { return pool.size(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywpyx.html