设计模式-简单工厂模式&工厂方法模式

1. 简单工厂模式定义

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过专门定义一个类来负责创建其他类的实例,这个类通常被称为工厂类。简单工厂模式并不是一种正式的设计模式,但它确实是一种常用的编程技巧。

在简单工厂模式中,工厂类包含了一个方法,这个方法根据传入的参数来决定创建哪种具体对象,并返回这个对象的实例。这样做的好处是,将对象创建的逻辑集中管理,客户端代码不需要直接实例化对象,而是通过工厂方法来获取所需的对象。

从上面的定义中可以看出,简单工厂模式包含以下三个部分:

  1. 工厂:负责实现创建所有产品的逻辑,可以说是在这个工厂里面可以实例化所有相关的类;
  2. 产品接口:这里面封装了所有产品的公共方法,这也是一类产品的特性,比如披萨制作过程都会包括:切等等。
  3. 具体产品:一般就是会实现产品接口里面所用公共方法的产品。比如奶酪披萨,素食披萨,他们的制作过程是差不多的,所以都会实现制作披萨这个公共方法。

2. 简单工厂模式UML图表示

2.1 相关代码实现

Go 复制代码
package simple_factory_pattern


// 产品接口
type Pizza interface {
    MakePizza()
}

package simple_factory_pattern

import "fmt"

// 具体产品---奶酪披萨
type CheesePizza struct{}

func NewCheesePizza() *CheesePizza {
    return &CheesePizza{}
}

func (c *CheesePizza) Prepare() {
    fmt.Println("Prepare Cheese Pizza")
}

func (c *CheesePizza) Bake() {
    fmt.Println("Bake Cheese Pizza")
}

func (c *CheesePizza) Cut() {
    fmt.Println("Cut Cheese Pizza")
}

func (c *CheesePizza) Box() {
    fmt.Println("Box Cheese Pizza")
}

func (c *CheesePizza) MakePizza() {
    c.Prepare()
    c.Bake()
    c.Cut()
    c.Box()
}



package simple_factory_pattern

import "fmt"

// 具体产品2---素食披萨
type VeggiePizza struct{}

func NewVeggiePizza() *VeggiePizza {
    return &VeggiePizza{}
}

func (v *VeggiePizza) Prepare() {
    fmt.Println("Prepare Veggie Pizza")
}

func (v *VeggiePizza) Bake() {
    fmt.Println("Bake Veggie Pizza")
}

func (v *VeggiePizza) Cut() {
    fmt.Println("Cut Veggie Pizza")
}

func (v *VeggiePizza) Box() {
    fmt.Println("Box Veggie Pizza")
}

func (v *VeggiePizza) MakePizza() {
    v.Prepare()
    v.Bake()
    v.Cut()
    v.Box()
}

package simple_factory_pattern

// 披萨工厂,专门用来实例化pizza对象
type PizzaFactory struct{}

// CreatePizza creates a pizza based on the pizzaType
func (p *PizzaFactory) CreatePizza(pizzaType string) Pizza {
    switch pizzaType {
    case "cheese":
       return NewCheesePizza()
    case "veggie":
       return NewVeggiePizza()
    default:
       return nil
    }
}

2.2 优缺点

简单工厂模式的优点包括:

  • 客户端代码与具体类的实现解耦,便于后期的扩展和维护。

  • 中央化了对象创建的逻辑,使代码更易读、更易管理。

缺点包括:

  • 工厂类集中了所有实例创建的逻辑,可能会导致该类变得过于复杂

  • 增加新的产品类型时 需要修改工厂类的代码,违背了开闭原则(对扩展开放,对修改关闭)。

3. 工厂方法模式

为了不违背开闭原则,因此有了工厂方法模式。在每次新增产品类型的时候,把对工厂类的修改放到了客户端进行判断,不需要再改变工厂类,从而不会违背开闭原则。

工厂方法模式是一种创建型模式,它通过定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法模式让一个类的实例化延迟到其子类。在工厂方法模式中,每个具体产品都有一个对应的具体工厂来创建。下面是将简单工厂模式改写成工厂方法模式的实现:

  1. 首先定义一个 Pizza 接口及其实现类。

  2. 然后为每个具体的 Pizza 类定义一个具体的工厂类,这些工厂类实现一个共同的 PizzaFactory 接口。

3.1 UML图表示

3.2 相关代码实现

Go 复制代码
// 产品接口
package factory_method_pattern

// 产品接口type Pizza interface {
    MakePizza()
}


// 具体产品实现--奶酪披萨

package factory_method_pattern

import "fmt"
// 具体产品---奶酪披萨type CheesePizza struct{}

func NewCheesePizza() *CheesePizza {
    return &CheesePizza{}
}

func (c *CheesePizza) Prepare() {
    fmt.Println("Prepare Cheese Pizza")
}

func (c *CheesePizza) Bake() {
    fmt.Println("Bake Cheese Pizza")
}

func (c *CheesePizza) Cut() {
    fmt.Println("Cut Cheese Pizza")
}

func (c *CheesePizza) Box() {
    fmt.Println("Box Cheese Pizza")
}

func (c *CheesePizza) MakePizza() {
    c.Prepare()
    c.Bake()
    c.Cut()
    c.Box()
}


// 具体产品实现2---素食披萨
go复制代码
package factory_method_pattern

import "fmt"
// 具体产品---素食披萨type VeggiePizza struct{}

func NewVeggiePizza() *VeggiePizza {
    return &VeggiePizza{}
}

func (v *VeggiePizza) Prepare() {
    fmt.Println("Prepare Veggie Pizza")
}

func (v *VeggiePizza) Bake() {
    fmt.Println("Bake Veggie Pizza")
}

func (v *VeggiePizza) Cut() {
    fmt.Println("Cut Veggie Pizza")
}

func (v *VeggiePizza) Box() {
    fmt.Println("Box Veggie Pizza")
}

func (v *VeggiePizza) MakePizza() {
    v.Prepare()
    v.Bake()
    v.Cut()
    v.Box()
}



// 工厂接口
package factory_method_pattern

// 工厂接口
type PizzaFactory interface {
    CreatePizza() Pizza
}

// 奶酪披萨工厂
package factory_method_pattern

// 奶酪披萨工厂
type CheesePizzaFactory struct{}

func NewCheesePizzaFactory() *CheesePizzaFactory {
    return &CheesePizzaFactory{}
}

func (c *CheesePizzaFactory) CreatePizza() Pizza {
    return NewCheesePizza()
}

// 素食披萨工厂
package factory_method_pattern

// 素食披萨工厂type VeggiePizzaFactory struct{}

func NewVeggiePizzaFactory() *VeggiePizzaFactory {
    return &VeggiePizzaFactory{}
}

func (v *VeggiePizzaFactory) CreatePizza() Pizza {
    return NewVeggiePizza()
}


// 使用实例
package main

import (
    "fmt"    
    "factory_method_pattern"
)

func main() {
    var factory factory_method_pattern.PizzaFactory

    // 使用 CheesePizzaFactory 创建 CheesePizza    
    factory = factory_method_pattern.NewCheesePizzaFactory()
    cheesePizza := factory.CreatePizza()
    cheesePizza.MakePizza()

    // 使用 VeggiePizzaFactory 创建 VeggiePizza    
    factory = factory_method_pattern.NewVeggiePizzaFactory()
    veggiePizza := factory.CreatePizza()
    veggiePizza.MakePizza()
}

在这个实现中,每个具体的披萨工厂都实现了 PizzaFactory 接口,并提供了自己的 CreatePizza 方法。这样,客户端代码可以根据需要选择不同的工厂来创建不同的披萨对象,而不需要直接依赖具体的披萨类。这种设计使得系统更灵活,更容易扩展。不会违背开闭原则

相关推荐
Theodore_10226 小时前
7 设计模式原则之合成复用原则
java·开发语言·jvm·设计模式·java-ee·合成复用原则
武子康6 小时前
Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片段
java·sql·设计模式·架构·mybatis·代理模式
博风9 小时前
设计模式:4、命令模式(双重委托)
设计模式·命令模式
捕鲸叉9 小时前
C++适配器模式之可插入适配器的实现模式和方法
开发语言·c++·设计模式
捕鲸叉9 小时前
C++结构型设计模式之适配器模式概述
c++·设计模式·适配器模式
RT_01149 小时前
设计模式之策略模式
java·设计模式·策略模式
lexusv8ls600h13 小时前
微服务设计模式 - 物化视图模式(Materialized View Pattern)
微服务·设计模式·云原生·架构
萨达大13 小时前
23种设计模式-备忘录(Memento)设计模式
java·c++·设计模式·软考·备忘录模式·软件设计师·行为型设计模式
冰零(lane)14 小时前
状态模式之状态机
java·设计模式·状态模式
萨达大16 小时前
23种设计模式-访问者(Visitor)设计模式
java·c++·设计模式·软考·访问者模式·软件设计师·行为型设计模式