zoukankan      html  css  js  c++  java
  • Go 设计模式 工厂模式

    Go 设计模式 - 工厂模式

    简单工厂模式

    go 语言没有构造函数一说,所以一般会定义NewXXX函数来初始化相关类。
    NewXXX 函数返回接口时就是简单工厂模式,也就是说Golang的一般推荐做法就是简单工厂。

    在这个simplefactory包中只有API 接口和NewAPI函数为包外可见,封装了实现细节。

    simple.go代码

    package simplefactory
    
    import "fmt"
    
    //API is interface
    type API interface {
        Say(name string) string
    }
    
    //NewAPI return Api instance by type
    func NewAPI(t int) API {
        if t == 1 {
            return &hiAPI{}
        } else if t == 2 {
            return &helloAPI{}
        }
        return nil
    }
    
    //hiAPI is one of API implement
    type hiAPI struct{}
    
    //Say hi to name
    func (*hiAPI) Say(name string) string {
        return fmt.Sprintf("Hi, %s", name)
    }
    
    //HelloAPI is another API implement
    type helloAPI struct{}
    
    //Say hello to name
    func (*helloAPI) Say(name string) string {
        return fmt.Sprintf("Hello, %s", name)
    }
    

      

    simple_test.go代码

    package simplefactory
    
    import "testing"
    
    //TestType1 test get hiapi with factory
    func TestType1(t *testing.T) {
        api := NewAPI(1)
        s := api.Say("Tom")
        if s != "Hi, Tom" {
            t.Fatal("Type1 test fail")
        }
    }
    
    func TestType2(t *testing.T) {
        api := NewAPI(2)
        s := api.Say("Tom")
        if s != "Hello, Tom" {
            t.Fatal("Type2 test fail")
        }
    }
    

      


    工厂方法模式

    工厂方法模式使用子类的方式延迟生成对象到子类中实现。

    Go中不存在继承 所以使用匿名组合来实现

    factorymethod.go

    package factorymethod
    
    //Operator 是被封装的实际类接口
    type Operator interface {
        SetA(int)
        SetB(int)
        Result() int
    }
    
    //OperatorFactory 是工厂接口
    type OperatorFactory interface {
        Create() Operator
    }
    
    //OperatorBase 是Operator 接口实现的基类,封装公用方法
    type OperatorBase struct {
        a, b int
    }
    
    //SetA 设置 A
    func (o *OperatorBase) SetA(a int) {
        o.a = a
    }
    
    //SetB 设置 B
    func (o *OperatorBase) SetB(b int) {
        o.b = b
    }
    
    //PlusOperatorFactory 是 PlusOperator 的工厂类
    type PlusOperatorFactory struct{}
    
    func (PlusOperatorFactory) Create() Operator {
        return &PlusOperator{
            OperatorBase: &OperatorBase{},
        }
    }
    
    //PlusOperator Operator 的实际加法实现
    type PlusOperator struct {
        *OperatorBase
    }
    
    //Result 获取结果
    func (o PlusOperator) Result() int {
        return o.a + o.b
    }
    
    //MinusOperatorFactory 是 MinusOperator 的工厂类
    type MinusOperatorFactory struct{}
    
    func (MinusOperatorFactory) Create() Operator {
        return &MinusOperator{
            OperatorBase: &OperatorBase{},
        }
    }
    
    //MinusOperator Operator 的实际减法实现
    type MinusOperator struct {
        *OperatorBase
    }
    
    //Result 获取结果
    func (o MinusOperator) Result() int {
        return o.a - o.b
    }

    factorymethod_test.go

    package factorymethod
    
    import "testing"
    
    func compute(factory OperatorFactory, a, b int) int {
        op := factory.Create()
        op.SetA(a)
        op.SetB(b)
        return op.Result()
    }
    
    func TestOperator(t *testing.T) {
        var (
            factory OperatorFactory
        )
    
        factory = PlusOperatorFactory{}
        if compute(factory, 1, 2) != 3 {
            t.Fatal("error with factory method pattern")
        }
    
        factory = MinusOperatorFactory{}
        if compute(factory, 4, 2) != 2 {
            t.Fatal("error with factory method pattern")
        }
    }
    

      


     创建者模式

    将一个复杂对象的构建分离成多个简单对象的构建组合

    builder.go

    package builder
    
    //Builder 是生成器接口
    type Builder interface {
        Part1()
        Part2()
        Part3()
    }
    
    type Director struct {
        builder Builder
    }
    
    // NewDirector ...
    func NewDirector(builder Builder) *Director {
        return &Director{
            builder: builder,
        }
    }
    
    //Construct Product
    func (d *Director) Construct() {
        d.builder.Part1()
        d.builder.Part2()
        d.builder.Part3()
    }
    
    type Builder1 struct {
        result string
    }
    
    func (b *Builder1) Part1() {
        b.result += "1"
    }
    
    func (b *Builder1) Part2() {
        b.result += "2"
    }
    
    func (b *Builder1) Part3() {
        b.result += "3"
    }
    
    func (b *Builder1) GetResult() string {
        return b.result
    }
    
    type Builder2 struct {
        result int
    }
    
    func (b *Builder2) Part1() {
        b.result += 1
    }
    
    func (b *Builder2) Part2() {
        b.result += 2
    }
    
    func (b *Builder2) Part3() {
        b.result += 3
    }
    
    func (b *Builder2) GetResult() int {
        return b.result
    }
    

    builder_test.go

    package builder
    
    import "testing"
    
    func TestBuilder1(t *testing.T) {
        builder := &Builder1{}
        director := NewDirector(builder)
        director.Construct()
        res := builder.GetResult()
        if res != "123" {
            t.Fatalf("Builder1 fail expect 123 acture %s", res)
        }
    }
    
    func TestBuilder2(t *testing.T) {
        builder := &Builder2{}
        director := NewDirector(builder)
        director.Construct()
        res := builder.GetResult()
        if res != 6 {
            t.Fatalf("Builder2 fail expect 6 acture %d", res)
        }
    }
    

     单例模式

    使用懒惰模式的单例模式,使用双重检查加锁保证线程安全

    singleton.go

    package singleton
    
    import "sync"
    
    //Singleton 是单例模式类
    type Singleton struct{}
    
    var singleton *Singleton
    var once sync.Once
    
    //GetInstance 用于获取单例模式对象
    func GetInstance() *Singleton {
        once.Do(func() {
            singleton = &Singleton{}
        })
    
        return singleton
    }
    

    singleton_test.go

    package singleton
    
    import (
        "sync"
        "testing"
    )
    
    const parCount = 100
    
    func TestSingleton(t *testing.T) {
        ins1 := GetInstance()
        ins2 := GetInstance()
        if ins1 != ins2 {
            t.Fatal("instance is not equal")
        }
    }
    
    func TestParallelSingleton(t *testing.T) {
        wg := sync.WaitGroup{}
        wg.Add(parCount)
        instances := [parCount]*Singleton{}
        for i := 0; i < parCount; i++ {
            go func(index int) {
                instances[index] = GetInstance()
                wg.Done()
            }(i)
        }
        wg.Wait()
        for i := 1; i < parCount; i++ {
            if instances[i] != instances[i-1] {
                t.Fatal("instance is not equal")
            }
        }
    }
    

      

  • 相关阅读:
    CC初试啼声-----演讲与我
    static关键字修饰类
    maven可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)
    Installation Directory must be on a local hard drive解决办法
    回顾JDBC
    java中的定时器
    怎么删除windows中无用的服务
    java实现简单的素数判断
    SQL注入
    @Override must override a superclass method 问题解决
  • 原文地址:https://www.cnblogs.com/zakun/p/15355478.html
Copyright © 2011-2022 走看看