23种设计模式讲解
- 策略模式
- 问题:
- 解决方案:
- 效果:
- 适用场景:
- 实际应用:
- 优点缺点:
- 实例:
- 装饰 6
- 问题:
- 解决方案:
- 效果:
- 代理 7
- 问题:
- 解决方案:
- 效果:
- 参考文献:
设计模式有四个基本要素:
- 模式名称(pattern name):一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
- 问题(problem):描述了应该在何时使用模式。
- 解决方案(solution):描述了设计的组成成分,它们之间的相关关系以及各自的职责和协作方案。
- 效果(consequences):描述了模式应用的效果以及使用模式应该权衡的问题。
设计模式总体分为三大类:
-
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
-
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
-
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
策略模式
策略模式(Strategy Pattern)是指定义一个算法家族,使得家族内的不同算法都遵从算法家族的接口及方法规范,从而可以实现算法间互相替换,且不会影响到使用算法的客户。
问题:
一个系统中有多个算法和类很相似,区分这些类和算法的只是其内部行为。
解决方案:
策略模式由三类主要角色组成:
- 策略类:定义所有支持算法的公共接口,在这个例子中具体为收费抽象类;
- 具体策略类:具体的算法,在这个例子中具体为各类收费类和折扣优惠收费类;
- 上下文类:维护对策略对象的应用。
效果:
适用场景:
一个系统中有多个算法和类很相似,区分这些类和算法的只是其内部行为。
实际应用:
在导航应用中,有不同的路径规划算法,如针对步行的、骑行的、搭乘公共交通工具的、以及开车的等。主要导航类的主要工作是在地图上渲染出规划好的路径,并不会在意是由和算法生成的路径。此时可以将路径规划算法使用策略模式进行封装,方便与主要导航类的交互。
优点缺点:
优点:
- 可以以相同的方式调用所有算法,减少了各种算法类与使用算法类之间的耦合。策略模式的Strategy类层次为Context类定义了一系列的可供重复使用的算法或行为,继承有助于析取这些算法中的公共功能。
- 简化了单元测试。每个算法都有自己的类,可以通过自己的接口单独测试;
- 符合“开放封闭原则”,无需对上下文进行修改就可以引入新的策略。
缺点:
- 不适合算法极少发生改变的场景,会使得程序整体过于复杂;
- 要求客户端必须知晓策略间的不同,因为需要从中选择;
实例:
要求实现一个商场收银软件程序,营业员可以通过输入客户所有购买商品的单价和数量,程序自动计算出总金额。同时满足:
- 商场有时会有打折活动(如商品打7折),
- 满减促销活动(如商品满300-100),
程序应能考虑这些活动的情形,在尽量减少重复代码的前提下,实现正确的金额计算。
使用策略模式来解决问题
- 首先创建抽象的算法类CashSupur,作为所有促销活动算法的抽象类,同时定义所有支持算法的公共接口,定义方法acceptCash()用于得到结果;
- 创建具体的促销算法类CashNormal,CashRebate等,继承于抽象算法类CashSupur,覆写acceptCash()实现具体的促销算法;
- 创建上下文类CashContext,维护对算法对象的引用,使用时根据用户输入,传入一个具体的促销算法类来配置。
# 策略模式: 设计一个 已知单价和数量 的总价单价计算器
## 现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
class CashSuper(object):
def __init__(self):
pass
def AcceptCash(self, money):
pass
## 正常收费子类
class CashNormal(object):
def AcceptCash(self, money):
return money
## 打折收费
class CashRebate(CashSuper):
__moneyRebate = 1
def CashRebate(self, moneyRebateStr):
self.__moneyRebate = float(moneyRebateStr)
def AcceptCash(self, money):
return money * self.__moneyRebate
## 返现收费
class CashReturn(CashSuper):
__moneyCondition = 0
__moneyReturn = 0
def cash_return(self,moneyConditionStr,moneyReturnStr):
self.__moneyCondition = float(moneyConditionStr)
self.__moneyReturn = float(moneyReturnStr)
def accept_cash(self,money):
result = money
if (money >= self.__moneyCondition):
result = money - money // self.__moneyCondition * self.__moneyReturn
return result
装饰 6
问题:
描述了应该在何时使用模式。
解决方案:
描述了设计的组成成分,它们之间的相关关系以及各自的职责和协作方案。
效果:
描述了模式应用的效果以及使用模式应该权衡的问题。
代理 7
问题:
描述了应该在何时使用模式。
解决方案:
描述了设计的组成成分,它们之间的相关关系以及各自的职责和协作方案。
效果:
描述了模式应用的效果以及使用模式应该权衡的问题。
参考文献:
CSDN - 23种设计模式