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

news2024/9/21 20:50:57

文章目录

  • 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 main

import "fmt"

// 定义抽象产品A
type AbstractProductA interface {
	SetName(name string)
	SetWeight(weight int64)
	Get()
}

// 定义具体产品A-1
type ConcreteProductA1 struct {
	Name   string
	Weight 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   string
	Weight 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   string
	Height 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   string
	Height 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) AbstractProductA
	SetProductB(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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/824487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

phpstudy 进行 composer 全局配置

背景 因为注意到,使用 phpStudy 进行环境搭建时,有时需要使用 composer 每次都需要查找资料进行配置, 在此进行记录笔记,方便有需要的道友借鉴 配置 版本:composer1.8.5(phpStudy8 当前只能安装这一个版本…

CAD批量转PDF的简单方法,三个步骤轻松完成转换

PDF格式的图纸可以在各种设备和软件上打开,因为PDF是一种跨平台的格式,不受操作系统或软件版本的影响。这意味着CAD图纸可以更容易地在不同的设备和操作系统之间传输,而无需担心兼容性问题,可以使图纸更易于共享、浏览和保护&…

Vue进阶(幺叁陆): transition标签实现页面跳转动画

文章目录 一、前言二、方案实现三、延伸阅读 transition标签四、拓展阅读 一、前言 在Vue项目开发过程中,应用全家桶vue-router实现路由跳转,且页面前进、后退跳转过程中,分别对应不同的切换动画。vue-router 切换页面时怎么设置过渡动画&am…

Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…

Doccano工具安装教程/文本标注工具/文本标注自己的项目/NLP分词器工具/自然语言处理必备工具/如何使用文本标注工具

这篇文章是专门的安装教程,后续的项目创建,如何使用,以及代码部分可以参考这篇文章: NER实战:(NLP实战/命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读)_会害羞的杨卓越的博客-…

【uniapp 样式】使用setStorageSync存储历史搜索记录

<template><view><view class"zhuangbox u-flex"><u--inputplaceholder"请输入关键字搜索"border"surround"shapecircleprefixIcon"search"prefixIconStyle"font-size: 22px;color: #909399"v-model&q…

vSphere ESXI 7.0 网络规划

ESXi 网络 业务网络、Vmotion&#xff08;漂移&#xff09;、管理网络、存储网络 ESXi 管理网络 vCenter Server 管理网络 vCenter Server SSO域名 Single Sign-on域名&#xff1a;在没有指定的情况下&#xff0c;默认填写 vsphere.local VMware vSphere整体解决方案和网络…

uniapp点击图片放大预览

阐述 有些时候我们在用uniapp显示图片时&#xff0c;有的不宜全部显示到屏幕上&#xff0c;uniapp提供了一个非常好用的api。 实现方式如下&#xff1a; <template><view class"content"><image class"logo" src"/static/images/a.…

Nacos 持久化实例 删不掉问题( Please unregister instance first )

文章目录 一、报错现象&#xff1a;二、问题解决过程&#xff1a;三、最终解决方案&#xff1a;四、注销实例API&#xff1a; &#x1f50e;请直接看第三部分&#x1f50e; 一、报错现象&#xff1a; 二、问题解决过程&#xff1a; 尝试将服务下线&#xff1a; 再次点击删除按…

如何在水务行业运用IPD?

水务行业&#xff0c;包括自来水的生产和供应、水务及其再生利用和其他水的处理、利用与分配。水务行业主要环节分布包括原水生产与供应、自来水生产和供应、污水收集、水务、中水与再生水利用等。 我国水务行业的产业链包括上游、中游、下游。上游包括科研和规划设计、设备及材…

英雄的力量【力扣2681】

1、解题思路 将数组按从大到小的顺序排列&#xff0c;i<j&#xff0c;那么以nums[i]开始&#xff0c;nums[j]结尾&#xff0c;i----j中的任意数&#xff0c;组成的排列&#xff0c;其英雄力量都是nums[i]*nums[i]*nums[j]&#xff1b; 若ij&#xff0c;则只有一种排列组合…

SOC FPGA之流水灯设计

一、DS-5简介 Altera Soc EDS开发套件的核心是Altera版ARM Development Studio 5(DS-5)工具包&#xff0c;为SoC器件提供了完整的嵌入式开发环境、FPGA自适应调试和对Altera工具的兼容。 1.1 DS-5 eclipse破解 首先下载破解器 然后进入cmd运行&#xff0c;进入到破解器所在文…

AndroidBanner - ViewPager

解决banner 不可见依旧轮播的问题 思考一下&#xff1a;什么时候可以轮播&#xff0c;什么时候不可以轮播 当Banner添加到屏幕上&#xff0c;且对用户可见的时候&#xff0c;可以开始轮播 当Banner从屏幕上移除&#xff0c;或者Banner不可见的时候&#xff0c;可以停止轮播 当…

排序进行曲-v2.0

小程一言 这篇文章是在排序进行曲1.0之后的续讲&#xff0c; 0之后的续讲,英语在上一篇讲的排序的基本概念与分类0之后的续讲, 英语在上一篇讲的排序的基本概念与分类这片主要是对0之后的续讲,英语在上一篇讲的排序的基本概念与分类这 篇主要是对几个简单的排序进行细致的分析…

Mr. Cappuccino的第55杯咖啡——Mybatis一级缓存二级缓存

Mybatis一级缓存&二级缓存 概述一级缓存特点演示前准备效果演示在同一个SqlSession中在不同的SqlSession中 源代码怎么禁止使用一级缓存一级缓存在什么情况下会被清除 二级缓存特点演示前准备效果演示在不同的SqlSession中 源代码怎么关闭二级缓存 一级缓存&#xff08;Spr…

【css】css调整文本间距

text-indent 属性用于指定文本第一行的缩进letter-spacing 属性用于指定文本中字符之间的间距line-height 属性用于指定行之间的间距&#xff1a;word-spacing 属性用于指定文本中单词之间的间距&#xff0c;这个和letter-spacing类似white-space 属性指定元素内部空白的处理方…

Java面向对象之方法的使用

文章目录 一、什么是方法二、方法的声明格式三、方法的分类四、方法的调用五、方法的注意点六、方法的重载七、可变形参的方法八、方法参数的值传递机制九、递归方法 一、什么是方法 方法(method)是类或对象行为特征的抽象&#xff0c;用来完成某个功能操作。在某些语言中也称…

JavaScript将CSV文件转为JSON

说在前面 相信平时大家或多或少都会有遇到过类似的情况&#xff1a; &#x1f64e;&#xff08;需求小姐姐&#xff09; &#x1f64e;‍♂&#xff08;我&#xff09; &#x1f64e;&#xff1a;这里我们需要做一个省市联动下拉框&#xff0c;你看看可以做吗&#xff1f; &am…

基于SSM 应急指挥平台-计算机毕设 附源码 13263

SSM应急指挥平台 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0…

DFS之连通性--迷宫

思路&#xff1a;就是通过dfs进行搜索&#xff0c;看是否能从给定的起点到给定的终点&#xff0c;当然也可以用bfs写&#xff0c;这里用到dfs写的 #include<bits/stdc.h> using namespace std; int n; char g[1010][1010]; int ax,ay,bx,by; int dx[4]{1,0,-1,0}; int dy…