设计模式的具体介绍有很多优秀的博文讲的已经很明白,这里不过多赘述。大部分博文只介绍了设计模式的概念和相关代码,这里为大家举一些具体的使用场景。
工厂模式(Factory Pattern)
- 图像处理软件中的图像读取器工厂,根据不同图像格式返回对应的读取器对象。
- 汽车制造业中的汽车工厂,根据不同的订单需求生产不同型号的汽车。
- 游戏开发中的怪物生成器工厂,根据游戏关卡需求生成不同种类的怪物。
- 文件系统中的文件对象工厂,根据文件类型创建相应的文件对象。
- 在 Hibernate 中,如果需要更换数据库,工厂模式同样发挥了作用。只需简单地更改方言(Dialect)和数据库驱动(Driver),就能够实现对不同数据库的切换。
- 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方,调用相应的记录器即可。
- 设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。
抽象工厂模式(Abstract Factory Pattern)
- UI框架中的主题工厂,根据用户选择的主题返回对应的UI组件工厂。
- 软件产品线中的产品家族工厂,根据不同产品线返回不同产品家族的组件工厂。
- 汽车制造业中的汽车零件工厂,根据不同车型返回对应的零件工厂。
- 电子设备制造中的电路板工厂,根据设备类型生产不同类型的电路板。
- 在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
- QQ 换皮肤,一整套一起换。
- 生成不同操作系统的程序。
单例模式(Singleton Pattern)
- 日志系统中的日志管理器,保证全局只有一个实例记录日志。
- 网络连接池中的连接管理器,保证全局只有一个实例管理连接。
- 配置管理器,保证全局只有一个实例来管理配置信息。
- 线程池中的线程管理器,保证全局只有一个实例来管理线程。
- 数据库连接池中的连接池管理器,保证全局只有一个实例管理数据库连接。
- 一个班级只有一个班主任。
- Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。
- 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
- 要求生产唯一序列号。
- WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
- 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
建造者模式(Builder Pattern)
- 文章编辑器中的文章构建器,根据用户输入的内容构建文章对象。
- 游戏角色创建器,根据用户选择的角色特征构建游戏角色对象。
- 套餐订单构建器,根据用户选择的商品组合构建订单对象。
- 电子商务网站中的购物车构建器,根据用户选购商品构建购物车对象。
- 自定义表单构建器,根据用户需求构建自定义表单对象。
- 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。
- JAVA 中的 StringBuilder。
原型模式(Prototype Pattern)
- 游戏开发中的角色克隆器,用于制作游戏角色的副本。
- 文档编辑器中的文档复制器,用于复制文档并进行修改。
- 模板复制器,用于复制模板文件以创建新的文档。
- 图像处理软件中的图像克隆器,用于制作图像的副本并进行编辑。
- 电子商务网站中的商品克隆器,用于复制商品以创建新的商品对象。
- 细胞分裂。
- JAVA 中的 Object clone() 方法。
- 一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
- 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
- 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
- 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone的方法创建一个对象,然后由工厂方法提供给调用者。
适配器模式(Adapter Pattern)
- 在新系统中使用旧版接口的适配器。
- 将不同的日志记录器适配为统一的接口以便使用。
- 将不同数据库API适配为统一的数据访问接口。
- 将不同的支付接口适配为系统内部的支付处理器。
- 将外部API适配为内部系统的数据交换格式。
- 读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
- 美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。
- JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。
- 在 LINUX 上运行 WINDOWS 程序。
- JAVA 中的 jdbc。
桥接模式(Bridge Pattern)
- 在不同平台上实现相同功能的桥接实现。
- 将不同数据库和ORM框架进行桥接。
- 将不同的图形库和绘图引擎进行桥接。
- 在不同操作系统上实现相同的界面桥接。
- 将不同的通信协议进行桥接。
- 墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。
过滤器模式(Filter Pattern)
- 判断用户是否登录或具有访问权限,如使用Authorize特性来限制只有通过身份验证的用户才能访问某些控制器或操作方法。
- 实现自定义的授权逻辑,如根据用户的角色、权限、IP地址等来决定是否允许访问。
- 实现一些全局的安全策略,如防止CSRF攻击、加密或解密请求参数等。
- 实现常见的错误处理策略,如捕获并处理控制器或操作方法中发生的未处理的异常,返回统一的错误信息或页面。
- 记录或分析异常信息,如记录异常日志,发送异常通知,收集异常统计等。
- 根据不同的异常类型或来源,执行不同的处理逻辑,如重定向到不同的错误页面,返回不同的错误码等。
组合模式(Composite Pattern)
- 构建树状结构的菜单和子菜单。
- 文件系统中的文件夹和文件结构。
- 组织架构中的部门和员工关系。
- 在图形界面中构建复杂的UI组件。
- 电子设备中的电路板和电子元件组合。
- 算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作符和另一个操作数。
- 在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
- 部分、整体场景,如树形菜单,文件、文件夹的管理。
装饰器模式(Decorator Pattern)
- 在文本编辑器中添加字体、颜色和样式装饰器。
- 在图像处理软件中添加滤镜和效果装饰器。
- 在日志记录系统中添加日志格式化和输出装饰器。
- 在游戏中添加武器和装备的属性装饰器。
- 在报表生成系统中添加图表和数据可视化装饰器。
- 孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。
- 不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。
- 扩展一个类的功能,动态增加功能,动态撤销。
外观模式(Facade Pattern)
- 向用户提供简化的订单处理接口。
- 对外部服务进行封装,提供统一的接口。
- 在系统中提供统一的认证和授权接口。
- 将复杂的数据处理流程封装为简单的
- 去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。
- JAVA 的三层开发模式。界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据库操作层(Data access layer)。
- 为复杂的模块或子系统提供外界访问的模块。
- 子系统相对独立。
- 预防低水平人员带来的风险。
享元模式(Flyweight Pattern)
- JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。
- 数据库的连接池。
- 系统有大量相似对象。
- 需要缓冲池的场景。
代理模式(Proxy Pattern)
- Windows 里面的快捷方式。
- 猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。
- 买火车票不一定在火车站买,也可以去代售点。
- 一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。
- spring aop。
- 按职责来划分,通常有以下使用场景: 1、远程代理。 2、虚拟代理。 3、Copy-on-Write 代理。 4、保护(Protect or Access)代理。 5、Cache代理。 6、防火墙(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。
责任链模式(Chain of Responsibility Pattern)
- JS 中的事件冒泡。
- JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。
命令模式(Command Pattern)
- GUI中每一个按钮都是一条命令。
- 模拟CMD。
解释器模式(Interpreter Pattern)
- 编译器。
- 运算表达式计算。
- 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
- 一些重复出现的问题可以用一种简单的语言来进行表达。
- 一个简单语法需要解释的场景。
迭代器模式(Iterator Pattern)
- JAVA 中的 iterator。
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 需要为聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口。
中介者模式(Mediator Pattern)
- 中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。
- 机场调度系统。
- MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。
- 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
备忘录模式(Memento Pattern)
- 打游戏时的存档。
- Windows 里的 ctrl + z。
- IE 中的后退。
- 数据库的事务管理。
- 需要保存/恢复数据的相关状态场景。
- 提供一个可回滚的操作。
观察者模式(Observer Pattern)
- 拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
- 西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
状态模式(State Pattern)
- 打篮球的时候运动员可以有正常状态、不正常状态和超常状态。
- 曾侯乙编钟中,‘钟是抽象接口’,'钟A’等是具体状态,'曾侯乙编钟’是具体环境(Context)。
- 行为随状态改变而改变的场景。
- 条件、分支语句的代替者。
策略模式(Strategy Pattern)
- 诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
- 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
- JAVA AWT 中的 LayoutManager。
- 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
- 一个系统需要动态地在几种算法中选择一种。
- 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
模板模式(Template Pattern)
- 在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。
- 西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。
- spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。
- 有多个子类共有的方法,且逻辑相同。
- 重要的、复杂的方法,可以考虑作为模板方法。