设计模式
什么是设计模式?
设计模式是软件设计中常见问题的典型解决方案。 它们就像能根据需求进行调整的预制蓝图, 可用于解决代码中反复出现的设计问题。
设计模式与方法或库的使用方式不同, 你很难直接在自己的程序中套用某个设计模式。 模式并不是一段特定的代码, 而是解决特定问题的一般性概念。 你可以根据模式来实现符合自己程序实际所需的解决方案。
人们常常会混淆模式和算法, 因为两者在概念上都是已知特定问题的典型解决方案。 但算法总是明确定义达成特定目标所需的一系列步骤, 而模式则是对解决方案的更高层次描述。 同一模式在两个不同程序中的实现代码可能会不一样。
算法更像是菜谱: 提供达成目标的明确步骤。 而模式更像是蓝图: 你可以看到最终的结果和模式的功能, 但需要自己确定实现步骤。
六大原则
设计模式遵循六大原则:
- 单一职责(一个类和方法只做一件事)
- 里氏替换(多态,子类可扩展父类)
- 依赖倒置(细节依赖抽象,下层依赖上层)
- 接口隔离(建立单一接口)
- 迪米特原则(最少知道,降低耦合)
- 开闭原则(抽象架构,扩展实现)
分类
设计模式可以根据其意图或目的来分类。共三种主要的模式类别:
- 创建型模式提供创建对象的机制,增加已有代码的灵活性和可复用性。
- 结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
- 行为模式负责对象间的高效沟通和职责委派。
设计模式分类及具体
创建型模式
行为模式
详细
工厂方法
实现要点:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
优点;
- 避免创建者与具体的产品逻辑耦合
- 满足单一职责,每一个业务逻辑实现都在所属自己的类中完成
- 满足开闭原则,无需更改使用调用方就可以在程序中引入新的产品类型
场景:周期运行的用户分群,可以按每天(小时:分钟)、每周(周X的小时:分钟)、每月(X号的小时:分钟)开始运行
实现:可以定义一个接口SegmentScheduleTimeParser
public abstract class SegmentScheduleTimeParser {
SegmentScheduleTimeResp parse(SegmentScheduleTimeReq req);
}和一个工厂类
public final SegmentScheduleTimeParserFactory {
SegmentScheduleTimeParser getParser(SegmentScheduleTimeReq req);
}额外特点:
- SegmentScheduleTimeParserFactory类可以是一个单例类
- SegmentScheduleTimeParserFactory类来确定要返回哪一个实现类,在Factory中可以使用Map结构来保存SegmentScheduleTimeParser,省去if-else代码
- 工厂方法可以只对外提供SegmentScheduleTimeParserFactory类和SegmentScheduleTimeParser接口,其它类均是package级别(不用设置为public级别)
抽象工厂
与工厂方法的区别:工厂方法返回的一个接口,而抽象工厂返回的却是多个接口。
使用抽象工厂模式一般要满足以下条件。
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件。如 Java 的 AWT 中的 Button 和 Text 等构件在 Windows 和 UNIX 中的本地实现是不同的。
抽象工厂在Java源码中的应用:
抽象工厂模式在Spring源码中的应用:
场景:盖房子的材料不同
吊顶:装修公司自带、二级顶、平米价格:850 元。
涂料:多乐士(Dulux)、第⼆二代、平米价格:719 元。
地板:圣象、一级、平米价格:318 元。
public interface DecorationAbstractFactory {
Ceiling getCelling();
Coat getCoat();
Floor getFloor();
Tile getTile();
}建造者模式
链式编程
原型模式
游戏中怪物模板配置对一个对象,但是在战斗场景中出现的怪物都是从怪物模板中复制出来了。我以前出现的一个问题是结束一场战斗后下次再遇到该怪物发现怪物的血是负的。
单例模式
- 懒汉式
- 饿汉式
- 双重校验
- 静态内部类
- 枚举
结构型模式
适配器模式
最后编辑:张三 更新时间:2026-03-05 17:51