工厂模式( 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()
}