设计模式学习笔记(一)

设计模式是为了设计出更容易维护的代码,“建立可维护的OO系统,要诀就在于想到系统以后可能需要的变化以及应付变化的原则。(《Head First 设计模式》)”

1. 策略模式

策略模式定义了算法族,分别封装起来,让它们之间可以相互转换,此模式让算法的变化独立于使用算法的客户。

大概实现

某一类(A类)的子类中可能需要变动的行为,独立为行为类,A类中含有该行为类的对象。
其中行为类的父类可以用接口(Java)或者抽象类(C++)实现(C++中如何实现像Java中接口功能--C++抽象类 & C++中抽象类和多继承
)。

例子(《Head First 设计模式》)

鸭子类(子类:绿头鸭、野鸭、橡皮鸭……)
飞行行为类(一般地飞、不能飞、乘火箭飞……)
叫行为类(呱呱叫、吱吱叫、不叫……)
UML图:


设计模式学习笔记(一)_第1张图片
策略模式UML图

设计模式学习笔记(一)_第2张图片
策略模式UML图2

2. 观察者模式

观察者模式使得主题的发布者和订阅者耦合度低,便于代码修改。
松耦合体现:
① 主题(发布者)对观察者的唯一了解就是它实现了一个特定的接口。
② 可以随时添加任意的新观察者,添加/删除时根本不需要修改主题。
③ 主题或观察者中的变化不会相互影响。

大概实现

订阅者类(观察者类)中实现自身数据的update函数;主题类做两件事:① 维护观察者队列,队列中每个元素都是一个观察者对象;② 每次自身数据更新就调用观察者队列中对象的update函数。

设计模式学习笔记(一)_第3张图片
观察者模式UML图

另一种方式

观察者从发布者处拉数据


设计模式学习笔记(一)_第4张图片
观察者UML图

拉模型的效率比较低,因为它涉及两个步骤,第一步,主题通知观察者;第二步观察者从主题那里提取所需的数据。

优缺点

推:效率较高,但是可能会退给接收者不需要的数据;
拉:效率较低。但由于只从主题发送所需的数据,所以能够提高性能。

例子

ROS的订阅/发布的通信方式用了观察者模式。
与ROS结构不同的是:观察者和主题仍然是一个线程。

例子(《Head First 设计模式》)

气象站、任意多的气象公告板。

例子(《Python设计模式》)

新闻通知系统。

3. 装饰者模式

装饰者模式在不改变原对象的基础上,通过对其进行包装拓展(增加属性或方法)使原有的对象可以满足用户更加复杂的需求(《JavaScript设计模式》)。
特点:便于拓展,会引入非常多的小类。

大概实现

建立一个基类A和一个装饰者基类(java拓展于A,c++继承于A),装饰者基类的创造函数需要传入一个A类对象,装饰者类中有一个函数——获取创造时传入的A类对象的属性或者调用它的函数。


设计模式学习笔记(一)_第5张图片
装饰者模式配图

例子(《Head First 设计模式》)

奶茶店不同的奶茶(基类A)和布丁、红豆、珍珠(装饰者类)等等。
java.io类。

例子(《JavaScript设计模式》)

为每个输入框都添加一行文字提示。

4. 工厂模式

工厂:创建类的类。
产品类只负责产品类的行为,但不负责其创建。

优点

  • 松耦合:对象的创建可独立于类的实现;
  • 简化客户端实现:客户端无需了解创建对象的类,但是照样可以使用它来创建对象。只需要知道需要传递的接口、方法和参数,就能够创建所需类型的对象了;
  • 可以自啊工厂中添加其他类型的对象,而这无需更改客户端代码。在最简单的情况下,客户端只需要传另一个参数就可以了;
  • 工厂还可以重用现有对象,但是,如果客户端直接创建对象的话,总是创建一个新的对象。

4.1 简单工厂模式

大概实现

把对象创建的过程独立成一类(工厂类)。工厂类的核心函数是对象类(产品类)的创建函数,此函数接收的参数不同,创建的产品类的类别也不同。

例子(《Python 设计模式》)

Animal

例子(《JavaScript 设计模式》)

  • 注册和登录页面、类型一:体育用品店、类型二:书店的书

例子(《head first 设计模式》)

pizza店


设计模式学习笔记(一)_第6张图片
简单工厂

4.2 工厂方法模式(factory method)

大概实现

工厂方法模式定义了一个接口作为工厂,需要创建的类都继承自这个接口。


设计模式学习笔记(一)_第7张图片
工厂方法模式

例子(《JavaScript 设计模式》)

pizza店

例子(《JavaScript 设计模式》)

广告展现

4.3 抽象工厂模式???

大概实现

抽象工厂定义了一系列接口作为生产一系列不同产品的工厂。


设计模式学习笔记(一)_第8张图片
image.png

例子(《Python 设计模式》)

pizza店

例子(《head first 设计模式》)

披萨店

PS:逆向依赖原则——尽量多依赖接口,少依赖具体类

你可能感兴趣的:(设计模式学习笔记(一))