当前位置: 首页 > news >正文

Go 语言 设计模式-抽象工厂模式

抽象工厂模式

抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
在这里插入图片描述

抽象工厂定义了用于创建不同产品的接口, 但将实际的创建工作留给了具体工厂类。 每个工厂类型都对应一个特定的产品变体。

在创建产品时, 客户端代码调用的是工厂对象的构建方法, 而不是直接调用构造函数 (new操作符)。 由于一个工厂对应一种产品变体, 因此它创建的所有产品都可相互兼容。

客户端代码仅通过其抽象接口与工厂和产品进行交互。 该接口允许同一客户端代码与不同产品进行交互。 你只需创建一个具体工厂类并将其传递给客户端代码即可。

概念示例

让我们假设一下, 如果你想要购买一组运动装备, 比如一双鞋与一件衬衫这样由两种不同产品组合而成的套装。 相信你会想去购买同一品牌的商品, 这样商品之间能够互相搭配起来。

如果我们把这样的行为转换成代码的话, 帮助我们创建此类产品组的工具就是抽象工厂, 便于产品之间能够相互匹配。

iSportsFactory.go: 抽象工厂接口

package main

import "fmt"

type ISportsFactory interface {
    makeShoe() IShoe
    makeShirt() IShirt
}

func GetSportsFactory(brand string) (ISportsFactory, error) {
    if brand == "adidas" {
        return &Adidas{}, nil
    }

    if brand == "nike" {
        return &Nike{}, nil
    }

    return nil, fmt.Errorf("Wrong brand type passed")
}

adidas.go: 具体工厂

package main

type Adidas struct {
}

func (a *Adidas) makeShoe() IShoe {
    return &AdidasShoe{
        Shoe: Shoe{
            logo: "adidas",
            size: 14,
        },
    }
}

func (a *Adidas) makeShirt() IShirt {
    return &AdidasShirt{
        Shirt: Shirt{
            logo: "adidas",
            size: 14,
        },
    }
}

nike.go: 具体工厂

package main

type Nike struct {
}

func (n *Nike) makeShoe() IShoe {
    return &NikeShoe{
        Shoe: Shoe{
            logo: "nike",
            size: 14,
        },
    }
}

func (n *Nike) makeShirt() IShirt {
    return &NikeShirt{
        Shirt: Shirt{
            logo: "nike",
            size: 14,
        },
    }
}

iShoe.go: 抽象产品

package main

type IShoe interface {
    setLogo(logo string)
    setSize(size int)
    getLogo() string
    getSize() int
}

type Shoe struct {
    logo string
    size int
}

func (s *Shoe) setLogo(logo string) {
    s.logo = logo
}

func (s *Shoe) getLogo() string {
    return s.logo
}

func (s *Shoe) setSize(size int) {
    s.size = size
}

func (s *Shoe) getSize() int {
    return s.size
}

adidasShoe.go: 具体产品

package main

type AdidasShoe struct {
    Shoe
}

nikeShoe.go: 具体产品

package main

type NikeShoe struct {
    Shoe
}

iShirt.go: 抽象产品

package main

type IShirt interface {
    setLogo(logo string)
    setSize(size int)
    getLogo() string
    getSize() int
}

type Shirt struct {
    logo string
    size int
}

func (s *Shirt) setLogo(logo string) {
    s.logo = logo
}

func (s *Shirt) getLogo() string {
    return s.logo
}

func (s *Shirt) setSize(size int) {
    s.size = size
}

func (s *Shirt) getSize() int {
    return s.size
}

adidasShirt.go: 具体产品

package main

type AdidasShirt struct {
    Shirt
}

nikeShirt.go: 具体产品

package main

type NikeShirt struct {
    Shirt
}

main.go: 客户端代码

package main

import "fmt"

func main() {
    adidasFactory, _ := GetSportsFactory("adidas")
    nikeFactory, _ := GetSportsFactory("nike")

    nikeShoe := nikeFactory.makeShoe()
    nikeShirt := nikeFactory.makeShirt()

    adidasShoe := adidasFactory.makeShoe()
    adidasShirt := adidasFactory.makeShirt()

    printShoeDetails(nikeShoe)
    printShirtDetails(nikeShirt)

    printShoeDetails(adidasShoe)
    printShirtDetails(adidasShirt)
}

func printShoeDetails(s IShoe) {
    fmt.Printf("Logo: %s", s.getLogo())
    fmt.Println()
    fmt.Printf("Size: %d", s.getSize())
    fmt.Println()
}

func printShirtDetails(s IShirt) {
    fmt.Printf("Logo: %s", s.getLogo())
    fmt.Println()
    fmt.Printf("Size: %d", s.getSize())
    fmt.Println()
}

output.txt: 执行结果

Logo: nike
Size: 14
Logo: nike
Size: 14
Logo: adidas
Size: 14
Logo: adidas
Size: 14

相关文章:

  • 全网没有之一的API 文档:Swagger
  • dubbo环境搭建ZooKeeper注册中心
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • 欧拉函数算法的实现
  • Ubuntu 创建本地 Git 并与 Github(私有库) 交互(上传与下载)| 记录 | 踩坑
  • 6.0、软件测试——判定表法
  • 面试题~~
  • 容斥原理算法的实现
  • 【爬虫】Python使用动态IP,多线程,爬取uncomtrade的数据
  • 【国科大——认知计算】认知计算 第一次研讨课
  • 20天深度复习JavaSE的详细笔记(十二)——集合(Collection、数据结构、List、泛型深入)
  • 测试项目中的风险管理
  • 数据结构第一课 —— 时间和空间复杂度
  • 剑指offer-62-圆圈中最后剩下的数字
  • 【vue】vue3中状态管理Pinia(Vuex5)使用快速上手
  • #Java异常处理
  • [Vue CLI 3] 配置解析之 css.extract
  • Android 控件背景颜色处理
  • ES学习笔记(12)--Symbol
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Javascript编码规范
  • Java程序员幽默爆笑锦集
  • Js基础知识(一) - 变量
  • oschina
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • Vue2 SSR 的优化之旅
  • vue-router的history模式发布配置
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • vue学习系列(二)vue-cli
  • vue总结
  • 百度地图API标注+时间轴组件
  • 程序员最讨厌的9句话,你可有补充?
  • 计算机在识别图像时“看到”了什么?
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 前端路由实现-history
  • 前端相关框架总和
  • 三栏布局总结
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 首页查询功能的一次实现过程
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 我建了一个叫Hello World的项目
  • 一道闭包题引发的思考
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 栈实现走出迷宫(C++)
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • "无招胜有招"nbsp;史上最全的互…
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (k8s中)docker netty OOM问题记录
  • (Python第六天)文件处理
  • (pytorch进阶之路)扩散概率模型
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (译)2019年前端性能优化清单 — 下篇
  • (转)Linux NTP配置详解 (Network Time Protocol)