工厂方法模式
定义一个用于建立对象的接口,让子类决定将哪个类实例化。再也不提供一个统一的工厂类来建立全部的产品对象,而是针对不一样的产品提供不一样的工厂,系统提供一个与产品等级结构对应的工厂等级结构。
工厂方法模式四要素:数据库
快餐店的食物,目前有汉堡,粥,须要向顾客展现价格。编程
修改前
缺点
添加食物时须要修改工厂类FoodsFactory的方法GetFoodide
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设计
无须知道具体产品类的类名。工厂方法用来建立客户所须要的产品,同时还向客户隐藏了哪一种具体产品类将被实例化这一细节,用户只须要关心所需产品对应的工厂,无须关心建立细节。对象
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它可以让工厂能够自主肯定建立何种产品对象,而如何建立这个对象的细节则彻底封装在具体工厂内部。工厂方法模式之因此又被称为多态工厂模式,就正是由于全部的具体工厂类都具备同一抽象父类。blog
在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其余的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就能够了,这样,系统的可扩展性也就变得很是好,彻底符合“开闭原则”。接口