Golang 设计模式:抽象工厂模式

使用 Golang 实现抽象工厂模式

抽象工厂模式介绍

抽象工厂模式是一种创建型设计模式,旨在提供一个接口用于创建一系列相关或依赖对象,而无需指定其具体类。

产品等级概念

产品等级是指一组具有相似用途或属于同一类别的产品集合。这些产品在功能和用途上有一定的相似性,但不一定有直接的关联。

在电器设备中,不同品牌的空调(比如 格力、美的)构成一个产品等级。它们都属于空调这个大类别,但品牌之间可能有很多差异。

产品族概念

产品族是指一组在某种维度上相关联的产品集合。这些产品之间通常有一定的关联性,可以一起使用,形成一个完整的解决方案。

在同一品牌的产品等级中,不同类型的电器(比如空调、电视机)构成一个产品族。它们之间存在关联性,属于同一品牌的整体产品组合。

需求

当用户需要的家电必须是同一品牌,不想是格力电视和美的空调;并且当你需要在添加新的品牌、新的家电时,不想修改已有代码时,符合开闭原则,可通过抽象工厂模式实现。

特点

抽象工厂模式具有以下特点:

  1. 产品族一致性: 抽象工厂模式确保创建的产品属于同一产品族,即产品之间有一定的关联性。这有助于确保产品的一致性,使它们能够协同工作。
  2. 工厂切换灵活性: 通过使用抽象工厂模式,客户端代码可以轻松地切换不同的工厂,以便创建不同产品族的对象。这使得系统更加灵活,能够适应不同的需求和变化。
  3. 系统扩展性: 当需要引入新的产品族时,只需添加新的具体工厂和产品类,而无需修改已有的代码。这有助于系统的扩展,同时保持对已有功能的稳定性。
  4. 符合开闭原则: 抽象工厂模式符合开闭原则,即对扩展开放,对修改关闭。通过添加新的具体工厂和产品,可以扩展系统的功能,而不会影响到已有的代码。
  5. 降低客户端与产品类的耦合度: 客户端代码通过抽象工厂接口与具体产品类解耦,客户端不需要知道具体产品的实现细节,只需关心抽象工厂接口和产品的一致性。
  6. 适用于复杂对象构建: 抽象工厂模式适用于需要构建一整个产品族,且这些产品族之间存在关联性的场景。它能够提供一种有组织的方式来创建和管理相关对象。

代码示例说明

以下是一个简单的 Golang 代码示例,以上述的家电为例子,演示了抽象工厂模式:

go 复制代码
package main

import "fmt"

// Appliance 表示家电的基本属性
type Appliance struct {
    brand string
}

// IAppliance 定义家电的行为接口
type IAppliance interface {
    Operate()
}

// TV 表示电视
type TV struct {
    Appliance
}

func (t *TV) Operate() {
    fmt.Printf("%s电视正在播放节目\n", t.brand)
}

// AirConditioner 表示空调
type AirConditioner struct {
    Appliance
}

func (ac *AirConditioner) Operate() {
    fmt.Printf("%s空调正在调整温度\n", ac.brand)
}

// AbstractFactory 定义创建家电的抽象工厂接口
type AbstractFactory interface {
    CreateTV() IAppliance
    CreateAirConditioner() IAppliance
}

// GreeFactory 格力品牌的家电工厂
type GreeFactory struct {
}

func (gf *GreeFactory) CreateTV() IAppliance {
    return &TV{Appliance: Appliance{brand: "格力"}}
}

func (gf *GreeFactory) CreateAirConditioner() IAppliance {
    return &AirConditioner{Appliance: Appliance{brand: "格力"}}
}

// MideaFactory 美的品牌的家电工厂
type MideaFactory struct {
}

func (mf *MideaFactory) CreateTV() IAppliance {
    return &TV{Appliance: Appliance{brand: "美的"}}
}

func (mf *MideaFactory) CreateAirConditioner() IAppliance {
    return &AirConditioner{Appliance: Appliance{brand: "美的"}}
}

func main() {
    // 使用格力工厂创建格力家电
    greeFactory := &GreeFactory{}
    greeTV := greeFactory.CreateTV()
    greeAC := greeFactory.CreateAirConditioner()

    greeTV.Operate()
    greeAC.Operate()

    fmt.Println()

    // 使用美的工厂创建美的家电
    mideaFactory := &MideaFactory{}
    mideaTV := mideaFactory.CreateTV()
    mideaAC := mideaFactory.CreateAirConditioner()

    mideaTV.Operate()
    mideaAC.Operate()
}

Appliance 结构体表示家电的基本属性,包括品牌。TVAirConditioner 是具体产品,实现了 IAppliance 接口。AbstractFactory 定义了创建家电的抽象工厂接口,包括创建电视和空调的方法。GreeFactoryMideaFactory 分别是格力和美的品牌的具体工厂,实现了抽象工厂接口。在 main 函数中,我们使用不同的工厂创建格力和美的家电,并调用它们的 Operate 方法。

相关推荐
研究司马懿1 天前
【云原生】Gateway API高级功能
云原生·go·gateway·k8s·gateway api
BD_Marathon1 天前
设计模式——合成复用原则
设计模式·合成复用原则
书院门前细致的苹果1 天前
设计模式大全:单例、工厂模式、策略模式、责任链模式
设计模式·责任链模式·策略模式
梦想很大很大1 天前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰2 天前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
BD_Marathon2 天前
设计模式——依赖倒转原则
java·开发语言·设计模式
BD_Marathon2 天前
设计模式——里氏替换原则
java·设计模式·里氏替换原则
jmxwzy2 天前
设计模式总结
设计模式
却尘2 天前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤2 天前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁