一文搞定 Go 工厂模式

382 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

前言

工厂模式是我们最常用的实例化对象模式之一了,工厂模式是一种用来创建对象的设计模式,我们不暴露对象创建的逻辑,而是将逻辑封装在一个函数内,通过使用一个共同的接口来指向新创建的对象。比如说,你需要一辆自行车,你可以给工厂一个指令,然后工厂就给你一辆自行车。工厂模式根据抽象程度的不同可以分为:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式,下面通过一些例子来理解工厂上述三种模式。需要的朋友可以参考以下内容,希望对大家有帮助。

简单工厂模式

go语言中没有构造函数,我们通常会定义NewXXX函数来初始化相关类。根据不同参数返回不同类的实例。

Demo示例如下:

package main

import "fmt"

type Person struct {
	Name string `json:"name"`
	Sex  string `json:"sex"`
}

func NewPerson(name, sex string) *Person {
	return &Person{Name: name, Sex: sex}
}

func main()  {
	person := NewPerson("小明", "男")
	fmt.Println(person.Name)
}

简单工厂你只需要传递一个合法的参数,就可以获取到你想要的对象,而无需知道创建的具体的细节。每次如果需要添加一个对象,那么我们需要新增一个构造函数,使得我们难以维护。所以简单工厂模式只适用于在创建时对象数量少,以及逻辑简单的情况。

工厂方法模式

在工厂方法模式中,依赖工厂方法,我们可以通过实现工厂接口来创建多种工厂,将对象创建从由一个对象负责所有具体类的实例化,变成由一群子类来负责对具体类的实例化,从而将过程解耦。

下面我们来看一下代码实现:

package main

import "fmt"

type Person struct {
	Name string `json:"name"`
	Sex  string `json:"sex"`
}
func NewPerson(sex string) func(name string) Person {
  return func(name string) Person {
    return Person{
      name: name,
      sex: sex,
    }
  }
}

func main()  {
	newPerson1 := NewPerson("男")
	p1 := newPerson1("小明")

	newPerson2 := NewPerson("女")
	p2 := newPerson2("小李")
}

抽象工厂模式

它和简单工厂模式的唯一区别,就是它返回的是接口而不是结构体。

通过返回接口,可以在你不公开内部实现的情况下,让调用者使用你提供的各种功能,也可以强制用户在初始一个对象的时候使用我们的构造函数。

下面我们来看一下代码实现:

package main

import "fmt"
type Person interface {
  Say()
}
type Person struct {
	Name string `json:"name"`
	Sex  string `json:"sex"`
}
func (p person) Say() {
  fmt.Printf("Hi! My name is %s", p.name)
}
func NewPerson(name, sex string) Person {
  return person{
    name: name,
    sex: sex,
  }
}

小结

  1. 工厂方法名首字母大写,返回的是 结构体实例的指针(值引用,外包操作的都将会是同一份数据)
  2. 结构体内的字段名是首字母小写的话,那么包外不能直接访问,需要通过 绑定的方法来获取,绑定的是结构体指针,因为包外要操作的对象需要用的是同一份数据。