设计模式入门:创建型、结构型、行为型
一、设计模式解决什么问题
设计模式是在特定场景下、针对重复出现的设计问题的通用解决方案的抽象。它们不是具体代码,而是「怎么组织类与对象、怎么分工、怎么降低耦合」的套路,用统一的名字(如 Factory、Observer)方便沟通和查阅。模式通常包含:问题(要解决什么)、方案(参与角色与协作方式)、后果(优缺点与适用边界)。
模式的价值在于:复用经验——不用从零摸索;统一语言——说「这里用策略模式」大家就懂;指导扩展——按模式扩展比乱加 if-else 更稳。但模式是手段不是目的:只有在「这里确实有重复问题」时引入才有意义,否则容易变成为模式而模式的过度设计。
二、GoF 分类概览
常见用法: 工厂——根据参数或配置返回具体产品,调用方只依赖抽象;单例——全局唯一实例(如配置、连接池),慎用、避免隐藏依赖。
常见用法: 适配器——把第三方接口「转」成己方接口;装饰器——包装对象,层层叠加行为(如日志、缓存),不修改原类。
常见用法: 观察者——主题状态变化时通知多个订阅者,解耦发布与订阅;策略——把算法封装成可替换的策略对象,运行时切换。
几个代表模式一句话
- 工厂(Factory):创建对象交给工厂方法/类,调用方不 new 具体类,便于换实现和测试。
- 单例(Singleton):保证某类全局只有一个实例;注意测试和并发,避免滥用。
- 适配器(Adapter):把不兼容的接口包装成目标接口,让老代码或第三方库能按己方接口使用。
- 装饰器(Decorator):用包装类层层叠加行为,与组件同接口,不修改原类即可「加一层」功能。
- 观察者(Observer):主题维护订阅列表,状态变化时通知所有观察者;事件、消息队列常是其实例。
- 策略(Strategy):把算法封装成可替换对象,上下文依赖策略接口,运行时注入不同实现。
三、何时引入模式、何时避免过度设计
模式是工具箱里的工具:问题对上了再用。若没有「多实现要切换」「多订阅者要通知」「接口不兼容要包装」等需求,不必强行上工厂、观察者、适配器。过度设计的表现:为了「用上模式」而拆出一堆只有一处调用的抽象、或每个类都套一层工厂,导致阅读和维护成本上升。
适合引入模式的时机
- 同一类问题反复出现(如多处需要「按类型创建」→ 工厂)
- 确实有多实现、要扩展(如多种支付方式 → 策略/工厂)
- 要解耦「谁通知谁」(事件、消息 → 观察者)
- 要对接老接口或第三方(接口不一致 → 适配器)
- 要无侵入地加行为(日志、缓存 → 装饰器/代理)
避免过度设计
- 只有一种实现、且短期不会变:不必先抽象再实现
- 调用点只有一处:不必为「可能以后会多」提前上模式
- 团队不熟悉该模式:先理解问题再引入,避免照抄结构
- 简单 if-else 能说清:不必为了「优雅」强行策略/状态机
建议:先写直白实现,在出现「改不动、重复多、要扩展」时再考虑对应模式;引入时指名「我们这里用 XX 模式」,便于沟通和文档化。
一句话: 设计模式是重复设计问题的通用解决方案,GoF 分为创建型(怎么造对象:工厂、单例等)、结构型(怎么拼结构:适配器、装饰器等)、行为型(怎么解耦行为:观察者、策略等)。在「问题确实存在、有多实现或要解耦」时引入;只有一种实现、不会扩展时不必为模式而模式,避免过度设计。
四、小结
设计模式解决反复出现的设计问题,提供可复用的套路与统一命名。GoF 分三类:创建型(工厂、单例等)、结构型(适配器、装饰器等)、行为型(观察者、策略等)。代表模式如工厂封装创建、适配器统一接口、观察者解耦通知、策略封装可替换算法。应在「问题存在、要扩展或解耦」时引入,避免只有一种实现或单点调用时过度设计。下一章进入版本控制与 Git 工作流,把「怎么协作、怎么管理变更」落到实处。