首页 > 其他分享 >4 抽象工厂方法 -- go语言设计模式

4 抽象工厂方法 -- go语言设计模式

时间:2023-08-04 11:03:03浏览次数:44  
标签:struct -- fmt func go new 设计模式 type

工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。因此,可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是本文将要学习的抽象工厂模式的基本思想。

抽象工厂方法模式的实现代码

package main

import "fmt"

// ======= 抽象层 =========
type AbstractApple interface {
	ShowApple()
}

type AbstractBanana interface {
	ShowBanana()
}

type AbstractPear interface {
	ShowPear()
}

//抽象工厂
type AbstractFactory interface {
	CreateApple() AbstractApple
	CreateBanana() AbstractBanana
	CreatePear() AbstractPear
}

// ======== 实现层 =========
/*  中国产品族 */
type ChinaApple struct {}
func (ca *ChinaApple) ShowApple() {
	fmt.Println("中国苹果")
}

type ChinaBanana struct {}
func (cb *ChinaBanana) ShowBanana() {
	fmt.Println("中国香蕉")
}

type ChinaPear struct {}
func (cp *ChinaPear) ShowPear() {
	fmt.Println("中国梨")
}

type ChinaFactory struct {}
func (cf *ChinaFactory) CreateApple() AbstractApple {
	apple := new(ChinaApple)

	return apple
}

func (cf *ChinaFactory) CreateBanana() AbstractBanana {
	banana := new(ChinaBanana)

	return banana
}

func (cf *ChinaFactory) CreatePear() AbstractPear {
	pear := new(ChinaPear)

	return pear
}

/*  日本产品族 */
type JapanApple struct {}
func (ja *JapanApple) ShowApple() {
	fmt.Println("日本苹果")
}

type JapanBanana struct {}
func (jb *JapanBanana) ShowBanana() {
	fmt.Println("日本香蕉")
}

type JapanPear struct {}
func (cp *JapanPear) ShowPear() {
	fmt.Println("日本梨")
}

type JapanFactory struct {}
func (jf *JapanFactory) CreateApple() AbstractApple {
	apple := new(JapanApple)
	return apple
}

func (jf *JapanFactory) CreateBanana() AbstractBanana {
	banana := new(JapanBanana)
	return banana
}

func (cf *JapanFactory) CreatePear() AbstractPear {
	pear := new(JapanPear)

	return pear
}

/*  美国产品族 */
type AmericanApple struct {}
func (aa *AmericanApple) ShowApple() {
	fmt.Println("美国苹果")
}

type AmericanBanana struct {}
func (ab *AmericanBanana) ShowBanana() {
	fmt.Println("美国香蕉")
}

type AmericanPear struct {}
func (ap *AmericanPear) ShowPear() {
	fmt.Println("美国梨")
}

type AmericanFactory struct {}

func (af *AmericanFactory) CreateApple() AbstractApple {
	apple := new(AmericanApple)
	return apple
}

func (af *AmericanFactory) CreateBanana() AbstractBanana {
	banana := new(AmericanBanana)
	return banana
}

func (af *AmericanFactory) CreatePear() AbstractPear {
	pear := new(AmericanPear)
	return pear
}

// ======== 业务逻辑层 =======
func main() {
	//需求1: 需要美国的苹果、香蕉、梨 等对象
	//1-创建一个美国工
	aFac := new(AmericanFactory)

	//2-生产美国苹果
	aApple := aFac.CreateApple()
	aApple.ShowApple()

	//3-生产美国香蕉
	aBanana := aFac.CreateBanana()
	aBanana.ShowBanana()

	//4-生产美国梨
	aPear := aFac.CreatePear()
	aPear.ShowPear()

	//需求2: 需要中国的苹果、香蕉
	//1-创建一个中国工厂
	cFac := new(ChinaFactory)

	//2-生产中国苹果
	cApple := cFac.CreateApple()
	cApple.ShowApple()

	//3-生产中国香蕉
	cBanana := cFac.CreateBanana()
	cBanana.ShowBanana()
}


终端输出

1.png

代码解析

func new(Type) *Type
// 内建函数new分配内存。其第一个实参为类型,而非值。其返回值为指向该类型的新分配的零值的指针。

工厂方法模式的代码拆分

1.项目的准备工作

找到 go 的 GOPATH

$ go env		//可以查看 GOPATH

在 GOPATH 目录下创建3个文件夹

1.bin文件夹		-- 存放编译后的二进制文件

2.pkg文件夹		-- 存放编译后的库文件

3.src文件夹		-- 存放源码文件

2.创建文件夹

​ -- 在项目文件夹 abstruct_fac 里创建新文件夹

​ unify -- 统一,用于存放接口文件

​ module -- 模块,用于存放结构体文件

​ -- 在 module 文件夹里创建

​ china -- 存储与中国相关的结构体

​ japan -- 存储与日本相关的结构体

​ american -- 存储与美国相关的结构体

2.png

3.接口文件 -- unify文件夹

文件1 -- abstractapple.go

package unify

type AbstractApple interface {
	ShowApple()
}

文件2 -- abstractbanana.go

package unify

type AbstractBanana interface {
	ShowBanana()
}

文件3 -- abstractpear.go

package unify

type AbstractPear interface {
	ShowPear()
}

3.png

4.结构体文件 -- module文件夹

1.中国包 -- china 文件夹

文件1 -- chinaapple.go

package china

import "fmt"

/*  中国产品族 */
type ChinaApple struct {}
func (ca *ChinaApple) ShowApple() {
	fmt.Println("中国苹果")
}

文件2 -- chinabanana.go

package china

import "fmt"

type ChinaBanana struct {}
func (cb *ChinaBanana) ShowBanana() {
	fmt.Println("中国香蕉")
}

文件3 -- chinapear.go

package china

import "fmt"

type ChinaPear struct {}
func (cp *ChinaPear) ShowPear() {
	fmt.Println("中国梨")
}

文件1 -- chinafactory.go

package china

import (
		"design/abstract_fac/unify"
)

type ChinaFactory struct {}
func (cf *ChinaFactory) CreateApple() unify.AbstractApple {
	apple := new(ChinaApple)

	return apple
}

func (cf *ChinaFactory) CreateBanana() unify.AbstractBanana {
	banana := new(ChinaBanana)

	return banana
}

func (cf *ChinaFactory) CreatePear() unify.AbstractPear {
	pear := new(ChinaPear)

	return pear
}

4.png

2.日本包 -- japan 文件夹

文件1 -- japanapple.go

package japan

import "fmt"

/*  日本产品族 */
type JapanApple struct {}
func (ja *JapanApple) ShowApple() {
	fmt.Println("日本苹果")
}

文件2 -- japanbanana.go

package japan

import "fmt"

type JapanBanana struct {}
func (jb *JapanBanana) ShowBanana() {
	fmt.Println("日本香蕉")
}

文件3 -- japanpear.go

package japan

import "fmt"

type JapanPear struct {}
func (jp *JapanPear) ShowPear() {
	fmt.Println("日本梨")
}

文件1 -- japanfactory.go

package japan

import (
		"design/abstract_fac/unify"
)

type JapanFactory struct {}
func (jf *JapanFactory) CreateApple() unify.AbstractApple {
	apple := new(JapanApple)
	return apple
}

func (jf *JapanFactory) CreateBanana() unify.AbstractBanana {
	banana := new(JapanBanana)
	return banana
}

func (cf *JapanFactory) CreatePear() unify.AbstractPear {
	pear := new(JapanPear)

	return pear
}

5.png

3.美国包 -- american 文件夹

文件1 -- americanapple.go

package american

import "fmt"

/*  美国产品族 */
type AmericanApple struct {}
func (aa *AmericanApple) ShowApple() {
	fmt.Println("美国苹果")
}

文件2 -- americanbanana.go

package american

import "fmt"

type AmericanBanana struct {}
func (ab *AmericanBanana) ShowBanana() {
	fmt.Println("美国香蕉")
}

文件3 -- americanpear.go

package american

import "fmt"

type AmericanPear struct {}
func (ap *AmericanPear) ShowPear() {
	fmt.Println("美国梨")
}

文件1 -- americanfactory.go

package american

import (
		"design/abstract_fac/unify"
)

type AmericanFactory struct {}

func (af *AmericanFactory) CreateApple() unify.AbstractApple {
	apple := new(AmericanApple)
	return apple
}

func (af *AmericanFactory) CreateBanana() unify.AbstractBanana {
	banana := new(AmericanBanana)
	return banana
}

func (af *AmericanFactory) CreatePear() unify.AbstractPear {
	pear := new(AmericanPear)
	return pear
}

6.png

5.主文件 -- main.go 在项目文件夹

package main

import (
  "design/abstract_fac/module/china"
  "design/abstract_fac/module/japan"
  "design/abstract_fac/module/american"
)

func main() {
	//需求1: 需要中国的苹果、香蕉、梨
	//1-创建一个中国工厂
	cFac := new(china.ChinaFactory)

	//2-生产中国苹果
	cApple := cFac.CreateApple()
	cApple.ShowApple()

	//3-生产中国香蕉
	cBanana := cFac.CreateBanana()
	cBanana.ShowBanana()

	//4-生产中国梨
	cPear := cFac.CreatePear()
	cPear.ShowPear()


	//需求2: 需要日本的苹果、香蕉、梨
	//1-创建一个日本工厂
	jFac := new(japan.JapanFactory)

	//2-生产日本苹果
	jApple := jFac.CreateApple()
	jApple.ShowApple()

	//3-生产日本香蕉
	jBanana := jFac.CreateBanana()
	jBanana.ShowBanana()

	//4-生产日本梨
	jPear := jFac.CreatePear()
	jPear.ShowPear()


	//需求3: 需要美国的苹果、香蕉、梨
	//1-创建一个美国工厂
	aFac := new(american.AmericanFactory)

	//2-生产美国苹果
	aApple := aFac.CreateApple()
	aApple.ShowApple()

	//3-生产美国香蕉
	aBanana := aFac.CreateBanana()
	aBanana.ShowBanana()

	//4-生产美国梨
	aPear := aFac.CreatePear()
	aPear.ShowPear()
}

终端输出

7.png

6.全部文件图

8.png

标签:struct,--,fmt,func,go,new,设计模式,type
From: https://blog.51cto.com/u_14483476/6958467

相关文章

  • C++ Toolkit zz
    所谓“工欲善其事,必先利其器”,从程序员的角度来讲,好工具的使用总会给人带来事半功倍的效果。面对众多工具/软件,我们应该如何取舍呢。前不久,笔者在csdn的c++论坛发了一篇贴文,以期能征求大家的广泛意见,得到了不错的反响。本文在对该贴进行整理的基础上,又做了一些补充。在这里要特别......
  • 优秀产品经理必备的技能有哪些?
     产品经理是负责公司产品的人。他们与产品团队和开发团队等团队合作,创造出在他们的行业中畅销的有效产品。由于涉及所有技术方面,例如编程语言和数据分析,技术技能对于成为一名成功的产品经理是必不可少的。但是,软技能也很重要,因为它们可以帮助他们更好地与团队中的其他人合作。在这......
  • CVS命令深入研究 zz
    CVS命令深入研究 作者:leizhimin日期:2006-11-2 环境:Windowsserver2003sp1简体中文版cvsnt-2.5.03.2260.msi目录:一、CVS命令整体结构二、CVS帮助察看方法概述三、CVS选项四、CVS命令五、CVS命令缩写六、C......
  • 系统架构设计师笔记第43期:云原生架构案例分析
    云原生架构是一种软件架构和开发方法论,旨在利用云计算、容器化和微服务等技术,构建高度可伸缩、弹性和可靠的应用程序。它的设计理念是将应用程序与底层的基础设施解耦,以实现更高的灵活性、可维护性和可扩展性。云原生架构的核心特点包括:微服务架构:将应用程序拆分为一组小型、自治的......
  • Sublime Text4修改tab键为4个空格
    SublimeText4设置保存时自动将tab制表符替换为4个空格sublime编辑器虽然能够用来编写python脚本,但是它在代码格式化以及缩进上就是要自己去设置才可以了,因为python对于空格以及缩进是有严格要求的。下面介绍一下该如何在sublime编辑器中显示制表符和空格,以及修改tab键为4个空格的......
  • 秒杀99%的海量数据处理面试题
    前言  一般而言,标题含有“秒杀”,“99%”,“史上最全/最强”等词汇的往往都脱不了哗众取宠之嫌,但进一步来讲,如果读者读罢此文,却无任何收获,那么,我也甘愿背负这样的罪名:-),同时,此文可以看做是对这篇文章:十道海量数据处理面试题与十个方法大总结的一般抽象性总结。  毕竟受文章......
  • 车载水基灭火器上架亚马逊应该怎么做呢?
    车载水基灭火器上架亚马逊美国站需要办理UL8测试报告。车载水基灭火器是一种重要的安全装备,它能够在紧急情况下有效灭火,保护车辆和乘员的安全。为了确保灭火器的质量和性能达到国际标准,UL测试报告是不可或缺的。那么,关于车载水基灭火器上架亚马逊美国站UL测试报告办理的问题,应该如......
  • Managed Debugging Assistants (zz)
    GettingRIDofJust-In-Timedebugge//z2013-08-0817:15:[email protected][T300,L4609,R130,V3618]AfterVisualStudioisinstalledonaserver,thedefaultbehaviorwhenanunhandledexceptionoccursistoshowan Exception dialogthatrequ......
  • Windows运行命令之netstat命令详解
    一、简介netstat命令显示处于活动状态的TCP连接、计算机正在侦听的端口、以太网统计信息、IP路由表、用于IP、ICMP、TCP和UDP协议的IPv4统计信息和IPv6统计信息(IPv6、ICMPv6、TCPoverIPv6和UDPoverIPv6协议)。使用没有参数的情况下,此命令显示活动TCP连接。 二、命令示例1、nets......
  • TwinCAT3 Database Server 模块的使用步骤(以MySQL为例)
    1.首先安装Mysql和Twincat3TF6420-Database-Server.exe2.在Mysql中创建数据库,以测试为目的,所以简单创建了两个 3.Twincat3可以在项目中添加,或者可以直接在菜单栏的Configurator中配置 连接的数据库的类型为NET_MySQL,由于拓扑是均基于一台IPC,所以可以选择localhost,数据库......