⌨️ 第五章 从设计到测试
📄 本篇摘要

两套面向对象的【标准语言】:UML 用一组标准图把设计画出来(类图最常用);设计模式把前辈踩坑后总结的方案起好名字(GoF 23 种分三类)。模式是名字化的经验——说【这里用单例】一个词顶十分钟解释。

📝 关系

上一节:多态与接口 | 下一节:对象之间的关系

一、UML:面向对象的通用画法

UML(统一建模语言)是一组标准图形记号,常用几张:

图 画什么
类图 类的属性方法+类间关系(本章 5-21 全是它的词汇)
时序图 对象间消息往来的时间顺序
用例图 系统功能与使用者
状态图 一个对象的状态流转

类图读法三分钟入门:矩形=类(三格:名字/字段/方法);箭头样式区分关系——空心三角=继承(泛化)、空心菱形=聚合、实心菱形=组合、普通箭头=依赖。UML 2.x 时代 ideas:图不用全会画,类图+时序图覆盖日常八成场景。

二、设计模式:有名字的套路

设计模式=反复出现的设计问题的成熟解法。1994 年 GoF(Gang of Four 四人帮)的《设计模式》总结 23 种,分三类:

模式的正确用法:先有问题,再找模式——拿着模式找问题是反面教材(过度设计:三层包装只为调一个函数)。

三、模式与多态的关系

几乎全部行为型模式的地基都是 5-19 的多态+接口:策略模式=把算法族做成可替换的接口实现;观察者=订阅者都实现同一个 update 接口。学模式前先把多态吃透,模式只是多态在具体场景的固定打法。

四、动手 Demo:单例与策略各来一发

# 模式一:单例(全局唯一)——用模块级实现最 Pythonic
class Config:
    _instance = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

a, b = Config(), Config()
print("单例:", a is b)

# 模式二:策略(算法可替换)——排序键即策略
def by_price(item):
    return item["price"]

def by_sales(item):
    return -item["sales"]          # 负号 = 降序

items = [
    {"name": "键盘", "price": 300, "sales": 50},
    {"name": "鼠标", "price": 100, "sales": 200},
    {"name": "显示器", "price": 900, "sales": 30},
]
print("按价格:", [x["name"] for x in sorted(items, key=by_price)])
print("按销量:", [x["name"] for x in sorted(items, key=by_sales)])

沙箱实跑输出:

单例: True
按价格: ['鼠标', '键盘', '显示器']
按销量: ['鼠标', '键盘', '显示器']

看到什么算成功:两次 Config() 拿到同一个对象(True);两种策略排序各自正确。

读结果:__new__ 拦截实例化保证全局唯一——配置、连接池、日志器常用单例(但教材提醒:全局状态是测试的敌人,能不用就不用)。策略 Demo 里 Python 的 key= 函数就是活生生的策略模式——把【怎么排】从【排这个动作】里拆出来随时替换,与 5-19 的鸭子类型一脉相承。

五、30 秒实验

给 Config 加 def __init__(self): self.value = 42,再 print 两实例的 value——发现每次 init 都重跑(值覆盖但对象同一个)。单例的正确 Python 写法其实是模块级变量——语言给了更简单的路,模式别硬套。

六、常见误区

误区 真相
23 个模式都要背 记住名字和用途即可;动手时查——用着用着自然熟
用了模式=代码高级 为用而用是过度设计;模式解决重复出现的问题
UML 图越全越好 类图+时序图覆盖八成日常;其余按需取用
自测三问(点击展开) 1. **GoF 模式分哪三类?** 答:创建型(怎么造)、结构型(怎么拼)、行为型(怎么协作)。 2. **类图里空心三角和实心菱形各表什么?** 答:空心三角=继承(泛化);实心菱形=组合(整体掌控部分的生命周期)。 3. **单例适合什么场景?风险是什么?** 答:全局唯一资源(配置、连接池);风险=全局状态难测试,Python 常用模块级变量替代。

相关笔记