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:简单工厂模式所创建的具体实例对象。

The Simple Factory pattern

:smile:

  1. 实现了对象创建和使用(于业务逻辑层)的分离。
  2. 不需要记住具体类名,记住参数即可,减少使用者记忆量。

:cry:

  1. 对工厂类职责过重,一旦不能工作,系统受到影响。
  2. 增加系统中类的个数,复杂度和理解度增加。
  3. 违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂。

:construction_worker:

  1. 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  2. 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

Factory Method

工厂方法:简单工厂 + “开闭原则”。工厂和具体产品都有抽象,业务逻辑面向抽象,符合依赖倒置。

  • 抽象工厂 Abstract Factory:工厂方法模式的核心,任何工厂类都必须实现这个接口。
  • 工厂 Concrete Factory:具体工厂类是抽象工厂的一个实现,负责实例化产品对象。
  • 抽象产品 Abstract Product:工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
  • 具体产品 Concrete Product:工厂方法模式所创建的具体实例对象。

The structure of the Factory Method pattern

:smile:

  1. 不需要记住具体类名,甚至连具体参数都不用记忆。
  2. 实现了对象创建和使用的分离。
  3. 系统的可扩展性也就变得非常好,无需修改接口和原类。
  4. 对于新产品的创建,符合开闭原则。

:cry:

  1. 增加系统中类的个数,复杂度和理解度增加。
  2. 增加了系统的抽象性和理解难度。

:construction_worker:

  1. 客户端不知道它所需要的对象的类。
  2. 抽象工厂类通过其子类来指定创建哪个对象。

Abstract Factory Method

:cry: 工厂方法每个工厂只生产一类产品,每增加一个产品,都要增加对应的工厂类。

:smile: 抽象工厂方法:将一些相关的产品组成一个**“产品族”**,由同一个工厂来统一生产,“工厂的工厂”。

  • 抽象工厂 Abstract Factory:它声明了一组用于创建产品族的方法,每一个方法对应一种产品。
  • 具体工厂 Concrete Factory:它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
  • 抽象产品 Abstract Product:它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • 具体产品 Concrete Product:它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

Abstract Factory design pattern

产品族 & 产品等级结构

  • 产品族:具有同一个地区、同一个厂商、同一个开发包、同一个组织模块,但具备不同功能产品的结合。
  • 产品等级结构:具有相同功能,但是来自不同的地区、不同的厂商、不同的开发包、不同的组织模块等的产品集合。
img

:smile:

  1. 拥有工厂方法模式的优点
  2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
  3. 增加新产品族很方便,无须修改已有系统,符合“开闭原则”。

:cry:

  1. 增加新产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背“开闭原则”。
  2. 如果划分不出产品等级和产品结构,且不稳定,就不要用抽象工厂方法。

:construction_worker:

  1. 系统中有多于一个的产品族。而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
  2. 产品等级结构稳定。设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。

Singleton

单例:

  1. 类只能有一个实例;
  2. 该必须自行创建这个实例;
  3. 该必须自行向整个系统提供这个实例 = 提供全局访问方法。

类别:

  1. Hungry:在初始化单例唯一指针的时候,就已经提前开辟好了一个对象,申请了内存。

    :smile: 不会出现线程并发创建,导致多个单例的出现。

    :cry: 如果这个单例对象在业务逻辑没有被使用,也会客观的创建一块内存对象,对于大对象浪费内存。

  2. Lazy:只有在尝试获取的才会创建实例。

    :smile: 节约内存。

    :cry: 线程不安全,需要加锁。但加锁对于高并发也会影响性能。

    优化:使用原子操作作 flag,若为 1 那么直接返回实例。否则加锁判 nil 创建实例。或直接 once.do 确保只执行一次。

The structure of the Singleton pattern

:smile:

  1. 单例模式提供了对唯一实例的受控访问。
  2. 节约系统资源。由于在系统内存中只存在一个对象。

:cry:

  1. 扩展略难。单例模式中没有抽象层。
  2. 节约系统资源。由于在系统内存中只存在一个对象。

:construction_worker:

  1. 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
  2. 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。