常用的几个设计模式
1 Singleton
单例,一个类仅允许一个对象存在。例如一个虚拟机只有一个堆。
1.1 饿汉模式
1 | class Demo { |
用语言初始化机制避免多线程多次构造对象的问题。只是在一开始就构造可能有点浪费?
1.2 懒汉模式
用到再构造(Lazy initialization)。注意多线程同步。
1 | public class Demo |
2 工厂模式
2.1 工厂方法模式
有一个抽象工厂、一个抽象产品,一堆产品。一个具体工厂生产一个具体产品。
这很OOP,符合开闭原则,用户只需要知道工厂,不需要知道具体产品是哪一个类。用的时候使用抽象产品(即只关心接口)
缺点是每添加一个产品就要加一个工厂。
2.2 抽象工厂
如果产品很多,特别是存在排列组合的情况,建议使用抽象工厂。
抽象工厂一个工厂可以生产一类产品(可以是不同的方法生产不同的产品)。这样在新增类型的时候才需要新工厂。
举个例子:
- 有两类抽象产品。键盘和鼠标.
- 抽象工厂,定义生产键盘和鼠标的接口
- 有Win鼠标、键盘,Mac鼠标、键盘四种具体产品
- Mac工厂和Win工厂,实现抽象工厂,生产Mac和Win的键盘和鼠标
3 观察者模式
观察者注册回调,在事件发生时invoke回调,通知观察者。
具体例子如MVVM的INotifyPropertyChanged
4 装饰器模式
- 有接口IBase
- A实现了接口IBase
- 装饰器Decorator实现了接口IBase,并且装饰器有一个局部变量A,装饰器选择性地将A的功能暴露,也可以修改、装饰A原有的功能,甚至增加新功能。
它的使用范围类似继承。但是装饰器相比继承提供了更高的可定制性。
在Java的系统库中
- InputStream是抽象构建角色(Component)
- ByteArrayInputStream、FileInputStream、StringBufferInputStream是具体构件角色(ConcreteComponent)
- 由FilterInputStream、ObectInputStream是抽象装饰角色(Decorator)。它们实现了InputStream所规定的接口。
- BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream是具体装饰角色(ConcreteDecorator)。