飞道的博客

Golang设计模式一: 创建型模式

226人阅读  评论(0)

Golang设计模式: 创建型模式

creational

创建型设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

描述

  1. 单例模式
    俺有 6 个漂亮的老婆,她们的老公都是我,我就是我们家里的老公 Sigleton,她们只要说道「老公」,都是指的同一个人,那就是我 (刚才做了个梦啦,哪有这么好的事)

    单例模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的 “单一实例” 的需求时才可使用。

    package Sigleton
    
    import "sync"
    
    var (
    	p    *Pet
    	once sync.Once
    )
    
    type Pet struct {
         
    	name string
    	age  int
    	mux  sync.Mutex
    }
    
    func GetInstance() *Pet {
         
    	once.Do(func() {
         
    		p = &Pet{
         }
    	})
    	return p
    }
    
  2. 原型模式
    跟 MM 用 QQ 聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要 copy 出来放到 QQ 里面就行了,这就是我的情话 prototype 了。(100 块钱一份,你要不要)

    原始模型模式:通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构。缺点是每一个类都必须配备一个克隆方法。

    package Prototype
    
    type Prototype interface {
         
    	Name() string
    	Clone() Prototype
    }
    
    type ConcretePrototype struct {
         
    	name string
    }
    
    func (p *ConcretePrototype) Name() string{
         
    	return p.name
    }
    
    func (p *ConcretePrototype) Clone() Prototype{
         
    	return &ConcretePrototype{
         name:p.name}
    }
    
  3. 工厂方法模式
    追 MM 少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是 MM 爱吃的东西,虽然口味有所不同,但不管你带 MM 去麦当劳或肯德基,只管向服务员说「来四个鸡翅」就行了。麦当劳和肯德基就是生产鸡翅的 Factory 工厂模式:客户类和工厂类分开。

    消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时,工厂类也要做相应的修改。如:如何创建及如何向客户端提供

    package Factory
    
    import "fmt"
    
    type Restaurant interface {
         
    	GetFood()
    }
    
    type Donglaishun struct {
         
    }
    
    func (d *Donglaishun) GetFood() {
         
    	fmt.Println("东来顺的饭菜准备继续")
    }
    
    type Qingfeng struct {
         
    }
    
    func (q *Qingfeng) GetFood() {
         
    	fmt.Println("庆丰包子铺饭菜准备就绪")
    }
    
    /*
    1. 定义产品接口Restaurant
    2. 定义不同产品结构体并分别实现接口
    3. 提供同一入口, 根据传参不同, 创建不同的产品结构体
    */
    func NewRestaurant(s string) Restaurant {
         
    	switch s {
         
    	case "d":
    		return &Donglaishun{
         }
    	case "q":
    		return &Qingfeng{
         }
    	}
    	return nil
    }
    
  4. 抽象工厂模式
    请 MM 去麦当劳吃汉堡,不同的 MM 有不同的口味,要每个都记住是一件烦人的事情,我一般采用 Factory Method 模式,带着 MM 到服务员那儿,说「要一个汉堡」,具体要什么样的汉堡呢,让 MM 直接跟服务员说就行了。

    工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

    package Abstract_Factory
    
    import "fmt"
    
    type Lunch interface {
         
    	Cook()
    }
    
    type rise struct {
         
    }
    
    func (c *rise) Cook() {
         
    	fmt.Println("it is a rise.")
    }
    
    type Tomato struct {
         
    }
    
    func (c *Tomato) Cook() {
         
    	fmt.Println("it is Tomato.")
    }
    
    type LunchFactory interface {
         
    	CreateFood() Lunch
    	CreateVegetable() Lunch
    }
    
    type simpleLunchFactory struct {
         
    }
    
    /*
    1. 定义产品接口Lunch
    2. 定义不同产品结构体并分别实现接口
    3. 定义抽象工厂接口
    4. 定义抽象工厂结构体, 分别实现抽象工厂接口, 生成相应的产品结构体
    */
    func NewSimpleShapeFactory() LunchFactory {
         
    	return &simpleLunchFactory{
         }
    }
    
    func (s *simpleLunchFactory) CreateFood() Lunch {
         
    	return &rise{
         }
    }
    
    func (s *simpleLunchFactory) CreateVegetable() Lunch {
         
    	return &Tomato{
         }
    }
    
  5. 建造者模式
    MM 最爱听的就是「我爱你」这句话了,见到不同地方的 MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到 MM 我只要按对应的键,它就能够用相应的语言说出「我爱你」这句话了,国外的 MM 也可以轻松搞掂,这就是我的「我爱你」builder。

    建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。

    package Builder
    
    import (
    	"fmt"
    )
    
    //产品角色
    type Car struct {
         
    	Brand string
    	Type  string
    	Color string
    }
    
    func (this *Car) Drive() error {
         
    	fmt.Printf("A %s %s %s car is running on the road!\n", this.Color, this.Type, this.Brand)
    	return nil
    }
    
    //建造者角色
    type Builder interface {
         
    	PaintColor(color string) Builder
    	AddBrand(brand string) Builder
    	SetType(t string) Builder
    	Build() Car
    }
    
    //具体的建造者
    type ConcreteBuilder struct {
         
    	ACar Car
    }
    
    func (this *ConcreteBuilder) PaintColor(cor string) Builder {
         
    	this.ACar.Color = cor
    	return this
    }
    
    func (this *ConcreteBuilder) AddBrand(bnd string) Builder {
         
    	this.ACar.Brand = bnd
    	return this
    }
    
    func (this *ConcreteBuilder) SetType(t string) Builder {
         
    	this.ACar.Type = t
    	return this
    }
    
    func (this *ConcreteBuilder) Build() Car {
         
    	return this.ACar
    }
    
    //导演者角色
    type Director struct {
         
    	Builder Builder
    }
    
    package Builder
    
    import (
    	"testing"
    )
    
    func TestConcreteBuilder(t *testing.T) {
         
    	dr := Director{
         &ConcreteBuilder{
         }}
    	adCar := dr.Builder.SetType("SUV").AddBrand("奥迪").PaintColor("white").Build()
    	adCar.Drive()
    
    	bwCar := dr.Builder.SetType("sporting").AddBrand("宝马").PaintColor("red").Build()
    	bwCar.Drive()
    }
    

关系

单例与原型: 创建单例, 通过原型进行复制
工厂与抽象工厂: 工厂提供同一入口, 通过传参不同创建不同结构体; 抽象提供不同入口, 分别创建不同结构体
建造者: 将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象

相关文档

design-patterns-in-golang
Golang设计模式之观察者模式
渣男 23 式 | 23 种设计模式的通俗解释,看完秒懂


转载:https://blog.csdn.net/qq_36652517/article/details/116545896
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场