【设计模式】简单工厂模式(Simple Factory Pattern)Go 实例

概述

简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同的实例,被创建的实例通常都具有共同的父类。

简单工厂模式属于创建型模式,但不属于 GOF 23 种设计模式。

优缺点及适用环境

优点:

  • 实现了创建对象和使用对象的分离;
  • 无需知道具体产品的类名;
  • 通过引入配置文件,无需修改代码即可更换和增加新的具体产品类,提高系统的灵活性。

缺点:

  • 职责过重,一旦程序出错,整个系统都不能运行;
  • 引入新的工厂,会导致增加了系统的复杂性和理解难度;
  • 违反了开闭原则,一旦新增产品必须修改原有代码;
  • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

适用环境

  • 创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂;
  • 客户端只需要传入工厂方法参数,无需知道对象如何创建;

实现

角色

工厂方法模式由具体工厂、抽象产品和具体产品等 3 个要素构成。

  • 具体工厂(Concrete Factory):它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法 factoryMethod,它的返回类型为抽象产品类型 AbstractProduct。
  • 抽象产品(Abstract Product):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
  • 具体产品(Concrete Product):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

UML 类图如下:
简单工厂模式

也就是定义一个抽象工厂,其定义了产品的上层接口,但不负责具体的产品,将生成任务交给不同的派生类工厂。这样就不用通过指定类型来创建对象了。

下面我们来讲解该模式:

抽象产品

package simple_factory

// 实现一个抽象的产品
// 声明 AbstractProduct 接口
// 包含 setName 和 getName 方法
type AbstractProduct interface {
	SetName(name string)
	GetName() string
}

具体产品 1

package simple_factory

// 实现一个具体的产品:ConcreteProduct1 的产品
type ConcreteProduct1 struct {
	name string
}

// ConcreteProduct1 的方法 setName
func (b *ConcreteProduct1) SetName(name string) {
	b.name = name
}

// ConcreteProduct1 的方法 getName
func (b *ConcreteProduct1) GetName() string {
	return "产品 1 的名称是:" + b.name
}

具体产品 2

package simple_factory

// 实现一个具体的产品:ConcreteProduct2 的产品
type ConcreteProduct2 struct {
	name string
}

// ConcreteProduct2 的方法 setName
func (b *ConcreteProduct2) SetName(name string) {
	b.name = name
}

// ConcreteProduct2 的方法 getName
func (b *ConcreteProduct2) GetName() string {
	return "产品 2 的名称是:" + b.name
}

工厂

package simple_factory

type productType string

const (
	product1 productType = "product1"
	product2 productType = "product2"
)

type Factory struct {
}

// 产品生产工厂
// 具体产品类 ConcreteProduct1 和 ConcreteProduct2 都实现了抽象产品类 AbstractProduct 的接口
// 工厂类实现的两种方法:使用 switch 判断来创建对象
func (c Factory) Create(productType string) AbstractProduct {
	switch productType {
	case "product1":
		// 生产产品 1
		return &ConcreteProduct1{}
	case "product2":
		// 生产产品 2
		return &ConcreteProduct2{}
	default:
		return nil
	}
}

测试

package simple_factory

import (
	"fmt"
	"testing"
)

func TestCar_Create(t *testing.T) {
	// 实例化
	byd := &ConcreteProduct1{}
	byd.SetName("产品1")
	fmt.Println(byd.GetName())

	// 实例化
	bmw := &ConcreteProduct2{}
	bmw.SetName("产品2")
	fmt.Println(bmw.GetName())
}

func TestCarFactory_Create(t *testing.T) {
	// 实例化
	carFactory := Factory{}

	byd := carFactory.Create(string(product1))
	byd.SetName("产品1")
	fmt.Println(byd.GetName())

	bmw := carFactory.Create(string(product2))
	bmw.SetName("产品2")
	fmt.Println(bmw.GetName())
}

测试结果

=== RUN   TestCar_Create
产品 1 的名称是:产品1
产品 2 的名称是:产品2
--- PASS: TestCar_Create (0.00s)
=== RUN   TestCarFactory_Create
产品 1 的名称是:产品1
产品 2 的名称是:产品2
--- PASS: TestCarFactory_Create (0.00s)
PASS

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_32828933/article/details/106116106
今日推荐