Design Patterns
Decorator Design pattern
用于扩展系统功能的装饰模式。
比如我们有一个鸭子类,可以调用其鸭子叫的方法。我们初始化了一个鸭子对象,如何统计这个对象叫了几次,也就是其鸭子叫方法被调用了几次?记住OCP原则不允许我们直接修改鸭子类。
我们可以用一个计数类来把鸭子类包住。
装饰模式实现一个接口,接口中的方法通过该变量的同一个参数去调用同一个方法,比如本例中是鸭子呱呱的计数,每次调用++。
Adapter design patterns
这个例子包括了几个原则:
- 首先不同接口功能尽量分开,ISP,也就是说鸭子叫和计数不要写一个方法里。
- 不能直接修改类,OCP。
- 如果想鸭子叫同时计数,直接调用包装类即可,DRY。
- GooseAdapter 只访问了 Goose 的 honk 方法而不是对其完全访问,DIP。这里如果改成继承的子类,就有全部访问权了。
Wrapper design patterns
Wrapper 模式包括 decorator 和 adapter。decorator 主要是外面的包裹类和里面的类都实现一个接口,比如上例的鸭子嘎嘎。adapter 是内部类不需实现。
Immutable View:前面提过java引用的问题,比如两个变量引用同一个对象,一改都改。这样就相当于有引用的时候,该目标对象完全暴露出来了。在wrapper里我们可以限制包装类:禁止修改对象,修改则抛出异常。
Composite Design Pattern
包装了一个集合。
Observer Pattern
比如看到绿灯汽车知道该走了,这种观察者一个变量改变影响其他变量的实现。
java是提供了observable的api的,当对应变量值改变时触发函数。
不过这种写法违反了OCP,因为我们修改了dogbot让他主动实现observer的update。我们可以采用decorator design 方法。
如果dogbots是一个接口,dogwatcher 可以实现计数功能,还可以在文件,在gui中实现dogbots,实现集合的dogbots,两者代码几乎是分离的。
我们先用一个ObservableDogBot类继承Observable,且实现未完成的dogbots,然后写一个dogreporter实现observer。最后rover.addObserver(reporter1);
Factory Methods
如果我们设定饥饿值大于6的狗要被构造为greedyDogBot是普通狗的子类,那么PlainDogBot和greedyDogBot都直接提供出来构造方法不太好。可以通过一个构造类来判断需要返回什么对象。
这个构造方法可以返回接口类,但是实际方法里返回的都是实现了接口类的具体类,这样可以隐藏返回类类型:
工厂类甚至自己可以包装好类然后送回来一个包装类:
当然工厂方法除了静态的,也可以是非静态的工厂对象。我们可以利用不同的工厂对象包装不同的包装类,这样还能进一步隐藏返回对象的一些信息。
比如下一个例子中,spy狗多一个watcher。我们用多态方法初始化两个 Dog Factory,但是一个是实际SpyDogFactory类型的,一个实际是PlainDogFactory类型的,因此两者调用makeDogBot的时候会返回不同的狗。
像计数等额外包装功能,我们也可以不用“先用一个计数类包装普通类,再用工厂类包装计数类”,而是把计数内容包装在工厂类里。
Singleton Design Pattern
构造方法不一定返回必须是新创建的对象,工厂类里可以返回已有的对象。
注意LSP原则。
Object Pool Design Pattern
对象池模式,保留一个对象列表,在需要的时候返回一个特定对象。
Strategy Design Pattern
选择要执行的策略。
上图是狗执行几次action的函数。我们也可以利用重写的Comparator实现条件结构,比如比较ab两狗叫了几次,叫的少的补差。
State Design Pattern
可以改变对象的状态类型。
下面改变的几个类型都是accountState抽象类的实现类,通过多态的方式初始化。
Bridge Design Pattern
解耦思想。比如我们需要12种颜色的画笔,可以选择12根固定颜色的蜡笔,或者1根毛笔和12种颜料。毛笔的例子就很好地解耦了画笔和颜色。
例子来源:处理多维度变化——桥接模式(一)_LoveLion的博客-CSDN博客
下例:求父子交集。
Flyweight Pattern
将那些大量的,具有很多内部状态而外部状态很少的对象进行共享,可以以类似缓存的方式共享。
概念来源:精读《设计模式 - Flyweight 享元模式》 - 知乎 (zhihu.com)