设计模式
最近学习了《图解设计模式》一书,做了一些笔记。
初识设计模式
- 设计模式不是类库
类库是由程序组合而成的组件,而设计模式则用来表现内部组件是如何被组装的,以及每一个组件是如何通过相互关联来构成一个庞大系统的。 - 不要使用具体的类来解决问题,要优先使用抽象类和接口来编程
如果只使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用
迭代器模式(Iterator)
一个一个遍历
使用迭代器模型可以将遍历与实现分离开。
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]);//迭代输出数组中的每个元素
}
将这里循环变量i的作用抽象化、通用化后形成的模式,就是迭代器模式
在python中,range()就是一个迭代器
-
迭代器模型中需要的角色
-
Iterator(迭代器)
负责定义按序遍历元素的API。需要有用于判断是否存在下一个元素的方法(hasnNext)和返回当前元素并获取下一个元素的方法(Next).
-
ConcreteIterator(具体的迭代器)
负责实现Iterator所定义的API。包含了遍历集合所必需的信息(实现具体的遍历)。
-
Aggregate(集合)
负责定义创建Iterator的API。这个API是一个方法。
-
ConcreteAggregate(具体的集合)
负责实现Aggregate所定义的API。会创建出具体的可迭代对象。
-
-
Iterator 模式与 visitor 的区别:
- 前者是从集合中一个一个取出元素进行遍历,但是并没有在Iterator接口中声明对取出的元素进行何种处理
- 后者是在遍历元素集合的过程中,对元素进行相同的处理
- 可以认为visitor是Iterator的进阶版
适配器模式(Adapter)
是一种可以用于填补“现有程序”与“所需程序”之间差异的设计模式
也被称为包装器模式(wrapper)
Adapter 模式有两种:类适配器模式(使用继承的适配器)和对象适配器模式(使用委托的适配器)
-
适配器模型中需要的角色
-
Target (对象)
负责定义所需的方法。即“所需程序”
-
Client(请求者)
负责使用Target角色所定义的方法进行具体处理。可以是Main类。
-
Adaptee(被适者)
是一个持有既定方法的角色。即“现有程序”。
-
Adapter(适配)
是适配器模型中的主角。用于填补“现有程序”与“所需程序”之间的差异。
-
-
什么时候才需要使用适配器模型?
当现有的类被充分测试过了,bug很少,而且已经被用于其他软件之中时,通常这些类可以作为组件重复利用。此时通过该模式创建所需要的方法群的时候。当出现bug时,由于我们很明确知道bug不在现有的类,所以只需要调查扮演适配器角色的类就可以了。这样的操作可以让代码问题的排查变得非常简单
此外还可以使用适配器模式使新旧版本兼容,帮助开发者轻松地同时维护新旧两个版本。
-
与Bridge模式和 Decorator模式的区别
- Adapter模式用于连接API不同的类,而Bridge模式则用于连接类的功能层次结构与实现层次结构
- Adapter 模式用于填补不同API之间的缝隙,而Decorator模式则是在不改变API的前提下增加功能。
单例模式(Singleton)
只有一个实例
为了达到任何情况下只剩成一个实例的效果。必须设置构造函数为private
-
单例模型中的角色
-
Singleton(单例)
在单例模型中只有一个角色。Singleton中有一个返回唯一实例的static方法。该方法总会返回同一个实例。 为了防止不小心用new关键字创建实例,还将构造函数设置为private
-
-
在以下模式中,多数情况下只会生成一个实例
- 抽象工厂模式
- 创建者模式
- 外观模式
- 原型模式