最后更新于2022年6月8日 14:31:48
按照《研磨设计模式》这本书上面的生产电脑的例子,1156针脚的CPU与主板组合;939的互相组合,不能跨针脚组合。
CPU和主板的接口与实现类
这个没什么区别,两种工厂都一样的:
CPU:
type CPUApi interface {
Calc()
}
/**
* IntelCPU
* @Description:
*/
type IntelCPU struct {
pins int
}
func NewIntelCPU(pins int) *IntelCPU {
return &IntelCPU{pins: pins}
}
func (i IntelCPU) Calc() {
fmt.Println("Intel CPU, pins=", i.pins)
}
/**
* AMDCPU
* @Description:
*/
type AMDCPU struct {
pins int
}
func NewAMDCPU(pins int) *AMDCPU {
return &AMDCPU{pins: pins}
}
func (a AMDCPU) Calc() {
fmt.Println("AMDYES!!!, pins=", a.pins)
}
主板:
type MainboardApi interface {
InsCPU()
}
/**
* GAMainboard
* @Description:
*/
type GAMainboard struct {
cpuHoles int
}
func NewGAMainboard(cpuHoles int) *GAMainboard {
return &GAMainboard{cpuHoles: cpuHoles}
}
func (G *GAMainboard) InsCPU() {
fmt.Println("Now in GAMainboard, cpuHoles= ", G.cpuHoles)
}
/**
* MSIMainboard
* @Description:
*/
type MSIMainboard struct {
cpuHoles int
}
func NewMSIMainboard(cpuHoles int) *MSIMainboard {
return &MSIMainboard{cpuHoles: cpuHoles}
}
func (G *MSIMainboard) InsCPU() {
fmt.Println("Now in MSIMainboard, cpuHoles= ", G.cpuHoles)
}
工厂方法
重点是工厂方法的实现,先把自己的观点放在前面:抽象工厂生产的是方案,简单工厂生产的是零件
简单工厂:
package simple_fac
/**
* createCPUApi
* @Description:
* @param t
* @return CPUApi
*/
func CreateCPUApi(t int) CPUApi {
var cpu CPUApi
if t == 1 {
cpu = NewIntelCPU(1156)
} else if t == 2 {
cpu = NewAMDCPU(939)
}
return cpu;
}
/**
* createMainboardApi
* @Description:
* @param t type of CPU
* @return MainboardApi
*/
func CreateMainboardApi(t int) MainboardApi {
var mainboard MainboardApi
if t == 1 {
mainboard = NewGAMainboard(1156)
} else if t == 2 {
mainboard = NewMSIMainboard(939)
}
return mainboard
}
可以看到工厂创建出来的是具体的主板和CPU这两个器件儿;
对应的简单工厂的组装工程师:
package simple_fac
type ComputerEngineer struct {
cpu CPUApi
mainboard MainboardApi
}
func NewComputerEngineer() *ComputerEngineer {
return &ComputerEngineer{}
}
func (ce *ComputerEngineer) MakeComputer(cpu int, mainboard int) {
//1、准备好装机的配件
ce.prepareHWs(cpu, mainboard)
//2、组装机器
//3、测试机器
//4、交付客户
}
func (ce *ComputerEngineer) prepareHWs(cpu int, mainboard int) {
ce.cpu = CreateCPUApi(cpu)
ce.mainboard = CreateMainboardApi(mainboard)
ce.cpu.Calc()
ce.mainboard.InsCPU()
}
组装的函数是MakeComputer(),
主函数如下:
package main
import "newPlayground0526/internal/simple_fac"
/**
* main
* @Description: 简单工厂
*/
func main() {
engineer := simple_fac.NewComputerEngineer()
engineer.MakeComputer(2, 2)
}
engineer.MakeComputer(1, 2)
抽象工厂
package ab_fac
type AbstractFactory interface {
createCPUApi() CPUApi
createMainboardApi() MainboardApi
}
// Schema1
type Schema1 struct {}
func (s *Schema1) createCPUApi() CPUApi {
return NewIntelCPU(1156)
}
func (s *Schema1) createMainboardApi() MainboardApi {
return NewGAMainboard(1156)
}
// Schema2
type Schema2 struct {}
func (s *Schema2) createCPUApi() CPUApi {
return NewIntelCPU(939)
}
func (s *Schema2) createMainboardApi() MainboardApi {
return NewGAMainboard(939)
}
跟简单工厂比起来,抽象工程生产的不是器件,而是Schema1和Schema2两个方案,相当于给器件之间添加了逻辑关系,就不会出现错误匹配的情况了。
相应的装机工程师的类是:
package ab_fac
type ComputerEngineer struct {
cpu CPUApi
mainboard MainboardApi
}
func NewComputerEngineer() *ComputerEngineer {
return &ComputerEngineer{}
}
func (ce *ComputerEngineer) MakeComputer(schema AbstractFactory) {
//1、准备好装机的配件
ce.prepareHWs(schema)
//2、组装机器
//3、测试机器
//4、交付客户
}
func (ce *ComputerEngineer) prepareHWs(schema AbstractFactory) {
ce.cpu = schema.createCPUApi()
ce.mainboard = schema.createMainboardApi()
ce.cpu.Calc()
ce.mainboard.InsCPU()
}
以下是主函数,看的更明显:
package main
import (
"newPlayground0526/internal/ab_fac"
)
/**
* main
* @Description: 简单工厂
*/
func main() {
engineer := ab_fac.NewComputerEngineer()
schema := new(ab_fac.Schema1)
engineer.MakeComputer(schema)
}
可见只要给装机工程师提供方案即可,避免了器件错位的情况。
吐槽
《研磨设计模式》里面有句话说的挺对的:工厂方法模式或简单工厂模式关注的是单个产品对象的创建,人家针对的问题就不是这种需要进行逻辑匹配的情况。