工厂模式

‌工厂模式‌ Factory Pattern

工厂模式( Factory Pattern )是一种创建型设计模式,通过将对象的创建过程封装到工厂类中,实现对象创建与使用的解耦,提升系统扩展性和维护性。‌ 其主要核心在于通过统一的接口管理对象实例化过程,使客户端无需直接依赖具体类。‌

工厂模式包含简单工厂模式、工厂方法模式和抽象工厂模式。

‌简单工厂模式

通过一个工厂类根据传入参数动态创建产品对象,违反开闭原则但实现简单(简单工厂模式属于非正式设计模式)。

示例 : 创建一个简单的形状工厂来生成不同类型的形状对象(如圆形、矩形)。

package main

import (
	"fmt"
)

// Shape 定义了形状的接口
type Shape interface {
	Draw()
}

// Circle 实现了 Shape 接口
// Go 中没有关键字显式声明某个类型实现了某个接口。
// 只要一个类型实现了接口要求的所有方法,该类型就自动被认为实现了该接口。
type Circle struct{}

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

// Rectangle 实现了 Shape 接口
type Rectangle struct{}

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

// 接下来,定义一个工厂类 ShapeFactory,它根据传入的参数创建并返回相应的形状对象。
// ShapeFactory 定义了工厂类
type ShapeFactory struct{}

func (sf *ShapeFactory) GetShape(shapeType string) Shape {
	switch shapeType {
	case "circle":
		return &Circle{}
	case "rectangle":
		return &Rectangle{}
	default:
		return nil
	}
}

// 在 main 函数中使用 ShapeFactory 来创建形状对象并调用它们的 Draw 方法。
func main() {
	factory := &ShapeFactory{}
	shape1 := factory.GetShape("circle")
	shape1.Draw()
	shape2 := factory.GetShape("rectangle")
	shape2.Draw()
}

‌工厂方法模式‌

定义抽象工厂接口,由子类决定实例化的具体类。例如:抽象工厂类派生出多个具体工厂,每个工厂负责一种产品的创建(如不同数据库连接)。

示例 :

package main

import (
	"fmt"
)

// Shape 定义了形状的接口
type Shape interface {
	Draw()
}

// Circle 实现了 Shape 接口
// Go 中没有关键字显式声明某个类型实现了某个接口。
// 只要一个类型实现了接口要求的所有方法,该类型就自动被认为实现了该接口。
type Circle struct{}

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

// Rectangle 实现了 Shape 接口
type Rectangle struct{}

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

// 定义工厂类
type ShapeFactory struct {
	CreareShape func() Shape
}

// 定义圆形工厂
type CircleFactory struct{}

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

// 定义矩形工厂
type RectangleFactory struct{}

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

func main() {
	circleFactory := &CircleFactory{}
	circle := circleFactory.CreateShape()
	circle.Draw()
	rectangleFactory := &RectangleFactory{}
	rectangle := rectangleFactory.CreateShape()
	rectangle.Draw()
}

总结

通过工厂方法,可以有效地屏蔽具体业务实现,实现了工厂方法模式的意义 :

‌工厂方法模式的意义在于将对象的创建过程与使用过程分离,通过定义一个接口或抽象类来让子类决定实例化哪一个类‌。这种模式不仅提升了系统的可扩展性和灵活性,还避免了对象创建过程中的代码重复和耦合,从而改善了代码的灵活性和可维护性‌

抽象工厂模式‌

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体类。下面是如何将上述代码改为抽象工厂模式的示例。

假设我们不仅需要创建形状,还需要创建与形状相关的颜色对象。
我们将定义一个抽象工厂接口 AbstractFactory,以及具体的工厂实现 ShapeColorFactory。每个具体的工厂将负责创建相关的形状和颜色对象。

示例代码 :

package main

import (
	"fmt"
)

// Shape 定义了形状的接口
type Shape interface {
	Draw()
}

// Circle 实现了 Shape 接口
type Circle struct{}

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

// Rectangle 实现了 Shape 接口
type Rectangle struct{}

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

// Color 定义了颜色的接口
type Color interface {
	Fill()
}

// Red 实现了 Color 接口
type Red struct{}

func (r *Red) Fill() {
	fmt.Println("Filling with Red")
}

// Green 实现了 Color 接口
type Green struct{}

func (g *Green) Fill() {
	fmt.Println("Filling with Green")
}

// AbstractFactory 定义了抽象工厂接口
type AbstractFactory interface {
	CreateShape(shapeType string) Shape
	CreateColor(colorType string) Color
}

// ShapeColorFactory 实现了 AbstractFactory 接口
type ShapeColorFactory struct{}

func (scf *ShapeColorFactory) CreateShape(shapeType string) Shape {
	switch shapeType {
	case "circle":
		return &Circle{}
	case "rectangle":
		return &Rectangle{}
	default:
		return nil
	}
}

func (scf *ShapeColorFactory) CreateColor(colorType string) Color {
	switch colorType {
	case "red":
		return &Red{}
	case "green":
		return &Green{}
	default:
		return nil
	}
}

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

	shape1 := factory.CreateShape("circle")
	shape1.Draw()

	color1 := factory.CreateColor("red")
	color1.Fill()

	shape2 := factory.CreateShape("rectangle")
	shape2.Draw()

	color2 := factory.CreateColor("green")
	color2.Fill()
}