工厂模式主要有三种不同的实作:
这三种实作由简单到复杂,今天会介绍最单纯的 Simple Factory Pattern
由一个工厂将制作产品的细节隐藏,让使用者不需要不需要知道细节也能获得产品
在制作一个物件的时候,物件常常还需要有其他後制的处理,这些处理使用者不需要知道,使用者只需要获得此产品即可,所以需要将後制处理作封装
要生产 PS5 主机光碟版与数位版给使用者,但使用者不需要知道「如何生产 CPU、显示晶片与加装光碟机」,使用者只需要获得此产品就行。
实作有问题的 code 如下:
(相关的 code 在Github - go-design-patterns)
package factory
import "fmt"
type PS5WithCD struct{}
func (p PS5WithCD) PlayGame() {
fmt.Println("loading cd...play!")
}
func (p PS5WithCD) AddCDMachine() {
fmt.Println("adding cd machine...done!")
}
func (p PS5WithCD) AddCPU() {
fmt.Println("adding cpu...done!")
}
func (p PS5WithCD) AddGPU() {
fmt.Println("adding gpu...done!")
}
type PS5WithDigital struct{}
func (p PS5WithDigital) PlayGame() {
fmt.Println("loading digital file...play!")
}
func (p PS5WithDigital) AddCPU() {
fmt.Println("adding cpu...done!")
}
func (p PS5WithDigital) AddGPU() {
fmt.Println("adding gpu...done!")
}
func main() {
ps5 := PS5WithCD{}
ps5.AddCDMachine()
ps5.AddCPU()
ps5.AddGPU()
// or
// ps5 := PS5WithDigital{}
// ps5.AddCPU()
// ps5.AddGPU()
ps5.PlayGame()
}
使用者有可能会购买光碟版PS5WithCD{}
或数位版PS5WithDigital{}
,并且回家玩游戏.PlayGame()
,但 PS5 得组装方式.AddCDMachine()
、.AddCPU()
、.AddGPU()
都是使用者不需要知道的。
想像一下你去买 PS5 的时候老板直接在你面前装 CPU 那画面也是够呛哈哈。
我们需要CreatePS5()
function 来将 PS5 的制作过程隐藏起来,如下:
package factory
import "fmt"
type PS5 interface {
PlayGame()
}
type PS5WithCD struct{}
func (p PS5WithCD) PlayGame() {
fmt.Println("loading cd...play!")
}
func (p PS5WithCD) AddCDMachine() {
fmt.Println("adding cd machine...done!")
}
func (p PS5WithCD) AddCPU() {
fmt.Println("adding cpu...done!")
}
func (p PS5WithCD) AddGPU() {
fmt.Println("adding gpu...done!")
}
type PS5WithDigital struct{}
func (p PS5WithDigital) PlayGame() {
fmt.Println("loading digital file...play!")
}
func (p PS5WithDigital) AddCPU() {
fmt.Println("adding cpu...done!")
}
func (p PS5WithDigital) AddGPU() {
fmt.Println("adding gpu...done!")
}
func CreatePS5(style string) PS5 {
switch style {
case "PS5WithCD":
ps5 := &PS5WithCD{}
ps5.AddCDMachine()
ps5.AddCPU()
ps5.AddGPU()
return ps5
case "PS5WithDigital":
ps5 := &PS5WithDigital{}
ps5.AddCPU()
ps5.AddGPU()
return &PS5WithDigital{}
}
return nil
}
func main() {
ps5 := CreatePS5("PS5WithCD")
ps5.PlayGame()
}
这样使用者就只需要CreatePS5()
後即可直接.PlayGame()
。CreatePS5()
有个特别的地方,
即透过 interface 来定义与外部沟通的方式
由於PS5WithCD{}
与PS5WithDigital{}
始终是不同的东西,我们须将这两个物件「相同」的行为定义出来,来跟使用者说「这个产品可以玩 PS5 的游戏」,我们称这个动作为「抽象」。
所以 PS5 interface 将.PlayGame()
这个行为抽象出来,只要能玩 PS5 游戏的产品,都称为 PS5 系列相关的产品,即 PS5 的光碟版与数位版。
最後整体 UML 如下(CreatePS5 不是 struct,所以我在上方标注这是一个 function 的区块):
PS5WithCD{}
、PS5WithDigital{}
由CreatePS5()
生产,他们依赖PS5
interface,而 user(main function)透过 interface 来操作生产出来的 PS5。
<<: [Day 22] Leetcode 437. Path Sum III (C++)
>>: 提供 REST API / 限定栏位 / 格式化LocalDate - day12
终於进入到Angular环节了, 个人学习过程中主要以保哥的Angular教学为主。 Angular...
点击进入React源码调试仓库。 概述 每个fiber节点在更新时都会经历两个阶段:beginWor...
在过去 Javascript还没发展 common.js 或是 ESM,在使用 Javascript...
任天堂在红白机之後的这台後继机种超级任天堂、以下简称 SFC、是我家当年的第三台主机、也是我曾经拥有...
1. 比较和交换(compare and swap,简称CAS)跟交换(swap)有什麽不同? 比较...