設計模式-工廠方法模式(Go實現)

 

目錄

  • 工廠方法模式
  • 需求
  • 修改前
    • 簡單工廠設計
    • 代碼
  • 修改後
    • 工廠方法設計
    • 代碼
  • 測試
    • 測試代碼
    • 結果
  • 總結
    • 適用場景
    • 優勢
    • 缺點
  • 參考

 

工廠方法模式

定義一個用於建立對象的接口,讓子類決定將哪個類實例化。再也不提供一個統一的工廠類來建立全部的產品對象,而是針對不一樣的產品提供不一樣的工廠,系統提供一個與產品等級結構對應的工廠等級結構。
工廠方法模式四要素:數據庫

  • 工廠接口。工廠接口是工廠方法模式的核心,與調用者直接交互用來提供產品。在實際編程中,有時候也會使用一個抽象類來做爲與調用者交互的接口,其本質上是同樣的。
  • 工廠實現。在編程中,工廠實現決定如何實例化產品,是實現擴展的途徑,須要有多少種產品,就須要有多少個具體的工廠實現。
  • 產品接口。產品接口的主要目的是定義產品的規範,全部的產品實現都必須遵循產品接口定義的規範。產品接口是調用者最爲關心的,產品接口定義的優劣直接決定了調用者代碼的穩定性。一樣,產品接口也能夠用抽象類來代替,但要注意最好不要違反里氏替換原則。
  • 產品實現。實現產品接口的具體類,決定了產品在客戶端中的具體行爲。
需求

快餐店的食物,目前有漢堡,粥,須要向顧客展現價格。編程

修改前

簡單工廠設計

在這裏插入圖片描述
缺點
添加食物時須要修改工廠類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

  • 在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其餘的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就能夠了,這樣,系統的可擴展性也就變得很是好,徹底符合「開閉原則」。接口

缺點

  • 在添加新產品時,須要編寫新的具體產品類,並且還要提供與之對應的具體工廠類,系統中類的個數將成對增長,在必定程度上增長了系統的複雜度,有更多的類須要編譯和運行,會給系統帶來一些額外的開銷。
  • 因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度,且在實現時可能須要用到反射等技術,增長了系統的實現難度。
相關文章
相關標籤/搜索