Skip to content

工厂模式(Factory Pattern)是一种创建型设计模式,旨在通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂模式将对象的创建过程抽象化,客户端不需要了解具体的创建细节,而只需依赖于工厂接口进行对象的创建。

工厂模式的类型

  1. 简单工厂模式(Simple Factory Pattern)
  2. 工厂方法模式(Factory Method Pattern)
  3. 抽象工厂模式(Abstract Factory Pattern)

这里我将详细介绍 简单工厂模式工厂方法模式 的实现,并举例说明它们在 Go 中的应用。


1. 简单工厂模式

简单工厂模式是最基础的一种工厂模式,它通过一个工厂类来实例化不同的产品对象。这个工厂类根据输入的参数返回不同类型的对象。

示例:简单工厂模式

假设我们要构建一个简单的图形绘制程序,需要支持不同类型的图形(例如:圆形、矩形、三角形)。我们将通过一个工厂来创建这些图形对象。

go
package main

import "fmt"

// 图形接口
type Shape interface {
	Draw()
}

// 圆形
type Circle struct{}

func (c *Circle) Draw() {
	fmt.Println("Drawing a Circle")
}

// 矩形
type Rectangle struct{}

func (r *Rectangle) Draw() {
	fmt.Println("Drawing a Rectangle")
}

// 三角形
type Triangle struct{}

func (t *Triangle) Draw() {
	fmt.Println("Drawing a Triangle")
}

// 简单工厂
type ShapeFactory struct{}

func (f *ShapeFactory) CreateShape(shapeType string) Shape {
	switch shapeType {
	case "circle":
		return &Circle{}
	case "rectangle":
		return &Rectangle{}
	case "triangle":
		return &Triangle{}
	default:
		return nil
	}
}

func main() {
	factory := &ShapeFactory{}

	// 创建一个圆形
	shape := factory.CreateShape("circle")
	shape.Draw()

	// 创建一个矩形
	shape = factory.CreateShape("rectangle")
	shape.Draw()

	// 创建一个三角形
	shape = factory.CreateShape("triangle")
	shape.Draw()
}

核心概念

  • Shape 接口定义了 Draw 方法,表示所有形状的绘制功能。
  • Circle、Rectangle、Triangle 这些具体类型实现了 Shape 接口。
  • ShapeFactory 是一个工厂类,根据传入的 shapeType 参数来实例化不同的形状。

2. 工厂方法模式

工厂方法模式相较于简单工厂模式,它将对象的创建委托给子类,允许子类决定实例化的具体对象。工厂方法模式不直接在工厂类中实现创建对象的逻辑,而是通过抽象工厂方法来让具体的工厂类决定如何创建产品。

示例:工厂方法模式

继续以上的图形绘制程序,我们将通过工厂方法模式来实现:

go
package main

import "fmt"

// 图形接口
type Shape interface {
	Draw()
}

// 圆形
type Circle struct{}

func (c *Circle) Draw() {
	fmt.Println("Drawing a Circle")
}

// 矩形
type Rectangle struct{}

func (r *Rectangle) Draw() {
	fmt.Println("Drawing a Rectangle")
}

// 工厂接口
type ShapeFactory interface {
	CreateShape() Shape
}

// 具体工厂:创建圆形
type CircleFactory struct{}

func (f *CircleFactory) CreateShape() Shape {
	return &Circle{}
}

// 具体工厂:创建矩形
type RectangleFactory struct{}

func (f *RectangleFactory) CreateShape() Shape {
	return &Rectangle{}
}

func main() {
	// 使用圆形工厂
	var factory ShapeFactory = &CircleFactory{}
	shape := factory.CreateShape()
	shape.Draw()

	// 使用矩形工厂
	factory = &RectangleFactory{}
	shape = factory.CreateShape()
	shape.Draw()
}

核心概念

  • Shape 接口定义了 Draw 方法。
  • CircleRectangle 是具体的图形对象。
  • ShapeFactory 是抽象工厂接口,定义了 CreateShape 方法。
  • CircleFactoryRectangleFactory 是具体的工厂类,负责实例化具体的图形对象。

3. 抽象工厂模式

抽象工厂模式是工厂模式的扩展,它提供了一组相关的工厂方法用于创建一系列产品对象。抽象工厂模式不仅能够创建单一产品,还能创建一组相关的产品。通常情况下,抽象工厂用于当你需要创建一组产品,但每个产品都可以是多个不同类型之一时。

示例:抽象工厂模式

我们继续使用图形绘制的例子,扩展成支持不同风格的图形(例如:现代风格和经典风格)。

go
package main

import "fmt"

// 图形接口
type Shape interface {
	Draw()
}

// 现代风格的圆形
type ModernCircle struct{}

func (m *ModernCircle) Draw() {
	fmt.Println("Drawing a Modern Circle")
}

// 经典风格的圆形
type ClassicCircle struct{}

func (c *ClassicCircle) Draw() {
	fmt.Println("Drawing a Classic Circle")
}

// 现代风格的矩形
type ModernRectangle struct{}

func (m *ModernRectangle) Draw() {
	fmt.Println("Drawing a Modern Rectangle")
}

// 经典风格的矩形
type ClassicRectangle struct{}

func (c *ClassicRectangle) Draw() {
	fmt.Println("Drawing a Classic Rectangle")
}

// 抽象工厂接口
type ShapeFactory interface {
	CreateCircle() Shape
	CreateRectangle() Shape
}

// 现代风格的工厂
type ModernFactory struct{}

func (m *ModernFactory) CreateCircle() Shape {
	return &ModernCircle{}
}

func (m *ModernFactory) CreateRectangle() Shape {
	return &ModernRectangle{}
}

// 经典风格的工厂
type ClassicFactory struct{}

func (c *ClassicFactory) CreateCircle() Shape {
	return &ClassicCircle{}
}

func (c *ClassicFactory) CreateRectangle() Shape {
	return &ClassicRectangle{}
}

func main() {
	// 创建现代风格的工厂
	modernFactory := &ModernFactory{}
	modernCircle := modernFactory.CreateCircle()
	modernCircle.Draw()

	// 创建经典风格的工厂
	classicFactory := &ClassicFactory{}
	classicRectangle := classicFactory.CreateRectangle()
	classicRectangle.Draw()
}

核心概念

  • Shape 接口定义了 Draw 方法。
  • ModernCircle、ClassicCircle、ModernRectangle、ClassicRectangle 是不同风格的具体产品。
  • ShapeFactory 是抽象工厂接口,定义了 CreateCircleCreateRectangle 方法。
  • ModernFactory 和 ClassicFactory 是具体的工厂类,分别创建不同风格的产品。

工厂模式的优缺点

优点

  1. 封装对象创建过程
    • 客户端不需要了解产品的具体创建过程,只需要调用工厂方法。
  2. 便于扩展
    • 新的产品类型可以通过添加新的工厂类来扩展,符合开闭原则。
  3. 隔离复杂的创建过程
    • 工厂方法将复杂的对象创建过程抽象出来,减少客户端的复杂性。

缺点

  1. 增加代码量
    • 每增加一个新的产品类型,就需要创建一个新的工厂类,导致代码量增加。
  2. 不灵活
    • 如果产品类之间的差异较小,工厂方法模式可能导致过多的冗余代码。

总结

工厂模式提供了创建对象的灵活性,通过将对象的创建过程抽象出来,可以使客户端代码解耦,便于扩展和维护。在 Go 中,工厂模式能够利用接口、结构体和方法的组合来实现强大的灵活性和可扩展性。