[go] 工厂方法模式

简介: [go] 工厂方法模式

工厂方法模式


工厂方法模式是一种创建型设计模式,定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。让类把实例化推迟到子类。


模型说明


  • Product:
  • 将会对接口进行声明。对于所有由创建者及其子类构件的对象,这些接口都是通用的。
  • ConcreteProductA,ConcreteProductB:
  • 具体产品是产品接口的不同实现。
  • Creator:
  • 声明返回产品对象的工厂方法。该方法的返回类型必须与产品接口相匹配。
  • 可以将工厂方法声明为抽象方法,强制要求每个子类以不同方式实现该方法。或者可以在基础工厂方法中返回默认产品类型。
  • ConcreteCreatorA,ConcreteCreatorB:将会重写基础工厂方法,使其返回不同类型的产品。


优缺点


1.优点

  • 你可以避免创建者和具体产品之间的紧密耦合。
  • 单一职责原则:你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
  • 开闭原则:无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。


2.缺点

  • 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。


使用场景


  • 当你在编写代码的过程中, 如果无法预知对象确切类别及其依赖关系时, 可使用工厂方法。
  • 如果你希望用户能扩展你软件库或框架的内部组件, 可使用工厂方法。
  • 如果你希望复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法。


参考代码


假设我们需要生产不同的手机


// 产品接口
type IPhone interface {
  setName(name string)
  setPrice(price float64)
  getName() string
  getPrice() float64
}
// 具体产品
type Phone struct {
  name  string
  price float64
}
func (g *Phone) setName(name string) {
  g.name = name
}
func (g *Phone) getName() string {
  return g.name
}
func (g *Phone) setPrice(price float64) {
  g.price = price
}
func (g *Phone) getPrice() float64 {
  return g.price
}
type Xiaomi struct {
  Phone
}
func NewXiaomi() IPhone {
  return &Phone{
    name:  "xiaomi",
    price: 1999,
  }
}
type Huawei struct {
  Phone
}
func NewHuawei() IPhone {
  return &Phone{
    name:  "huawei",
    price: 4999,
  }
}
// 工厂方法
func getPhone(phoneType string) (IPhone, error) {
  if phoneType == "xiaomi" {
    return NewXiaomi(), nil
  }
  if phoneType == "huawei" {
    return NewHuawei(), nil
  }
  return nil, fmt.Errorf("wrong phone type passed")
}
// 客户端执行
func main() {
  xiaomi, err := getPhone("xiaomi")
  if err != nil {
    panic(err)
  }
  huawei, err := getPhone("huawei")
  if err != nil {
    panic(err)
  }
  printDetails(xiaomi)
  printDetails(huawei)
}
func printDetails(p IPhone) {
  fmt.Printf("Phone: %s", p.getName())
  fmt.Println()
  fmt.Printf("Price: %.2f", p.getPrice())
  fmt.Println()
  fmt.Println("---------------------------")
}

输出:

Phone: xiaomi 
Price: 1999.00 
--------------------------- 
Phone: huawei 
Price: 4999.00 
---------------------------
相关文章
|
存储 Go
Go 语言开源项目使用的函数选项模式
Go 语言开源项目使用的函数选项模式
61 0
|
6月前
|
物联网 Go 网络性能优化
使用Go语言(Golang)可以实现MQTT协议的点对点(P2P)消息发送。MQTT协议本身支持多种消息收发模式
使用Go语言(Golang)可以实现MQTT协议的点对点(P2P)消息发送。MQTT协议本身支持多种消息收发模式【1月更文挑战第21天】【1月更文挑战第104篇】
474 1
|
3月前
|
缓存 NoSQL Go
通过 SingleFlight 模式学习 Go 并发编程
通过 SingleFlight 模式学习 Go 并发编程
|
14天前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
14天前
|
安全 Go 开发者
破译Go语言中的并发模式:从入门到精通
在这篇技术性文章中,我们将跳过常规的摘要模式,直接带你进入Go语言的并发世界。你将不会看到枯燥的介绍,而是一段代码的旅程,从Go的并发基础构建块(goroutine和channel)开始,到高级模式的实践应用,我们共同探索如何高效地使用Go来处理并发任务。准备好,让Go带你飞。
|
3月前
|
存储 Unix 测试技术
解释Go中常见的I/O模式
解释Go中常见的I/O模式
|
4月前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
69 8
|
3月前
|
缓存 算法 Go
|
3月前
|
存储 Unix 测试技术
解释Go中常见的I/O模式
解释Go中常见的I/O模式