前言
设计模式,即Design Patterns,是指在软件设计中,被反复使用的一种代码设计经验。使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性。
设计模式这个术语是上个世纪90年代由Erich Gamma、Richard Helm、Raplh Johnson和Jonhn Vlissides四个人总结提炼出来的,并且写了一本Design Patterns的书。这四人也被称为四人帮(GoF)。
为什么要使用设计模式?根本原因还是软件开发要实现可维护、可扩展,就必须尽量复用代码,并且降低代码的耦合度。
设计模式是软件工程中用来解决常见问题的模板或指南。它们通常提供了一种在特定情况下解决问题的标准化方法,主要分为三大类,下面将总结每一类的特点以及包含的设计模式。
创建型模式(Creational Patterns)
-
简介
创建型模式关注的是对象的创建机制,试图创建对象而不让用户指定具体的类。这些模式有助于隐藏对象创建的细节,使得系统更加灵活,并支持按需创建对象。常见的创建型模式包括:
- 简单工厂模式(Simple Factory Pattern)
- 工厂方法模式(Factory Method Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 单例模式(Singleton Pattern)
- 原型模式(Prototype Pattern)
- 建造者模式(Builder Pattern)
-
形象案例
-
简单工厂模式(Simple Factory Pattern)
假设你在开一家咖啡店,你需要能够快速制作各种类型的咖啡。简单工厂模式就像是你店里有一个咖啡机,这个咖啡机可以根据顾客的要求自动制作出拿铁、美式或卡布奇诺等咖啡。你不需要知道咖啡机内部是如何工作的,只需要告诉它你想要哪种咖啡,它就会为你制作出来。这里的"简单工厂"就是咖啡机,它负责创建(制作)各种类型的咖啡。
-
工厂方法模式(Factory Method Pattern)
现在,假设你不仅卖咖啡,还开始卖茶。你希望可以根据饮品类型来决定使用哪种机器制作。工厂方法模式就像是你为咖啡和茶分别设置了不同的制作站(机器)。当你需要一杯咖啡时,你会去咖啡站;如果需要一杯茶,则去茶站。这里的"工厂方法"是指每个站(机器)都有自己的制作方法,但是你只需要告诉它们你想要什么,它们各自会用正确的方法来制作。
-
抽象工厂模式(Abstract Factory Pattern)
继续扩展你的饮品店,除了咖啡和茶,你还增加了果汁。抽象工厂模式就像是你为每一种饮品类型设立了一个"生产线",这个生产线可以生产与之相关的多种产品。例如,咖啡生产线可以生产拿铁、美式和卡布奇诺;茶生产线可以生产绿茶、红茶和乌龙茶;果汁生产线可以生产橙汁、苹果汁和葡萄汁。这里的"抽象工厂"是指每条生产线,它们可以生产一系列相关的产品。
-
单例模式(Singleton Pattern)
想象你在管理一个公共厨房,这个厨房只有一个,所有人都共享。单例模式就像是确保只有一个公共厨房存在,并且每个人都能访问到它。无论多少人来使用这个厨房,系统保证只会有一个厨房实例,并且任何人都可以通过相同的方式来访问它。
-
原型模式(Prototype Pattern)
假设你是一名糕点师傅,你制作了一份非常受欢迎的蛋糕样品。每次有客人点这种蛋糕的时候,你不是重新制作一份新的蛋糕,而是复制这份样品。原型模式就像是你保留了一个蛋糕样品,每次需要的时候就复制这个样品。这种方法节省了时间和材料,因为你不需要每次都从头开始制作。
-
建造者模式(Builder Pattern)
继续我们的糕点师傅的例子,现在你想给顾客提供更多的个性化选择。建造者模式就像是你允许顾客自己选择蛋糕的每一层,包括奶油、水果和其他配料。糕点师傅会根据顾客的选择一步步地组装蛋糕。这里的"建造者"是指糕点师傅,他按照客户的订单逐步构建蛋糕。
通过这些例子,我们可以更好地理解这些模式的应用场景和它们各自的特点。
结构型模式(Structural Patterns)
-
简介
结构型模式处理的是如何组合类和对象以形成更大的结构。它们提供了简化类或对象接口的方法,以及通过使用继承或组合来增强现有功能的方式。这类模式可以帮助开发人员构建复杂系统,同时保持代码的清晰性和简单性。典型的结构型模式有:
- 代理模式(Proxy Pattern)
- 门面模式(Facade Pattern)
- 装饰器模式(Decorator Pattern)
- 享元模式(Flyweight Pattern)
- 组合模式(Composite Pattern)
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
-
形象案例
-
代理模式(Proxy Pattern)
假设你是一位明星,经常需要出席各种活动。由于行程繁忙,你可能会请一位助理代表你参加某些活动。代理模式就像是这位助理,在你不能亲自到场的情况下,代替你进行活动。这里的"代理"就是你的助理,它代表真正的对象(你)来进行操作。
-
门面模式(Facade Pattern)
想象你在逛一个大型购物中心。虽然购物中心内有很多不同的店铺和服务,但你只需进入购物中心的大门就可以接触到所有的服务。门面模式就像是购物中心的入口,它提供了一个简单的界面来访问一组子系统的功能。顾客不需要知道购物中心内部的复杂结构,只需要通过大门就可以访问所有服务。
-
装饰器模式(Decorator Pattern)
假设你有一杯普通的咖啡,但你想要增加一些额外的味道。你可以往里面加糖、奶或者巧克力粉。装饰器模式就像是你在咖啡上添加的不同配料,每一次添加都增加了咖啡的功能(口味),但并没有改变咖啡的本质(仍然是咖啡)。这样,你可以在不改变原始对象的前提下,动态地为其添加新功能。
-
享元模式(Flyweight Pattern)
想象你在制作许多张生日卡片,每张卡片都需要打印一个名字。为了节省资源,你可以预先制作好一些基本的设计模板,然后根据需要插入不同的名字。享元模式就像是这些预先制作好的设计模板,它们是共享的部分,只有变化的部分(如名字)是在实际使用时加入的。
-
组合模式(Composite Pattern)
现在想象你在组织一个家庭聚会,聚会中有不同的小组活动。这些小组活动可以是一个人单独表演,也可以是几个人组成的团队表演。组合模式就像是这种组织形式,它可以让你轻松地将个人表演和团队表演组合在一起,并以一致的方式对待它们。无论是个人还是团队,都可以被视为整体的一部分。
-
适配器模式(Adapter Pattern)
假设你有一台只支持USB接口的电脑,但是你有一个只支持HDMI接口的显示器。你需要一个转换器来连接这两个设备。适配器模式就像是这个转换器,它允许你不兼容的接口互相通信。转换器在这里充当了"适配器"的角色,它使两个不同的接口可以协同工作。
-
桥接模式(Bridge Pattern)
想象你正在装修一间房间,你想要更换灯饰。你希望可以随意选择不同样式的灯具,并且能够方便地安装在现有的电路系统上。桥接模式就像是你的电路系统和灯饰之间的桥梁,它分离了"照明设备"(灯饰)和"控制系统"(电路)。这样,你可以独立地更改灯饰而不必改变电路系统,反之亦然。
通过这些例子,我们可以更直观地理解这些模式是如何帮助我们在软件设计中解决实际问题的。
行为型模式(Behavioral Patterns)
-
简介
行为型模式关注的是算法的实现,即类的行为。它们描述了类之间的职责分配以及对象之间的通信机制。这类模式可以帮助开发者定义对象之间如何有效地通信,以及如何分配责任。行为型模式的例子有:
- 委派模式(Delegate Pattern)
- 模板方法模式(Template Method Pattern)
- 策略模式(Strategy Pattern)
- 责任链模式(Chain of Responsibility Pattern)
- 迭代器模式(Iterator Pattern)
- 命令模式(Command Pattern)
- 状态模式(State Pattern)
- 备忘录模式(Memento Pattern)
- 中介者模式(Mediator Pattern)
- 解释器模式(Interpreter Pattern)
- 观察者模式(Observer Pattern)
- 访问者模式(Visitor Pattern)
-
形象案例
-
委派模式(Delegate Pattern)
假设你是一家公司的经理,你需要安排员工完成各种任务。但你不可能亲自去做每一件事,所以你会委派任务给下属。委派模式就像是你将任务交给合适的员工去执行,他们负责具体的实施细节。
-
模板方法模式(Template Method Pattern)
想象你在教孩子们画画。你会先画一个轮廓,然后让他们填充颜色。这里,你提供了一个基本的框架(轮廓),但具体的填充部分由孩子们自由发挥。模板方法模式就像是这个绘画过程,框架(模板方法)是固定的,但具体的实现(颜色填充)可以由不同的孩子来完成。
-
策略模式(Strategy Pattern)
假设你在玩一个棋盘游戏,游戏中有不同的策略可以选择,比如进攻、防守或平衡发展。策略模式就像是你根据当前的游戏情况选择最适合的策略来指导你的下一步行动。
-
责任链模式(Chain of Responsibility Pattern)
想象你在公司里提交一个报销申请。这个申请需要经过多个部门审批,首先是部门经理审批,然后是财务部门审核,最后是总经理签字。责任链模式就像是这个审批流程,每一个环节负责一部分决策,直到请求被完全处理。
-
迭代器模式(Iterator Pattern)
假设你在图书馆里寻找一本书。你可以通过目录或者书架上的索引找到这本书的位置。迭代器模式就像是这个索引系统,它提供了一种访问集合元素的方法,而不需要暴露底层的数据结构。
-
命令模式(Command Pattern)
想象你在使用一个电视遥控器。遥控器上有不同的按钮,每一个按钮对应电视的一个操作,比如开机、换频道等。命令模式就像是遥控器上的每一个按钮,它们封装了对电视的操作请求,并可以被延迟执行或记录下来。
-
状态模式(State Pattern)
假设你在玩一个电子游戏中的角色,这个角色在不同情况下会有不同的行为,比如在战斗时和休息时。状态模式就像是角色在不同状态下的表现,角色根据当前的状态来决定如何行动。
-
备忘录模式(Memento Pattern)
想象你在写一篇长文章,为了避免中途丢失数据,你会保存多个版本的草稿。备忘录模式就像是保存这些草稿的过程,它允许你在不破坏当前状态的情况下保存和恢复历史状态。
-
中介者模式(Mediator Pattern)
假设你在主持一个会议,会议中有多个参与者讨论同一个议题。中介者模式就像是你作为主持人,协调各个参与者之间的交流,确保会议顺利进行。
-
解释器模式(Interpreter Pattern)
想象你在学习一门新的编程语言,这门语言有自己的语法和解释规则。解释器模式就像是这个编译器或解释器,它负责理解和执行这门语言的语法规则。
-
观察者模式(Observer Pattern)
假设你订阅了一份报纸,每天早上送报员会把最新的报纸送到你家门口。观察者模式就像是这个订阅过程,当你订阅后,送报员会在每天早上更新信息并发送给你。
-
访问者模式(Visitor Pattern)
想象你在一个动物园里,动物园里有不同的动物。当你参观时,你会对每种动物做一些不同的事情,比如喂食或拍照。访问者模式就像是你作为游客对不同动物的访问行为,每种动物接受访问者的动作,但具体的操作是由访问者来定义的。
通过这些例子,我们可以更好地理解这些行为型模式是如何帮助我们定义对象之间的交互以及职责分配的。
总结
分类 | 解释 | 举例 |
---|---|---|
创建型模式(Creational Patterns) | 这类模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象,这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活 | 简单工厂模式(Simple Factory Pattern)、工厂方法模式(Factory Method Pattern)、抽象工厂模式(Abstract Factory Pattern)、单例模式(Singleton Pattern)、原型模式(Prototype Pattern)建造者模式(Builder Pattern) |
结构型模式(Structural Patterns) | 这类设计模式关注类和对象的组合。继成的概念被用来组合接口和定义组合对象获得新功能的方式 | 代理模式(Proxy Pattern)、门面模式(Facade Pattern)、装饰器模式(Decorator Pattern)、享元模式(Flyweight Pattern)、组合模式(Composite Pattern)、适配器模式(Adapter Pattern)、桥接模式(Bridge Pattern) |
行为型模式(Behavioral Patterns) | 这类设计模式特别关注对象之间的通信 | 委派模式(Delegate Pattern)、模板方法模式(Template Method Pattern)、策略模式(Strategy Pattern)、责任链模式(Chain of Responsibility Pattern)、迭代器模式(Iterator Pattern)、命令模式(Command Pattern)、状态模式(State Pattern)、备忘录模式(Memento Pattern)、中介者模式(Mediator Pattern)、解释器模式(Interpreter Pattern)、观察者模式(Observer Pattern)、访问者模式(Visitor Pattern) |