常用的设计模式介绍
创建型模式 (Creational Patterns)
此类模式主要关注对象的创建过程,旨在将对象的创建与使用解耦,提升系统的灵活性和可扩展性。
1. 单例模式 (Singleton Pattern)
核心思想: 确保一个类在整个系统中只有一个实例,并提供一个全局访问点来获取这个实例。
使用场景: * 资源共享与控制: 当多个模块需要共享同一个资源,且需要集中控制时,例如数据库连接池、线程池等。 * 全局配置信息: 应用程序的配置文件通常是唯一的,适合用单例模式来读取和管理。 * 频繁创建与销毁的对象: 对于那些创建和销毁开销大的对象,使用单例模式可以显著提升性能,例如日志记录器。 * 操作系统组件: 例如Windows的任务管理器和回收站,都是典型的单例应用,确保在系统中只存在一个实例。
2. 工厂方法模式 (Factory Method Pattern)
核心思想: 定义一个用于创建对象的接口,但将具体的实例化过程延迟到子类中进行。
使用场景: * 不确定具体对象类型: 当一个类无法预知需要创建的对象的具体类别时,可以将创建任务交给子类完成。 * 需要解耦创建者与产品: 希望将对象的创建和使用分离开,降低它们之间的耦合度。 * 扩展性要求高的场景: 当需要增加新的产品时,只需添加对应的工厂子类即可,无需修改现有代码,符合“开闭原则”。 * 跨平台UI库: 例如,一个UI框架可以定义一个创建按钮的工厂方法,具体的Windows按钮和HTML按钮由不同的子类工厂来创建。
3. 建造者模式 (Builder Pattern)
核心思想: 将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建出不同的表示。
使用场景: * 复杂对象的构建: 当一个对象的创建过程包含多个步骤或需要设置大量参数时,使用建造者模式可以使代码更清晰。 * 属性间存在依赖或顺序要求: 如果对象的某些属性需要按照特定的顺序来设置,或者属性之间存在依赖关系,建造者模式可以很好地控制构建过程。 * 创建不同表示的对象: 当需要使用相同的构建流程创建出不同配置或形态的对象时。例如,肯德基套餐的构建,服务员(指挥者)按照固定的流程(构建过程)组合不同的汉堡、饮料(具体组件),最终生成不同的套餐(产品)。
结构型模式 (Structural Patterns)
这类模式主要关注如何将类和对象组合成更大的结构,同时保持结构的灵活性和高效性。
1. 适配器模式 (Adapter Pattern)
核心思想: 作为两个不兼容接口之间的桥梁,使得原本由于接口不兼容而不能一起工作的类可以协同工作。
使用场景: * 系统集成与复用: 当需要复用一个已经存在的类,但其接口与当前系统的需求不匹配时。 * 第三方库的集成: 在整合外部库或API时,由于其接口可能与系统不一致,可以通过适配器进行转换。 * 接口统一: 当系统中存在多个功能类似但接口不同的组件时,可以使用适配器模式提供一个统一的接口。 * 兼容旧版本接口: 在系统升级过程中,为了兼容旧版本的接口,可以使用适配器模式。 * 具体案例: 常见的电源适配器,可以将220V的电压转换为110V,让电器在不同电压标准下正常工作。
2. 装饰器模式 (Decorator Pattern)
核心思想: 动态地为一个对象添加额外的职责,就扩展功能而言,它比生成子类的方式更为灵活。
使用场景: * 动态添加或撤销功能: 需要在运行时为一个对象动态地添加或移除功能,而不想通过继承来静态地实现。 * 避免子类爆炸: 当需要为对象添加多种功能,而这些功能的组合会导致产生大量的子类时,使用装饰器模式可以有效避免这种情况。 * 功能增强: 在不改变原有对象结构的情况下,为其增加新的功能。 * 具体案例: 孙悟空的七十二变,孙悟空本身(具体组件)通过不同的变化(具体装饰器)来获得新的能力。 另一个例子是为一幅画添加画框和玻璃,画本身的功能没有改变,但通过装饰增强了其展示效果。
3. 代理模式 (Proxy Pattern)
核心思想: 为其他对象提供一种代理以控制对这个对象的访问。
使用场景: * 访问控制: 当需要对对象的访问进行权限控制时,可以在代理中进行检查。 * 延迟初始化(虚拟代理): 对于创建开销大的对象,可以延迟其实例化,直到真正需要使用时才创建。 * 远程代理: 当需要访问位于远程服务器上的对象时,代理可以在本地代表远程对象,处理网络通信等细节。 * 日志记录与监控: 可以在不修改业务代码的情况下,通过代理记录方法的调用日志或监控其性能。 * 具体案例: Windows系统中的快捷方式,它作为文件或程序的代理存在。 另一个例子是信用卡,它是银行账户中资金的代理,在交易中代替现金进行支付。
行为型模式 (Behavioral Patterns)
这类模式主要关注对象之间的通信以及职责的分配。
1. 观察者模式 (Observer Pattern)
核心思想: 定义对象之间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。
使用场景: * 事件驱动系统: 当一个对象的改变需要触发其他多个对象的操作时,例如GUI中的事件监听。 * 发布-订阅系统: 消息的发布者不需要知道具体的订阅者,两者解耦。例如邮件订阅、新闻推送等。 * MVC架构: 在MVC(模型-视图-控制器)模式中,模型(Model)作为被观察者,当其数据变化时会通知视图(View,观察者)进行更新。 * 具体案例: 拍卖系统中,当有新的出价时,所有参与拍卖的人都会收到通知。
2. 策略模式 (Strategy Pattern)
核心思想: 定义一系列算法,并将每一个算法封装起来,使它们可以相互替换。此模式让算法的变化独立于使用算法的客户。
使用场景:
* 多种算法选择: 当一个系统需要动态地在多种算法中选择一种时,例如不同的排序算法、压缩算法等。
* 避免多重条件判断: 当代码中存在大量与算法选择相关的if-else或switch语句时,可以使用策略模式来简化和优化结构。
* 扩展性要求: 当需要方便地增加新的算法时,只需添加新的策略类即可。
* 具体案例: 电商网站的支付功能,可以选择支付宝支付、微信支付或银行卡支付,每种支付方式都是一种独立的策略。 另一个例子是出行方式的选择,可以选择骑自行车、乘坐公交或开车,每种方式对应不同的策略。
3. 模板方法模式 (Template Method Pattern)
核心思想: 在一个方法中定义一个算法的骨架,而将某些步骤延迟到子类中实现。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
使用场景:
* 算法骨架固定,细节可变: 当多个子类有共同的执行流程,但某些具体的步骤实现不同时。
* 代码复用: 将多个子类中重复的代码提取到父类的模板方法中,便于维护。
* 控制子类扩展: 模板方法模式通过在父类中定义算法框架,来控制子类的行为,通常模板方法会用final关键字修饰,防止被子类重写。
* 具体案例: 泡茶和冲咖啡的流程类似(烧水、冲泡、倒入杯中、加料),可以将共同的步骤定义在模板方法中,而具体的冲泡内容和添加的调料则由子类来实现。