package
0.0.0-20240828052546-079cc6e6950d
Repository: https://github.com/kokoiruby/go_learning.git
Documentation: pkg.go.dev
# README
Creational
模式名称 | 模式名称 | 作用 |
---|---|---|
创建型模式 | 单例模式 ★★★★☆ | 是保证一个类仅有一个实例,并提供一个访问它的全局访问点。 |
简单工厂模式 ★★★☆☆ | 通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 | |
工厂方法模式 ★★★★★ | 定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。 | |
抽象工厂模式 ★★★★★ | 提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。 | |
原型模式 ★★★☆☆ | 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 | |
建造者模式 ★★☆☆☆ | 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 |
Why Factory?
如果没有工厂模式,在开发者创建一个类型对象时,如果有很多不同子类型的对象将会如何实现?
- 可能导致类中包含很多 if/else
- 类的职责过重,需要负责初始化其他子类,违反单一原则。
- 当增加新的类型,需要修改构造函数,违反了开闭原则。
- 业务逻辑层会直接依赖基础类模块,当主类型变化时,业务逻辑代码也会随之改变。
∴ 将业务层创建对象与基础类模块做解耦 → 中间加一层工厂模块层。业务层不需要考虑基础类对象是如何创建的,具体创建的实现由工厂来决定。
Simple Factory
- 工厂 Factory:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
- 抽象产品 Abstract Product:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- 具体产品 Concrete Product:简单工厂模式所创建的具体实例对象。
:smile:
- 实现了对象创建和使用(于业务逻辑层)的分离。
- 不需要记住具体类名,记住参数即可,减少使用者记忆量。
:cry:
- 对工厂类职责过重,一旦不能工作,系统受到影响。
- 增加系统中类的个数,复杂度和理解度增加。
- 违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂。
:construction_worker:
- 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。
Factory Method
工厂方法:简单工厂 + “开闭原则”。工厂和具体产品都有抽象,业务逻辑面向抽象,符合依赖倒置。
- 抽象工厂 Abstract Factory:工厂方法模式的核心,任何工厂类都必须实现这个接口。
- 工厂 Concrete Factory:具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
- 抽象产品 Abstract Product:工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- 具体产品 Concrete Product:工厂方法模式所创建的具体实例对象。
:smile:
- 不需要记住具体类名,甚至连具体参数都不用记忆。
- 实现了对象创建和使用的分离。
- 系统的可扩展性也就变得非常好,无需修改接口和原类。
- 对于新产品的创建,符合开闭原则。
:cry:
- 增加系统中类的个数,复杂度和理解度增加。
- 增加了系统的抽象性和理解难度。
:construction_worker:
- 客户端不知道它所需要的对象的类。
- 抽象工厂类通过其子类来指定创建哪个对象。
Abstract Factory Method
:cry: 工厂方法每个工厂只生产一类产品,每增加一个产品,都要增加对应的工厂类。
:smile: 抽象工厂方法:将一些相关的产品组成一个**“产品族”**,由同一个工厂来统一生产,“工厂的工厂”。
- 抽象工厂 Abstract Factory:它声明了一组用于创建产品族的方法,每一个方法对应一种产品。
- 具体工厂 Concrete Factory:它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
- 抽象产品 Abstract Product:它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
- 具体产品 Concrete Product:它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
产品族 & 产品等级结构
- 产品族:具有同一个地区、同一个厂商、同一个开发包、同一个组织模块,但具备不同功能产品的结合。
- 产品等级结构:具有相同功能,但是来自不同的地区、不同的厂商、不同的开发包、不同的组织模块等的产品集合。

:smile:
- 拥有工厂方法模式的优点
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
- 增加新产品族很方便,无须修改已有系统,符合“开闭原则”。
:cry:
- 增加新产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背“开闭原则”。
- 如果划分不出产品等级和产品结构,且不稳定,就不要用抽象工厂方法。
:construction_worker:
- 系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
- 产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
Singleton
单例:
- 类只能有一个实例;
- 该必须自行创建这个实例;
- 该必须自行向整个系统提供这个实例 = 提供全局访问方法。
类别:
-
Hungry:在初始化单例唯一指针的时候,就已经提前开辟好了一个对象,申请了内存。
:smile: 不会出现线程并发创建,导致多个单例的出现。
:cry: 如果这个单例对象在业务逻辑没有被使用,也会客观的创建一块内存对象,对于大对象浪费内存。
-
Lazy:只有在尝试获取的才会创建实例。
:smile: 节约内存。
:cry: 线程不安全,需要加锁。但加锁对于高并发也会影响性能。
优化:使用原子操作作 flag,若为 1 那么直接返回实例。否则加锁判 nil 创建实例。或直接 once.do 确保只执行一次。
:smile:
- 单例模式提供了对唯一实例的受控访问。
- 节约系统资源。由于在系统内存中只存在一个对象。
:cry:
- 扩展略难。单例模式中没有抽象层。
- 节约系统资源。由于在系统内存中只存在一个对象。
:construction_worker:
- 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
- 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。