《golang设计模式》第一部分·创建型模式-05-工厂方法模式(Factory Method)

news2024/12/24 23:07:26

文章目录

  • 1 概述
    • 2.1 角色
    • 2.2 类图
  • 2 代码示例
    • 2. 1 设计
    • 2.2 代码
    • 2.3 类图
  • 3. 简单工厂
    • 3.1 角色
    • 3.2 类图
    • 3.3 代码示例
      • 3.3.1 设计
      • 3.3.2 代码
      • 3.3.3 类图

1 概述

工厂方法类定义产品对象创建接口,但由子类实现具体产品对象的创建。

2.1 角色

  • Product(抽象产品):它是具体产品的抽象类,可以是结构体,也可以是接口
  • ConcreteProduct(具体产品):它实现了抽象产品接口,对应了一种具体产品
  • Factroy(抽象工厂):在抽象工厂类中声明了工厂方法,用于返回一个产品。
  • ConcreteFactory(具体工厂):实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

2.2 类图

«interface»
Product
+Get()
ConcreteProductA
+Get()
ConcreteProductB
+Get()
«interface»
Factroy
+CreateProduct()
ConcreteFactroyA
+CreateProduct() : Product
ConcreteFactroyB
+CreateProduct() : Product
Client

2 代码示例

2. 1 设计

2.2 代码

package main

import (
	"fmt"
)

type Product interface {
    Get()
}

type ConcreteProductA struct {
    Name string
	Kind string
}


func (c *ConcreteProductA) Get() {
	fmt.Printf("%+v",c)
}
type ConcreteProductB struct {
    Name string
	Kind string
}


func (c *ConcreteProductB) Get() {
	fmt.Printf("%+v",c)
}

type ConcreteProductC struct {
    Name string
	Kind string
}


func (c *ConcreteProductC) Get() {
	fmt.Printf("%+v",c)
}


type Factroy interface {
	CreateProduct(name string) Product
}

type ConcreteFactoryA struct {
}

func (f  *ConcreteFactoryA) CreateProduct(name string) Product {
	p := &ConcreteProductA{
		Name: name,
		Kind:"A",
	}
	return p
}

type ConcreteFactoryB struct {
}

func (f *ConcreteFactoryB) CreateProduct(name string) Product {
	p := &ConcreteProductB{
		Name: name,
		Kind: "B",
	}
	return p
}

type ConcreteFactoryC struct {
}

func (f *ConcreteFactoryC) CreateProduct(name string) Product {
	p := &ConcreteProductC{
		Name: name,
		Kind: "C",
	}
	return p
}

func CreateProduct(myType int64) Factroy {
	switch myType {
	case 1:
		return  &ConcreteFactoryA{}
	case 2:
		return &ConcreteFactoryB{}
	case 3:
		return &ConcreteFactoryC{}
	}
	return nil
}

func main() {
	factory := CreateProduct(1)
	product := factory.CreateProduct("nginx")
    product.Get()
}
  • 输出
&{Name:nginx Kind:A}

2.3 类图

«interface»
Product
+Get()
ConcreteProductA
+string Name
+string Kind
+Get()
ConcreteProductB
+string Name
+string Kind
+Get()
ConcreteProductC
+string Name
+string Kind
+Get()
«interface»
Factroy
+CreateProduct()
ConcreteFactroyA
+CreateProduct() : Product
ConcreteFactroyB
+CreateProduct() : Product
ConcreteFactroyC
+CreateProduct() : Product

3. 简单工厂

在产品结构简单的情况下,我们可以把工厂模式简化成一个简单工厂

3.1 角色

  • Product(抽象产品):它是具体产品的抽象类,可以是结构体,也可以是接口
  • ConcreteProduct(具体产品):它实现了抽象产品接口,对应了一种具体产品
  • Factroy(简单工厂):根据一个条件用于返回一个产品

去掉了具体工厂角色,产品由简单工厂直接返回。

3.2 类图

«interface»
Product
+Create()
ConcreteProductA
+Create()
ConcreteProductB
+Create()
Factroy
+CreateProduct() : Product

3.3 代码示例

3.3.1 设计

  • 定义一个抽象产品Product
  • 定义三个具体产品ConcreteProductAConcreteProductBConcreteProductC
    • 它们各自的Get()方法会访问它本身
  • 定义一个简单工厂
    • 简单工厂的CreateProduct()方法会返回一个产品
  • 调用
    • 实例化一个简单工厂
    • 用简单工厂创建一个产品
    • 用产品的Get()方法查询结果

3.3.2 代码

package main

import (
	"fmt"
)

type Product interface {
	Get()
}

type ConcreteProductA struct {
	Name string
	Kind string
}

func (c *ConcreteProductA) Get() {
	fmt.Printf("%+v", c)
}

type ConcreteProductB struct {
	Name string
	Kind string
}

func (c *ConcreteProductB) Get() {
	fmt.Printf("%+v", c)
}

type ConcreteProductC struct {
	Name string
	Kind string
}

func (c *ConcreteProductC) Get() {
	fmt.Printf("%+v", c)
}

type Factroy struct {
}

func (f *Factroy) CreateProduct(myType int64, name string) Product {
	switch myType {
	case 1:
		return &ConcreteProductA{
			Name: name,
			Kind: "A",
		}
	case 2:
		return &ConcreteProductB{
			Name: name,
			Kind: "B",
		}
	case 3:
		return &ConcreteProductC{
			Name: name,
			Kind: "C",
		}
	}
	return nil
}

func main() {
	factory := &Factroy{}
	product := factory.CreateProduct(1, "nginx")
	product.Get()
}

  • 输出
&{Name:nginx Kind:A}

3.3.3 类图

«interface»
Product
+Get()
ConcreteProductA
+Name
+Kind
+Cet()
ConcreteProductB
+Name
+Kind
+Get()
ConcreteProductC
+Name
+Kind
+Get()
Factroy
+CreateProduct() : Product

在这里插入图片描述

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

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

相关文章

opencv-38 形态学操作-闭运算(先膨胀,后腐蚀)cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

闭运算是先膨胀、后腐蚀的运算,它有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景图像进行连接。 例如,在图 8-17 中,通过先膨胀后腐蚀的闭运算去除了原始图像内部的小孔(内部闭合的…

MacBook截取网页长图

第一步:⌘Command Option I 第二步:⌘Command Shift P 第三步: 红框内输入Capture full size screenshot,回车,长图会自动下载。

软考高项(六)项目管理概述 ★重点集萃★

👑 个人主页 👑 :😜😜😜Fish_Vast😜😜😜 🐝 个人格言 🐝 :🧐🧐🧐说到做到,言出必行&am…

VR实景导航——开启3D可视化实景导航新体验

数字化时代,我们大家出门在外都是离不开各种导航软件,人们对导航的需求也越来越高,而传统的导航软件由于精度不够,无法满足人们对真实场景的需求,这个时候就需要VR实景导航为我们实景指引目的地的所在。 VR实景导航以其…

新一代开源流数据湖平台Apache Paimon入门实操-上

文章目录 概述定义核心功能适用场景架构原理总体架构统一存储基本概念文件布局 部署环境准备环境部署 实战Catalog文件系统Hive Catalog 创建表创建Catalog管理表查询创建表(CTAS)创建外部表创建临时表 修改表修改表修改列修改水印 概述 定义 Apache Pa…

【每日一题】—— C. Challenging Cliffs(Codeforces Round 726 (Div. 2))

🌏博客主页:PH_modest的博客主页 🚩当前专栏:每日一题 💌其他专栏: 🔴 每日反刍 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…

SpringBoot 项目创建与运行

一、Spring Boot 1、什么是Spring Boot?为什么要学 Spring Boot Spring 的诞生是为了简化 Java 程序的开发的,而 Spring Boot 的诞生是为了简化 Spring 程序开发的。 Spring Boot 翻译一下就是 Spring 脚手架 盖房子的这个架子就是脚手架,…

【Linux】网络编程套接字

1 预备知识 1.1 IP地址 IP协议有两个版本,分别是IPv4和IPv6。没有特殊说明,默认都是IPv4对于IPv4,IP地址是一个四个字节32为的整数;对于IPv6来说,IP地址是128位的整数 我们通常也使用 “点分十进制” 的字符串表示IP…

C 语言高级1-内存分区,多级指针,位运算

目录 1. 内存分区 1.1 数据类型 1.1.1 数据类型概念 1.1.2 数据类型别名 1.1.3 void数据类型 1.1.4 sizeof操作符 1.1.5 数据类型总结 1.2 变量 1.1.1 变量的概念 3.1.2 变量名的本质 1.3 程序的内存分区模型 1.3.1 内存分区 1.3.1.1 运行之前 1.3.1.2运行之后 1…

无涯教程-Perl - 循环语句

在某些情况下,您需要多次执行一个代码块。通常,语句是按顺序执行的:函数中的第一个语句首先执行,然后第二个执行,依此类推。 Perl编程语言提供了以下类型的循环来处理循环需求。 Sr.No.Loop Type & 描述1 while loop在给定条…

Redis-1

Redis 理论部分 redis 速度快的原因 1、纯内存操作 2、单线程操作,避免了频繁的上下文切换和资源争用问题,多线程需要占用更多的 CPU 资源 3、采用了非阻塞 I/O 多路复用机制 4、提供了非常高效的数据结构,例如双向链表、压缩页表和跳跃…

【从零开始学习JAVA | 第三十七篇】初识多线程

目录 前言: ​编辑 引入: 多线程: 什么是多线程: 多线程的意义: 多线程的应用场景: 总结: 前言: 本章节我们将开始学习多线程,多线程是一个很重要的知识点&#xff…

Java泛型(Generic)

文章目录 泛型概述泛型的引入 使用泛型举例集合中使用泛型 比较器中使用泛型相关使用说明自定义泛型结构自定义泛型类或泛型接口3.2.1 说明 自定义泛型方法举例练习 泛型在继承上的体现通配符的使用使用注意点有限制的通配符泛型应用举例 泛型概述 举例1:中药店&am…

第一章:继承

系列文章目录 文章目录 系列文章目录前言继承的概念及定义继承的概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类和派生类对象赋值转换(公有继承)继承中的作用域派生类的默认成员函数继承与友元继承与静态成员不能被继承的类复…

学习系统编程No.35【基于信号量的CP问题】

引言: 北京时间:2023/8/2/12:52,时间飞逝,恍惚间已经来到了八月,给我的第一感觉就是快开学了,别的感觉其实没有,哈哈!看着身边的好友网络相关知识都要全部学完了,就好像…

Linux系统---进程概念

文章目录 冯诺依曼体系结构操作系统(OS)进程的理解 进程状态 进程优先级 环境变量 进程地址空间 一、冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。 如图为冯诺依曼体系结构图&…

【BEV感知】2-BEV感知算法数据形式

文章目录 1 图像1.1 如何获取图像特征? 2 点云2.1 稀疏性2.2 无序性2.3 为什么要用点云?2.4 如何提取点云特征?Point-basedVoxel-based 3 图像点云 1 图像 图像是由相机生成的,是将三维世界中的坐标点(单位为米&#…

I- yh的线段(2023河南萌新联赛第(四)场:河南大学)

链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 yh喜欢好线段,好线段即两条线段相交且不与其他线段重合的线段。 两条线段[l1,r1]和[l2,r2]相交(如果存在至少一个x,使得l1≤x≤r1和l2≤x≤r2,则认为两个线段…

Linux运维面试题(四)之Linux服务管理

Linux运维面试题(四)之Linux服务管理 4.1 SSHSSH的登录验证方式SSH的登陆端口(默认22)和监听设置(/etc/ssh/sshd_config)SSH的登录用户限制(/etc/ssh/sshd_config PermitRootLogin)SSH的登录超时设置(/etc/…

软件测试之Docker常见问题汇总!附解决方法!

1、配置国内源进行docker安装,报错 HTTP Error 404 - Not Found 【整整200集】超超超详细的Python接口自动化测试进阶教程,真实模拟企业项目实战!! 原因: 由于配置国内镜像源时,把地址写错了,导…