修改前
简单工厂设计
缺点
添加食物时需要修改工厂类FoodsFactory的方法GetFood
代码
package SimpleFactory
import (
"fmt"
)
type Foods interface {
Display()
}
type Hamburger struct {
price int
}
func (h Hamburger) Display() {
fmt.Println("I'm Hamburger, price is ",h.price)
}
type Porridge struct {
price int
}
func (p Porridge) Display() {
fmt.Println("I'm Porridge, price is ",p.price)
}
type FoodsFactory struct {
}
func (f FoodsFactory)GetFood(name string) Foods {
switch name {
case "hamburger":
return & Hamburger{price: 10}
case "porridge":
return &Porridge{price: 8}
default:
return nil
}
}
修改后
工厂方法设计
优点
添加食物时,添加一个类和对应的具体工厂方法即可,不需要修改源代码
代码
package FactoryMethod
import (
"fmt"
)
type Foods interface {
Display()
}
type Hamburger struct {
price int
}
func (h Hamburger) Display() {
fmt.Println("I'm Hamburger, price is ",h.price)
}
type Porridge struct {
price int
}
func (p Porridge) Display() {
fmt.Println("I'm Porridge, price is ",p.price)
}
type FoodsFactory interface {
GetFood()
}
type HamburgerFactory struct {
}
func (h HamburgerFactory)GetFood() Foods {
return & Hamburger{price: 10}
}
type PorridgeFactory struct {
}
func (p PorridgeFactory)GetFood() Foods {
return &Porridge{price: 8}
}
测试
测试代码
package FactoryMethod
import "testing"
func TestMethod(t \*testing.T) {
h := HamburgerFactory{}
ham := h.GetFood()
ham.Display()
p := PorridgeFactory{}
por := p.GetFood()
por.Display()
}
结果
=== RUN TestMethod
I’m Hamburger, price is 10
I’m Porridge, price is 8
— PASS: TestMethod (0.00s)
PASS
总结
适用场景
- 客户端不知道它所需要的对象的类。在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中。
- 抽象工厂类通过其子类来指定创建哪个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
优点
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!