图说设计模式笔记#1
前言
之前自己也学习过设计模式,但是学了之后大部分设计模式没怎么在实际场景中使用过,导致知识点遗忘的差不多了。偶然间发现了me115/design_patterns 这个开源项目,趁此机会打算再系统得学习巩固一下设计模式知识。
图说设计模式:本书使用图形和代码结合的方式来解析设计模式
引用自图说设计模式
UML图形符号
关系 | 说明 | 符号说明 | plantuml写法 | 图形 |
---|---|---|---|---|
实现关系 | 继承抽象类 | 带空心三角箭头的虚线 | <|… | |
泛化关系 | 继承非抽象类 | 带空心三角箭头的实线 | <|-- | |
组合关系 | 是一种强依赖的特殊聚合关系,如果整体不存在了,则部分也不存在了 | 带实心菱形箭头的实线 | *-- | |
聚合关系 | 整体由部分构成,整体与部分不是强依赖,即使整体不存在了,部分依然存在 | 带空心菱形箭头的实线 | o-- | |
关联关系 | 描述不同类的对象之间的结构关系,是一种静态关系,与运行状态无关,是一种强关联的关系,默认不强调方向,表示对象间互相知道,如果A–>B 表示A知道B,B不知道A。在代码中通常以成员变量的形式实现。 | 实线 | -- | |
依赖关系 | 描述一个对象在运行期间会用到另一个对象的关系,与关联关系不同的是,它是一种临时性的关系,在运行间产生。在代码中表现为类构造方法及类方法的传入参数 | 带箭头的虚线 | <… |
设计模式按类型区分
- 创建型模式
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
- 建造者模式(Builder)
- 原型模式(Prototype)
- 单例模式(Singleton)
- 结构型模式
- 适配器模式(Adapter)
- 桥接模式(Bridge)
- 组合模式(Composite)
- 装饰模式(Decorator)
- 外观模式(Facade)
- 享元模式(Flyweight)
- 代理模式(Proxy)
- 行为型模式
- 职责链模式(Chain of Responsibility)
- 命令模式(Command)
- 解释器模式(Interpreter)
- 迭代器模式(Iterator)
- 中介者模式(Mediator)
- 备忘录模式(Memento)
- 观察者模式(Observer)
- 状态模式(State)
- 策略模式(Strategy)
- 模板方法模式(Template Method)
- 访问者模式(Visitor)
什么是创建型模式
创建型模式对类的实例化过程进行了抽象,将对象的创建和使用过程分离。使得外界只需要知道它们共同的接口,而不清楚具体的实线细节,使系统符合单一职责原则。
简单工厂模式
模式动机
提供一个方法,传入不同的参数来返回需要的对象。
模式定义
在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
模式结构
- Factory:工厂角色,实现创建实例的逻辑
- Product:抽象产品角色,工厂创建的所有对象的父类,负责描述所有实例的公共接口
- ConcreteProduct:具体产品角色,最终创建的目标
时序图
代码实现
1 |
|
简单工厂模式优缺点
- 优点
- 工厂类包含判断逻辑,客户端没有创建产品的责任,只需要消费产品;通过此方式实现了对责任的分割
- 客户端需要知道所创建具体产品的类名,只需要知道创建产品的参数即可,对于复杂类名,通过简单工厂模式可以减少使用者的记忆量
- 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性
- 缺点
- 工厂类集中了所有产品的创建逻辑,一旦出问题,整个系统都要受影响
- 使用简单工厂模式会增加系统类的个数,在一定程度上增加了系统的复杂度和理解难度
- 系统拓展困难,添加新产品就不得不修改工厂类,产品数量增多后可能会造成工厂逻辑变复杂,不利于系统拓展和维护
- 由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构
适用环境
- 工厂类负责创建的对象比较少,逻辑不太复杂
- 客户端只知道工厂类的参数,对创建对象的细节不关心
模式应用
-
java.text.DateFormat
1
2
3
4public final static DateFormat getDateInstance();
public final static DateFormat getDateInstance(int style);
public final static DateFormat getDateInstance(int style,Locale
locale); -
java加密技术
1
KeyGenerator keyGen=KeyGenerator.getInstance("DESede");
工厂方法模式
模式动机
创建过程交给专门的工厂子类去完成。每当出现一个新的产品,只需要为新产品创建一个具体的工厂类就可以,这一特点使得工厂方法模式具有超越简单工厂模式的优越性,更加符合开闭原则
。
模式定义
工厂方法模式又被称为工厂模式,也叫虚拟构造器模式或者多态模式。在工厂模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生成具体的产品对象。
模式结构
- Product:抽象产品
- ConcreteProduct:具体产品
- Factory:抽象工厂
- ConcreteFactory:具体工厂
代码实现
父类工厂
1 |
|
工厂子类
1 |
|
使用
1 |
|
模式分析
使用了面向对象的多态性。核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类,核心类仅仅负责子类必须实现的接口,不负责哪个产品被实例化的细节,使得允许系统在不修改工厂角色的情况下引进新产品
使用场景
-
日志记录器
工厂方法模式优缺点
- 优点
- 用户只需要关心所需产品对应的工厂,无须关心创建细节
- 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,使得工厂子类可以自己决定创建何种产品,自己实现创建逻辑
- 系统中加入新产品时,只要添加一个具体工厂和具体产品就可以,系统的扩展性就变得非常好,完全符合开闭原则
- 缺点
- 新增产品时需要编写新的具体产品类,也要提供与之对应的具体工厂类,系统中的类数量成对增加,一定程度上增加了系统的复杂度,以及增加系统编译运行的开销
- 增加抽象层的定义,增加了系统的抽象性和理解难度
适用环境
- 一个类不知道它所需要的对象的类,但要知道创建这个对象的具体工厂类
- 一个类用过其子类来指定创建哪个对象
- 将创建对象的任务委托个多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时在动态指定,可将具体工厂类名存储在配置文件或数据库中
模式应用
-
JDBC中的工厂方法
1
2
3Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");
模式拓展
- 在抽象工厂角色可以中定义多个工厂方法
- 产品对象的重复使用:工厂对象将已经创建过的产品保存到一个集合中,然后根据客户对产品的请求,再对集合进行查询
图说设计模式笔记#1
https://blog.kedr.cc/posts/3935682145/