工厂模式主要有三种不同的实作:
这三种实作由简单到复杂,今天会介绍 Simple Factory Pattern 延伸的 Factory Method Pattern
将复杂的生产逻辑再拆分至特定工厂,由使用者端决定要使用什麽工厂来生产产品
以昨天的例子简单得来说,就是「将 if else/swtich 的逻辑拆分至不同工厂」,即:
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
}
拆分至PS5WithCDFactory{}
、PS5WithDigital{}
,「单一产品由单一工厂生产」,这样做有什麽优缺点呢?
优点:
缺点:
延续昨天的情境,要生产 PS5 主机光碟版与数位版给使用者,但使用者不需要知道「如何生产 CPU、显示晶片与加装光碟机」,使用者只需要获得此产品就行。
程序码如下:
(相关的 code 在Github - go-design-patterns)
package main
import "fmt"
type GameMachineFactory interface {
Create() GameMachine
}
type PS5WithCDFactory struct{}
func (f *PS5WithCDFactory) Create() GameMachine {
ps5 := &PS5WithCD{}
ps5.AddCDMachine()
ps5.AddCPU()
ps5.AddGPU()
return &PS5WithCD{}
}
type PS5WithDigitalFactory struct{}
func (f *PS5WithDigitalFactory) Create() GameMachine {
ps5 := &PS5WithDigital{}
ps5.AddCPU()
ps5.AddGPU()
return &PS5WithDigital{}
}
type GameMachine 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 User(gameMachineFactory GameMachineFactory) {
gameMachine := gameMachineFactory.Create()
gameMachine.PlayGame()
}
func main() {
User(&PS5WithCDFactory{})
}
UML 图如下:
可以与昨天 UML 图比较,关键差异在於「把工厂也建立了 inferface」,使用者就可以使用GameMachineFactory
interface 来去选择哪间工厂,而选好了工厂後,工厂依照 interface 把Create()
提供给使用者操作,创建出游戏机,之後就与 Simple Factory Pattern 是一样使用者依照GameMachine
interface 来游玩游戏。
图片来源 延续上一篇所谈的气候变迁与净零碳排, 在大势所趋之下, 近年无论是在投资与企业经营上的一...
API 今天来厘清 @material-ui/core/styles 的 API。 createGe...
前言 写一个 OS 是多麽美好的事,在有限的生命中千万不要遗漏了它。 -- 王佑中博士 笔者在开始撰...
各位先备好 如果有一个excel里面资料大概有50列,而每一行都是记载着不同的资讯,譬如:姓名/电话...
D21. 题目练习uva350 #include <stdio.h> #include ...