Datawhale 202212 设计模式 | 第二章 23种设计模式

本文详细介绍了23种经典的设计模式,包括创建型、结构型和行为型三种类型。每种模式均涵盖问题、解决方案、效果及应用场景等内容,并通过实例深入浅出地解析策略模式,帮助读者更好地理解和掌握设计模式的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式有四个基本要素:

  • 模式名称(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种设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值