第30 章 软件设计模式(举例说明)
2 设计模式:
- 创建型模式:
- 工厂方法(factory method):
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
- 抽象工厂(abstract factory):
为创建一系列相关或相互依赖的对象提供一个接口,而无需指定它们具体的类。
- 单例(singleton):
保证一个类只有一个实例,并提供一个全局访问点。
以单例模式(singleton)为例,这是一个创建型模式,用于确保一个类只有一个实例,并提供一个全局访问点。
假设我们需要创建一个日志记录器(logger)类,这个类负责记录应用程序的日志信息。我们希望在整个应用程序中只使用一个logger实例。为了满足这个需求,我们可以使用单例模式来实现logger类。
以下是一个使用python实现的单例模式示例:
```python
class logger:
_instance = none
def __new__(cls, args, kwargs):
if cls_instance is none:
cls_instance = super()__new__(cls)
return cls_instance
def log(self, message):
print(f&34;[{datetimenow()}] {message}&34;)
使用示例
logger1 = logger()
logger1log(&34;this is a log message&34;)
logger2 = logger()
logger2log(&34;this is another log message&34;)
输出结果:
[2023-03-30 12:34:56789123] this is a log message
[2023-03-30 12:34:56789123] this is another log message
```
在这个示例中,我们使用了 `__new__` 方法来确保logger类只有一个实例。当我们实例化logger对象时,如果没有实例存在,将创建一个新实例;如果实例已经存在,将直接返回已存在的实例。这样,我们可以在应用程序中多次实例化logger对象,但始终只会得到一个实例。
- 建造者(builder):
将一个复杂对象的构建与其表示分离,使相同的构建过程可以创建不同的表示。
- 原型(prototype):
使用原型实例指定创建对象的种类,并通过复制这个原型来创建新的对象。
- 结构型模式:
- 适配器(adapter):
将一个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而不能一起工作的类能一起工作。
- 桥接(bridge):
将抽象部分与实现部分分离,使它们可以独立地变化。
- 组合(posite):
将对象组合成树形结构以表示“部分-整体”的层次结构。
- 装饰器(decorator):
动态地给一个对象添加一些额外的职责。
- 外观(facade):
为一个复杂的子系统提供一个简单的接口,使子系统更易于使用。
- 享元(flyweight):
利用共享对象有效地支持大量的细粒度对象。
- 代理(proxy):
为其他对象提供一种代理以控制对这个对象的访问。
- 行为型模式:
- 责任链(chain of responsibility):
将请求的处理对象连接成一条链,沿着这条链传递请求,直到有一个对象处理它为止。
- 命令(mand):
将一个请求封装为一个对象,使您可以用不同的请求参数化其他对象,队列化或日志请求。
- 解释器(interpreter):
定义一种语言,并表示它的文法以及对语言的解释。
- 迭代器(iterator):
通过提供一种方法来访问聚合对象的元素,而不暴露其内部表示。
- 中介者(mediator):
定义一个中介对象来封装一系列对象之间的交互。
- 备忘录(memento):
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
- 观察者(observer):
定义对象间的一对多依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都得到通知并自动更新。
- 状态(state):
允许对象在内部状态改变时改变其行为。
- 策略(strategy):
定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。
- 模板方法(template method):
模板方法模式(template method)是一种行为型设计模式,用于定义算法的骨架,并将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
以一个简化的泡茶过程的示例来说明模板方法模式。在这个示例中,我们将泡茶过程分为几个步骤,如烧水、泡制茶叶、倒入杯子等。我们可以将这些步骤定义在一个抽象类中,然后让具体子类实现这些步骤。
```java
public abstract class teamaking {
// 模板方法
final void preparetea() {
boilwater();
brewtea();
pourincup();
addcondiments();
}
// 烧水
void boilwater() {
systemoutprintln(&34;burning water&34;);
}
// 泡制茶叶
abstract void brewtea();
// 倒入杯子
void pourincup() {
systemoutprintln(&34;pouring into cup&34;);
}
// 添加调料
void addcondiments() {
systemoutprintln(&34;adding condiments&34;);
}
}
public class greentea extends teamaking {
override
void brewtea() {
systemoutprintln(&34;brewing green tea&34;);
}
}
public class blacktea extends teamaking {
override
void brewtea() {
systemoutprintln(&34;brewing black tea&34;);
}
}
public class client {
public static void main(string[] args) {
teamaking greentea = new greentea();
greenteapreparetea();
teamaking blacktea = new blacktea();
blackteapreparetea();
}
}
```
在这个示例中,我们定义了一个名为 `teamaking` 的抽象类,其中包含了泡茶过程的模板方法 `preparetea()`。`preparetea()` 方法中包含了泡茶过程的各个步骤,如烧水、泡制茶叶、倒入杯子等。其中,泡制茶叶的步骤是一个抽象方法,需要子类来实现。
我们创建了两个具体的茶叶子类 `greentea` 和 `blacktea`,分别实现了泡制茶叶的步骤。在客户端代码中,我们实例化了这两个子类的实例,并调用了 `preparetea()` 方法来泡茶。
通过使用模板方法模式,我们定义了一个固定的算法结构,并将具体的泡茶步骤推迟到子类中实现。这样,我们可以在子类中灵活地定义泡茶过程,而不必修改 `teamaking` 类的结构。