工廠方法模式
定義一個用於建立對象的接口,讓子類決定將哪個類實例化。再也不提供一個統一的工廠類來建立全部的產品對象,而是針對不一樣的產品提供不一樣的工廠,系統提供一個與產品等級結構對應的工廠等級結構。
工廠方法模式四要素:數據庫
快餐店的食物,目前有漢堡,粥,須要向顧客展現價格。編程
修改前
缺點
添加食物時須要修改工廠類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
在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其餘的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就能夠了,這樣,系統的可擴展性也就變得很是好,徹底符合「開閉原則」。接口