浅析设计模式
一、什么是设计模式?
设计模式,是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
Christopher Alexander对设计模式这样说:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样你就能一次又一次地使用该方案而不必做重复劳动。”
设计模式四个基本要素:
- 模式名称;
- 问题;
- 解决方案;
- 效果。
二、对类的回顾
类和对象的三大特性:
- 封装
- 继承
- 多态
关于特性,就不做赘述了。我们先要了解 接口 这个概念。什么是接口?
接口:一种特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法。
接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法。
接口的作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现。
Python中关于接口的两种写法:
# 写法一: class InterFace(object): def method(self,arg): raise NotImplementedError # 写法二: from abc import abstractmethod,ABCMeta class InterFace(metaclass=ABCMeta): @abstractmethod def method(self,arg): pass
三、设计模式的六大原则:
-
开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
- 里氏(Liskov)替换原则:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
- 依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
- 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
- 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用。
- 单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
四、设计模式的分类:
1、创建型模式:
- 工厂方法模式 (*)
- 抽象工厂模式 (*)
- 创建者模式 (*)
- 原型模式
- 单例模式 (*)
2、结构型模式:
- 适配器模式 (*)
- 桥模式
- 组合模式 (*)
- 装饰模式
- 外观模式
- 享元模式
- 代理模式 (*)
3、行为型模式:
- 解释器模式
- 责任链模式 (*)
- 命令模式
- 迭代器模式 (*)
- 中介者模式
- 备忘录模式
- 观察者模式
- 状态模式
- 策略模式 (*)
- 访问者模式
- 模板方法模式 (*)
五、简单工厂模式
1、内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
2、角色:
- 工厂角色(Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
3、优点:
- 隐藏了对象创建的实现细节
- 客户端不需要修改代码
4、缺点:
- 违反了单一职责原则,将创建逻辑集中到一个工厂类里
-
当添加新产品时,需要修改工厂类代码,违反了开闭原则
六、工厂方法模式
1、内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
2、角色:
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
工厂方法模式相比简单工厂模式将每个具体产品都对应了一个具体工厂。
3、使用场景:
- 需要生产多种、大量复杂对象的时候
- 需要降低耦合度的时候
- 当系统中的产品种类需要经常扩展的时候
4、优点:
- 每个具体产品都对应一个具体工厂类,不需要修改工厂类代码
- 隐藏了对象创建的实现细节
5、缺点:
- 每增加一个具体产品类,就必须增加一个相应的具体工厂类
七、抽象工厂模式
1、内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
例:生产一部手机,需要手机壳、CPU、操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
2、角色:
- 抽象工厂角色(Creator)
- 具体工厂角色(Concrete Creator)
- 抽象产品角色(Product)
- 具体产品角色(Concrete Product)
- 客户端(Client)
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
3、适用场景:
- 系统要独立于产品的创建与组合时
- 强调一系列相关的产品对象的设计以便进行联合使用时
- 提供一个产品类库,想隐藏产品的具体实现时
4、优点:
- 将客户端与类的具体实现相分离
- 每个工厂创建了一个完整的产品系列,使得易于交换产品系列
- 有利于产品的一致性(即产品之间的约束关系)
5、缺点:
-
难以支持新种类的(抽象)产品
八、建造者模式
未完待续……