GO设计模式 —— 工厂方法模式

75 阅读3分钟

一、工厂模式概述

工厂模式是一种创建型设计模式,它定义了一个创建对象的接口,但将实际的对象创建工作推迟到子类中进行。这使得在不直接调用构造函数的情况下创建对象成为可能,从而提高了系统的灵活性和可扩展性。
说白了,就是你要去买水果,不用去果园里摘,而是直接去水果店直接拿就可以。

二、Go语言实现

1、工厂方法模式的实现步骤

  1. 定义产品接口
  2. 实现接口(具体产品)
  3. 定义产品工厂接口
  4. 实现产品工厂接口(具体产品的具体工厂) 下面我们就用一个例子来实现这个步骤:
    步骤一: 定义产品接口
// 定义一个动物接口,有叫的行为和吃的行为
type Animal interface {
    Speak() string
    Eat() string
}

步骤二: 实现接口(具体的产品)

// 定义两个具体的动物实现这个接口
// 狗的实现
type Dog struct {
    Name string
}

func (dog Dog) Speak() string {
    return dog.Name + "发出了汪汪的叫声"
}
func (dog Dog) Eat() string {
    return dog.Name + "正在吃狗粮"
}

// 猫的实现
type Cat struct {
    Name string
}

func (cat Cat) Speak() string {
    return cat.Name + "发出了喵喵的叫声"
}
func (cat Cat) Eat() string {
    return cat.Name + "正在吃猫粮"
}

步骤三: 定义产品工厂接口

// 获取动物的工厂接口
type AnimalFactory interface {
    CreateAnimal() Animal
}

步骤四: 实现产品工厂接口(具体产品的具体工厂)

// 对每一类动物定义工厂实现类
type DogFactory struct{}
type CatFactory struct{}

func (df DogFactory) CreateAnimal() Animal {
    return Dog{Name: "来福"}
}
func (cf CatFactory) CreateAnimal() Animal {
    return Cat{Name: "花花"}
}

然后在main函数中使用:

func main() {
    dogFactory := DogFactory{}
    catFactory := CatFactory{}
    dog := dogFactory.CreateAnimal()
    cat := catFactory.CreateAnimal()
    fmt.Println(dog.Speak())
    fmt.Println(dog.Eat())
    fmt.Println(cat.Speak())
    fmt.Println(cat.Eat())

}

三、练手题目

这里我使用的题目都来自于代码随想录的卡码网,大家也可以自己去上面练习。

1、题目简介

【设计模式专题之工厂方法模式】2.积木工厂

时间限制:1.000S  空间限制:256MB

题目描述

小明家有两个工厂,一个用于生产圆形积木,一个用于生产方形积木,请你帮他设计一个积木工厂系统,记录积木生产的信息。

输入描述

输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示生产的次数。 

接下来的 N 行,每行输入一个字符串和一个整数,字符串表示积木的类型。积木类型分为 "Circle" 和 "Square" 两种。整数表示该积木生产的数量

输出描述

对于每个积木,输出一行字符串表示该积木的信息。

输入示例
3
Circle 1
Square 2
Circle 1
输出示例
Circle Block
Square Block
Square Block
Circle Block
提示信息

在示例中,积木工厂生产了3块积木,其中有2块是圆形积木,1块是方形积木。根据输入的类型,每块积木的信息被输出到控制台。

2、具体实现

package main

import (
    "fmt"
)

// 定义一个积木接口
type Block interface {
    //具有生产的行为
    Produce() string
}
//圆形积木实现
type Circle struct{}

func (c Circle) Produce() string {
    return "Circle Block"
}
//方形积木实现
type Square struct{}

func (s Square) Produce() string {
    return "Square Block"
}
//积木工厂接口
type BlockFactory interface {
    CreateBlock() Block
}

type CircleFactory struct{}
type SquareFactory struct{}
//圆形积木工厂实现
func (c *CircleFactory) CreateBlock() Block {
    return &Circle{}
}
//方形积木工厂实现
func (s *SquareFactory) CreateBlock() Block {
    return &Square{}
}

func main() {
    circleFactory := CircleFactory{}
    squareFactory := SquareFactory{}
    arr := []string{}
    var count int
    fmt.Scanln(&count)

    for count > 0 {
       var text string
       var numb int
       fmt.Scanf("%s %d\n", &text, &numb)

       if text == "done" {
          break
       }
       switch text {
       case "Circle":
          for i := 0; i < numb; i++ {
             res := circleFactory.CreateBlock().Produce()
             arr = append(arr, res)
          }
          break
       case "Square":
          for i := 0; i < numb; i++ {
             res := squareFactory.CreateBlock().Produce()
             arr = append(arr, res)
          }
          break
       default:
          break

       }
       count--
    }
    for _, item := range arr {
       fmt.Println(item)
    }
}