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

《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)

文章目录

  • 1. 概述
    • 1.1 角色
    • 1.2 类图
  • 2. 代码示例
    • 2.1 设计
    • 2.2 代码
    • 2.3 类图

1. 概述

1.1 角色

  • AbstractFactory(抽象工厂):它声明了一组用于创建产品的方法,每一个方法对应一种产品。
  • ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
  • AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

1.2 类图

«interface»
ProductA
ProductA1
ProductA2
«interface»
ProductB
ProductB1
ProductB2
Client
«interface»
AbstractFactory
+CreateProductA() : ProductA
+CreateProductB() : ProductB
ConcreteFactory1
+CreateProductA() : ProductA
+CreateProductB() : ProductB
ConcreteFactory2
+CreateProductA() : ProductA
+CreateProductB() : ProductB

2. 代码示例

2.1 设计

  • 定义抽象产品A
    • 定义具体产品A-1
      • 它有NameWeight两个成员
      • 它的SetName()SetWeight()两个方法分别负责设置以上两个成员
      • 它的Get()方法获取它本身的信息
    • 定义具体产品A-2
      • 它有NameWeight两个成员
      • 它的SetName()SetWeight()两个方法分别负责设置以上两个成员
      • 它的Get()方法获取它本身的信息
  • 定义抽象产品B
    • 定义具体产品B-1
      • 它有NameHeight两个成员
      • 它的SetName()SetHeight()两个方法分别负责设置以上两个成员
      • 它的Get()方法获取它本身的信息
    • 定义具体产品B-2
      • 它有NameHeight两个成员
      • 它的SetName()SetHeight()两个方法分别负责设置以上两个成员
      • 它的Get()方法获取它本身的信息
  • 定义抽象工厂
    • 定义具体工厂1
      • 它的方法SetProductA()设置具体产品A-1
      • 它的方法SetProductB()设置具体产品B-1
    • 定义具体工厂2
      • 它的方法SetProductA()设置具体产品A-2
      • 它的方法SetProductB()设置具体产品B-2
  • 定义一个函数CreateFactory(),用来创建具体工厂
  • 调用
    • CreateFactory()函数实例化 具体工厂1——factory1
    • factory1实例化产品A-1产品B-1,并查看结果
    • CreateFactory()函数实例化 具体工厂2——factory2
    • factory2实例化产品A-2产品B-2,并查看结果

2.2 代码

package mainimport "fmt"// 定义抽象产品A
type AbstractProductA interface {SetName(name string)SetWeight(weight int64)Get()
}// 定义具体产品A-1
type ConcreteProductA1 struct {Name   stringWeight int64
}func (c *ConcreteProductA1) SetName(name string) {c.Name = name
}func (c *ConcreteProductA1) SetWeight(weight int64) {c.Weight = weight
}func (c *ConcreteProductA1) Get() {fmt.Printf("%v\n", c)
}// 定义具体产品A-2
type ConcreteProductA2 struct {Name   stringWeight int64
}func (c *ConcreteProductA2) SetName(name string) {c.Name = name
}func (c *ConcreteProductA2) SetWeight(weight int64) {c.Weight = weight
}
func (c *ConcreteProductA2) Get() {fmt.Printf("%v\n", c)
}// 定义抽象产品B
type AbstractProductB interface {SetName(name string)SetHeight(height int64)Get()
}// 定义具体抽象产品B-1
type ConcreteProductB1 struct {Name   stringHeight int64
}func (c *ConcreteProductB1) SetName(name string) {c.Name = name
}func (c *ConcreteProductB1) SetHeight(height int64) {c.Height = height
}
func (c *ConcreteProductB1) Get() {fmt.Printf("%v\n", c)
}// 定义具体产品B-2
type ConcreteProductB2 struct {Name   stringHeight int64
}func (c *ConcreteProductB2) SetName(name string) {c.Name = name
}func (c *ConcreteProductB2) SetHeight(height int64) {c.Height = height
}
func (c *ConcreteProductB2) Get() {fmt.Printf("%v\n", c)
}// Factory部分// 定义抽象工厂
type Factory interface {SetProductA(name string, weight int64) AbstractProductASetProductB(name string, height int64) AbstractProductB
}// 定义具体工厂1
type Factory1 struct {
}func (f *Factory1) SetProductA(name string, weight int64) AbstractProductA {a := &ConcreteProductA1{}a.SetName(name)a.SetWeight(weight)return a
}func (f *Factory1) SetProductB(name string, height int64) AbstractProductB {a := &ConcreteProductB1{}a.SetName(name)a.SetHeight(height)return a
}// 定义具体工厂2
type Factory2 struct {
}func (f *Factory2) SetProductA(name string, weight int64) AbstractProductA {a := &ConcreteProductA2{}a.SetName(name)a.SetWeight(weight)return a
}func (f *Factory2) SetProductB(name string, height int64) AbstractProductB {a := &ConcreteProductB2{}a.SetName(name)a.SetHeight(height)return a
}// 写一个创建工厂的函数
func CreateFactory(pType int64) Factory {switch pType {case 1:return &Factory1{}case 2:return &Factory2{}}return nil
}func main() {factory1 := CreateFactory(1)factory1.SetProductA("A1", 3).Get()factory1.SetProductB("B1", 3).Get()factory2 := CreateFactory(2)factory2.SetProductA("A2", 4).Get()factory2.SetProductB("B2", 4).Get()
}
  • 输出
&{A1 3}
&{B1 3}
&{A2 4}
&{B2 4}

2.3 类图

«interface»
ProductA
+SetName(name string)
+SetWeight(weight int64)
+Get()
ProductA1
-Name string
-Weight int64
+SetName(name string)
+SetWeight(weight int64)
+Get()
ProductA2
-String Name
-Int64 Weight
+SetName(name string)
+SetWeight(weight int64)
+Get()
«interface»
ProductB
+SetName(name string)
+SetHeight(height int64)
+Get()
ProductB1
-String Name
-Int64 Height
+SetName(name string)
+SetHeight(height int64)
+Get()
ProductB2
-String Name
-Int64 Height
+SetName(name string)
+SetHeight(height int64)
+Get()
Client
«interface»
AbstractFactory
+SetProductA(name string, weight int64) : AbstractProductA
+SetProductB(name string, height int64) : AbstractProductB
ConcreteFactory1
+SetProductA(name string, weight int64) : AbstractProductA
+SetProductB(name string, height int64) : AbstractProductB
ConcreteFactory2
+SetProductA(name string, weight int64) : AbstractProductA
+SetProductB(name string, height int64) : AbstractProductB

在这里插入图片描述

相关文章:

《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 1.1 角色 AbstractFactory(抽象工厂):它声明了一组用于创建产品的方法,每一个方法对应一种产品。ConcreteFactory(具体工厂&#xf…...

改进粒子群算法优化BP神经网络---回归+分类两种案例

今天采用改进的粒子群算法(LPSO)优化算法优化BP神经网络。本文选用的LPSO算法是之前作者写过的一篇文章:基于改进莱维飞行和混沌映射(10种混沌映射随意切换)的粒子群优化算法,附matlab代码 文章一次性讲解两种案例,回归…...

VSCode和QT联合开发

提示:本文为学习记录,若有错误,请联系作者,谦虚受教。 文章目录 前言一、VSCODE下载二、使用步骤1.下载扩展 二、新建工程1.新建文件夹2.新建工程3.UI界面文件操作4.效果 总结 前言 一、VSCODE下载 下载地址 二、使用步骤 1.下…...

YOLO5-1 使用YOLO5检测 水面漂浮物记录

一 数据集 robflow 漂浮物数据集:buoy Computer Vision Dataset by ai 二 YOLO5管网 yolo5 :https://github.com/ultralytics/yolov5 克隆代码: git clone https://github.com/ultralytics/yolov5 # clone cd yolov5 pip install -r requirements.…...

MongoDB教程-7

正如在MongoDB关系的最后一章中所看到的,为了在MongoDB中实现规范化的数据库结构,我们使用了引用关系的概念,也被称为手动引用,在这个概念中,我们手动将被引用文档的id存储在其他文档中。然而,在一个文档包…...

Redisson提供优秀的并发控制机制

1. JDK集合类 对于JDK的集合类&#xff0c;forEach方法其实并不能完全避免并发修改异常。 forEach本质上还是一个循环遍历&#xff0c;如果在循环体内直接对集合进行修改&#xff0c;仍然会产生ConcurrentModificationException。 例如&#xff1a; List<String> lis…...

Linux: 设置qmake的Qt版本

Qt开发&#xff0c;qmake会对应一个Qt版本&#xff0c;有时候需要切换这个版本&#xff0c;例如把qmake从Qt5.12切换到Qt5.9, 怎么操作呢&#xff1f; 案例如下&#xff1a; 银河麒麟V10系统&#xff0c;下载安装了Qt5.9.8&#xff0c;但是检查qmake发现它使用的是5.12.8&…...

使用LLM插件从命令行访问Llama 2

大家好&#xff0c;最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2&#xff0c;这是一项非常重要的进展。Facebook最初的LLaMA模型于今年2月发布&#xff0c;掀起了开源LLM领域的创新浪潮——从微调变体到从零开始的再创造。 如果在Llama 2版本发布之日&a…...

gateway过滤器没生效,特殊原因

看这边文章的前提&#xff0c;你要会gateway&#xff0c;知道过滤器怎么配置&#xff1f; 直接来看过滤器&#xff0c;局部过滤器 再来看配置 请求路径 http://127.0.0.1:8080/appframework/services/catalog/catalogSpecials.json?pageindex1&pagesize10&pkidd98…...

长相思追剧小游戏

看效果图 Vue长相思 刚学Vue&#xff0c;正好在追剧&#xff0c;看到这个小案例觉得挺好玩的&#xff0c;第一天学&#xff0c;代码太简陋了 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&qu…...

leetcode做题笔记51

按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一种…...

Windows同时安装两个版本的JDK并随时切换,以JDK6和JDK8为例,并解决相关存在的问题(亲测有效)

Windows同时安装两个版本的JDK并随时切换&#xff0c;以JDK6和JDK8为例&#xff0c;并解决相关存在的问题&#xff08;亲测有效&#xff09; 1.下载不同版本JDK 这里给出JDK6和JDK的百度网盘地址&#xff0c;具体安装过程&#xff0c;傻瓜式安装即可。 链接&#xff1a;http…...

【ChatGPT辅助学Rust | 基础系列 | Cargo工具】Cargo介绍及使用

文章目录 前言一&#xff0c;Cargo介绍1&#xff0c;Cargo安装2&#xff0c;创建Rust项目2&#xff0c;编译项目&#xff1a;3&#xff0c;运行项目&#xff1a;4&#xff0c;测试项目&#xff1a;5&#xff0c;更新项目的依赖&#xff1a;6&#xff0c;生成项目的文档&#xf…...

全面了解CPU Profiler:解读CPU性能分析工具的核心功能与用法

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、使用3.1 通过调用系统API3.2 通过Android Stu…...

rust format!如何转义{},输出{}?

在Rust中&#xff0c;如果你想要在字符串中包含花括号 {} &#xff0c;你需要使用双花括号 {{}} 来进行转义。这是因为单个花括号 {} 在字符串中表示占位符&#xff0c;用于格式化字符串。 以下是一个示例&#xff1a; fn main() {let text "这是一个示例&#xff1a; {…...

真人AI写真的制作方法-文生图换脸

AI写真最近火起来了&#xff0c;特别是某款现象级相机的出现&#xff0c;只需要上传自己的照片&#xff0c;就能生成漂亮的写真照&#xff0c;这一产品再次带火了AI绘画。今天我就来分享一个使用Stable Diffusion WebUI制作真人AI写真的方法&#xff0c;不用训练&#xff0c;快…...

vscode如何包含第三方库

方法1&#xff1a;使用C Extension 在include 的 rapidjson的头文件时&#xff0c;vscode会提示找不到的问题 悬停&#xff0c;点击黄色提示 Edit "includePath" setting Include Path&#xff0c;输入rapidjson的include路径 /Users/xxx/workspaces/rapidjson-1.1.…...

【Docker】Docker安装Consul

文章目录 1. 什么是Consul2. Docker安装启动Consul 点击跳转&#xff1a;Docker安装MySQL、Redis、RabbitMQ、Elasticsearch、Nacos等常见服务全套&#xff08;质量有保证&#xff0c;内容详情&#xff09; 1. 什么是Consul Consul是HashiCorp公司推出的开源软件&#xff0c;提…...

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(20)-Fiddler精选插件扩展安装让你的Fiddler开挂到你怀疑人生

1.简介 Fiddler本身的功能其实也已经很强大了&#xff0c;但是Fiddler官方还有很多其他扩展插件功能&#xff0c;可以更好地辅助Fiddler去帮助用户去开发、测试和管理项目上的任务。Fiddler已有的功能已经够我们日常工作中使用了&#xff0c;为了更好的扩展Fiddler&#xff0c…...

计算机top命令

top 快捷键 1 核心参数 1 1 参考资料 [1]. https://blog.csdn.net/weixin_45465395/article/details/115728520 [2].https://www.cnblogs.com/liushui-sky/p/13224762.html...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...