1 概述
工廠方法類定義產品對象創建接口,但由子類實現具體產品對象的創建。
2.1 角色
- Product(抽象產品):它是具體產品的抽象類,可以是結構體,也可以是接口
- ConcreteProduct(具體產品):它實現了抽象產品接口,對應了一種具體產品
- Factroy(抽象工廠):在抽象工廠類中聲明了工廠方法,用于返回一個產品。
- ConcreteFactory(具體工廠):實現了在抽象工廠中聲明的工廠方法,并可由客戶端調用,返回一個具體產品類的實例。
2.2 類圖
image.png
classDiagram
class Product{
<<interface>>
+Get()
}
class ConcreteProductA{
+Get()
}
class ConcreteProductB{
+Get()
}
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
class Factroy{
<<interface>>
+CreateProduct()
}
class ConcreteFactroyA{
+CreateProduct() Product
}
class ConcreteFactroyB{
+CreateProduct() Product
}
ConcreteFactroyA ..|> Factroy
ConcreteFactroyB ..|> Factroy
ConcreteProductA <.. ConcreteFactroyA
ConcreteProductB <.. ConcreteFactroyB
class Client {
}
Product <-- Client
Client --> Factroy
2 代碼示例
2. 1 設計
2.2 代碼
package main
import (
"fmt"
)
type Product interface {
Get()
}
type ConcreteProductA struct {
Name string
Kind string
}
func (c *ConcreteProductA) Get() {
fmt.Printf("%+v",c)
}
type ConcreteProductB struct {
Name string
Kind string
}
func (c *ConcreteProductB) Get() {
fmt.Printf("%+v",c)
}
type ConcreteProductC struct {
Name string
Kind string
}
func (c *ConcreteProductC) Get() {
fmt.Printf("%+v",c)
}
type Factroy interface {
CreateProduct(name string) Product
}
type ConcreteFactoryA struct {
}
func (f *ConcreteFactoryA) CreateProduct(name string) Product {
p := &ConcreteProductA{
Name: name,
Kind:"A",
}
return p
}
type ConcreteFactoryB struct {
}
func (f *ConcreteFactoryB) CreateProduct(name string) Product {
p := &ConcreteProductB{
Name: name,
Kind: "B",
}
return p
}
type ConcreteFactoryC struct {
}
func (f *ConcreteFactoryC) CreateProduct(name string) Product {
p := &ConcreteProductC{
Name: name,
Kind: "C",
}
return p
}
func CreateProduct(myType int64) Factroy {
switch myType {
case 1:
return &ConcreteFactoryA{}
case 2:
return &ConcreteFactoryB{}
case 3:
return &ConcreteFactoryC{}
}
return nil
}
func main() {
factory := CreateProduct(1)
product := factory.CreateProduct("nginx")
product.Get()
}
- 輸出
&{Name:nginx Kind:A}
2.3 類圖
image.png
classDiagram
class Product{
<<interface>>
+Get()
}
class ConcreteProductA{
+Name:string
+Kind:string
+Get()
}
class ConcreteProductB{
+Name:string
+Kind:string
+Get()
}
class ConcreteProductC{
+Name:string
+Kind:string
+Get()
}
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
Product <|.. ConcreteProductC
class Factroy{
<<interface>>
+CreateProduct()
}
class ConcreteFactroyA{
+CreateProduct() Product
}
class ConcreteFactroyB{
+CreateProduct() Product
}
class ConcreteFactroyC{
+CreateProduct() Product
}
ConcreteFactroyA ..|> Factroy
ConcreteFactroyB ..|> Factroy
ConcreteFactroyC ..|> Factroy
ConcreteProductA <.. ConcreteFactroyA
ConcreteProductB <.. ConcreteFactroyB
ConcreteProductC <.. ConcreteFactroyC
3. 簡單工廠
在產品結構簡單的情況下,我們可以把工廠模式簡化成一個簡單工廠
3.1 角色
- Product(抽象產品):它是具體產品的抽象類,可以是結構體,也可以是接口
- ConcreteProduct(具體產品):它實現了抽象產品接口,對應了一種具體產品
- Factroy(簡單工廠):根據一個條件用于返回一個產品
去掉了具體工廠角色,產品由簡單工廠直接返回。
3.2 類圖
image.png
classDiagram
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
class ConcreteProductA{
+Create()
}
class ConcreteProductB{
+Create()
}
class Product{
<<interface>>
+Create()
}
Factroy --> Product
class Factroy{
+CreateProduct() Product
}
3.3 代碼示例
3.3.1 設計
- 定義一個抽象產品
Product
- 定義三個具體產品
ConcreteProductA
、ConcreteProductB
、ConcreteProductC
- 它們各自的
Get()
方法會訪問它本身
- 它們各自的
- 定義一個簡單工廠
- 簡單工廠的CreateProduct()方法會返回一個產品
- 調用
- 實例化一個簡單工廠
- 用簡單工廠創建一個產品
- 用產品的Get()方法查詢結果
3.3.2 代碼
package main
import (
"fmt"
)
type Product interface {
Get()
}
type ConcreteProductA struct {
Name string
Kind string
}
func (c *ConcreteProductA) Get() {
fmt.Printf("%+v", c)
}
type ConcreteProductB struct {
Name string
Kind string
}
func (c *ConcreteProductB) Get() {
fmt.Printf("%+v", c)
}
type ConcreteProductC struct {
Name string
Kind string
}
func (c *ConcreteProductC) Get() {
fmt.Printf("%+v", c)
}
type Factroy struct {
}
func (f *Factroy) CreateProduct(myType int64, name string) Product {
switch myType {
case 1:
return &ConcreteProductA{
Name: name,
Kind: "A",
}
case 2:
return &ConcreteProductB{
Name: name,
Kind: "B",
}
case 3:
return &ConcreteProductC{
Name: name,
Kind: "C",
}
}
return nil
}
func main() {
factory := &Factroy{}
product := factory.CreateProduct(1, "nginx")
product.Get()
}
- 輸出
&{Name:nginx Kind:A}
3.3.3 類圖
image.png
classDiagram
Product <|.. ConcreteProductA
Product <|.. ConcreteProductB
Product <|.. ConcreteProductC
class ConcreteProductA{
+Name
+Kind
+Cet()
}
class ConcreteProductB{
+Name
+Kind
+Get()
}
class ConcreteProductC{
+Name
+Kind
+Get()
}
class Product{
<<interface>>
+Get()
}
Factroy --> Product
class Factroy{
+CreateProduct() Product
}