第 8 卷
不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
- FlyweightFactory——享元工厂
职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方法。
享元工厂的代码:
public class FlyweightFactory { //定义一个池容器
private staticHashMap<String,Flyweight> pool= new HashMap<String,Flyweight>();
//享元工厂 public static Flyweight getFlyweight(String Extrinsic){
//需要返回的对象 Flyweight flyweight = null;
//在池中没有该对象 if(pool.containsKey(Extrinsic)){
flyweight = pool.get(Extrinsic);
}else{ //根据外部状态创建享元对象
flyweight = new ConcreteFlyweight1(Extrinsic);
//放置到池中 pool.put(Extrinsic, flyweight);
} return flyweight;
} }
使用场景:
- 系统中存在大量的相似对象。
- 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对
象没有特定身份。
- 需要缓冲池的场景。
注意:
- 享元模式是线程不安全的,只有依靠经验,在需要的地方考虑一下线程安全,在
大部分场景下不用考虑。对象池中的享元对象尽量多,多到足够满足为止。
- 性能安全:外部状态最好以 java 的基本类型作为标志,如 String,int,可以提
高效率。
23.桥梁模式(Bridge Pattern)
定义:Decouple an abstraction from its implementation so that the two can vary independently.(将抽象和实现解耦,使得两者可以独立地变化。)
- Abstraction——抽象化角色
它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类。
- Implementor——实现化角色
它是接口或者抽象类,定义角色必需的行为和属性。
- RefinedAbstraction——修正抽象化角色
它引用实现化角色对抽象化角色进行修正。
- ConcreteImplementor——具体实现化角色
它实现接口或抽象类定义的方法和属性。
使用场景:
- 不希望或不适用使用继承的场景
- 接口或抽象类不稳定的场景
- 重用性要求较高的场景
注意:
发现类的继承有 N 层时,可以考虑使用桥梁模式。桥梁模式主要考虑如何拆分抽象和实现。
设计原则:
●Single Responsibility Principle:单一职责原则
单一职责原则有什么好处:
- 类的复杂性降低,实现什么职责都有清晰明确的定义;
- 可读性提高,复杂性降低,那当然可读性提高了;
- 可维护性提高,可读性提高,那当然更容易维护了;
●变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护
性都有非常大的帮助。
ps:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。
单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因
环境而异。
● Liskov Substitution Principle:里氏替换原则
定义:Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
(所有引用基类的地方必须能透明地使用其子类的对象。)
通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不
行了,有子类出现的地方,父类未必就能适应。
定义中包含的四层含义:
1.子类必须完全实现父类的方法 2.子类可以有自己的个性
3.覆盖或实现父类的方法时输入参数可以被放大如果父类的输入参数类型大于子类的输入参数类型,会出现父类存在的地
方,子类未必会存在,因为一旦把子类作为参数传入,调用者很可能进入子类的方法范畴。
- 覆写或实现父类的方法时输出结果可以被缩小
父类的一个方法的返回值是一个类型 T,子类的相同方法(重载或覆写)的返回值为 S,那么里氏替换原则就要求 S 必须小于等于 T,也就是说,要么 S 和 T
是同一个类型,要么 S 是 T 的子类。
- Interface Segregation Principle:接口隔离原则
接口分为两种:
实例接口(Object Interface):Java 中的类也是一种接口类接口(Class Interface): Java 中经常使用 Interface 关键字定义的接口
隔离:建立单一接口,不要建立臃肿庞大的接口;即接口要尽量细化,同时接口中的方法要尽量少。
接口隔离原则与单一职责原则的不同:接口隔离原则与单一职责的审视角度是不相同的,单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划
分,而接口隔离原则要求接口的方法尽量少。
● Dependence Inversion Principle:依赖倒置原则
原始定义:
①高层模块不应该依赖低层模块,两者都应该依赖其抽象;
②抽象不应该依赖细节(实现类);
③细节应该依赖抽象。
依赖倒置原则在 java 语言中的体现:
①模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
②接口或抽象类不依赖于实现类;