之前我们介绍了工厂设计模式,现在我们再看一下抽象工厂设计模式。抽象工程模式顾名思义就是对工厂模式的一层抽象,也是创建型模式的一种,通常用来创建一组存在相关性的对象。

UML类图大致如下:

类图比较复杂,最好用个例子来说明。比方说,国内有两家生产运动服的工厂:nike和adidas 。现在我们想购买一套运动服,包含短裤(short)和运动鞋(shoe)。通常我们都会在同一家工厂购买整套的运动服。这时抽象工厂模式就可以发挥作用了。

现在我们需要的产品有两种:短裤(short)和运动鞋(shoe)。

生产这些产品的工厂有两家:nike和adidas。

nike和adidas都是运动服厂商,可以视为是 iSportsFactory接口的实现

然后,我们还要为具体的产品定义两个接口:

  • iShort,它有两个实现,分别是nikeShortadidasShort
  • iShoe,它也有两个实现,分别是nikeShoeadidasShoe

看下具体的代码:

iSportsFactory.go

package main

import "fmt"

type iSportsFactory interface {
makeShoe() iShoe
makeShort() iShort
} 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")
}

  iShort.go

package main

type iShort interface {
setLogo(logo string)
setSize(size int)
getLogo() string
getSize() int
} type short struct {
logo string
size int
} func (s *short) setLogo(logo string) {
s.logo = logo
} func (s *short) getLogo() string {
return s.logo
} func (s *short) setSize(size int) {
s.size = size
} func (s *short) getSize() int {
return s.size
}

  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
}

  nike.go

package main

type nike struct {
} type nikeShoe struct {
shoe
} type nikeShort struct {
short
} func (n *nike) makeShoe() iShoe {
return &nikeShoe{
shoe: shoe{
logo: "nike",
size: 14,
},
}
} func (n *nike) makeShort() iShort {
return &nikeShort{
short: short{
logo: "nike",
size: 14,
},
}
}

  adidas.go

package main

type adidas struct {
} type adidasShoe struct {
shoe
} type adidasShort struct {
short
} func (a *adidas) makeShoe() iShoe {
return &adidasShoe{
shoe: shoe{
logo: "adidas",
size: 14,
},
}
} func (a *adidas) makeShort() iShort {
return &adidasShort{
short: short{
logo: "adidas",
size: 14,
},
}
}

  main.go

package main

import "fmt"

func main() {
adidasFactory, _ := getSportsFactory("adidas")
nikeFactory, _ := getSportsFactory("nike")
nikeShoe := nikeFactory.makeShoe()
nikeShort := nikeFactory.makeShort()
adidasShoe := adidasFactory.makeShoe()
adidasShort := adidasFactory.makeShort()
printShoeDetails(nikeShoe)
printShortDetails(nikeShort)
printShoeDetails(adidasShoe)
printShortDetails(adidasShort)
} func printShoeDetails(s iShoe) {
fmt.Printf("Logo: %s", s.getLogo())
fmt.Println()
fmt.Printf("Size: %d", s.getSize())
fmt.Println()
} func printShortDetails(s iShort) {
fmt.Printf("Logo: %s", s.getLogo())
fmt.Println()
fmt.Printf("Size: %d", s.getSize())
fmt.Println()
}

 代码已上传至GitHub:zhyea / go-patterns / abstract-factory-pattern

End!

GoLang设计模式3 - 抽象工厂模式的更多相关文章

  1. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  2. 桥接模式及C++实现 C++设计模式-AbstractFactory抽象工厂模式

    桥接模式及C++实现 桥接模式 先说说桥接模式的定义:将抽象化(Abstraction)与实现化(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式之一 ...

  3. Java 设计模式之抽象工厂模式(三)

    原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...

  4. java设计模式之抽象工厂模式

    上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改 ...

  5. php设计模式之抽象工厂模式

    之前总结了一下工厂模式,其实准确地说是简单 工厂模式,在它的基础上再进行抽象就可以得到一种新的模式:抽象工厂模式. 专业一点的定义为: 抽象工厂模式(Abstact Factory)是一种常见的软件设 ...

  6. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  7. C#设计模式(4)-抽象工厂模式

    引言 上一篇介绍了设计模式中的简单工厂模式-C#设计模式(3)-工厂方法模式,本篇将介绍抽象工厂模式: 抽象工厂模式简介 抽象工厂模式(AbstractFactory):提供一个创建一系列相关或相互依 ...

  8. C#设计模式之四抽象工厂模式(AbstractFactory)【创建型】

    一.引言     写了3篇有关设计模式的文章了,大家有了些反馈,说能从中学到一些东西,我感到很欣慰,那就继续努力.今天我要写第四个模式了,该模式叫抽象工厂.上一篇文章我们讲了[工厂方法]模式,它是为了 ...

  9. Head First设计模式之抽象工厂模式

    一.定义 给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足一下条件:     1)系统中有多个产品族,而系统一次只可能消费其中一族产品.      2)同属于同一个 ...

随机推荐

  1. Vue__npm run build npm run dev

    npm run build npm run dev 一.以前一直错的做法 以前,git完项目之后就,执行1.npm install 2.npm run build 3.npm run dev.今天ma ...

  2. js学习笔记之自调用函数、闭包、原型链

     自调用函数 var name = 'world!'; // console.log(typeof name) (function () { console.log(this.name, name, ...

  3. 原生ajax练习-post&xml

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Java方法03——方法的重载

    方法的重载(println 就是一个典型的重载(源码)) 重载就是在一个类中,有相同的函数名称,但形参不同的函数 方法重载的规则 方法名称必须相同 参数列表必须不同(个数不同.或者类型不同.参数排列顺 ...

  5. NTP\rsync+inotify

    NTP网络时间协议 NTP(Network Time Protocol)网络时间协议基于UDP,用于网络时间同步的协议,使网络中的计算机时钟同步到UTC(世界统一时间),再配合各个时区的偏移调整就能实 ...

  6. RHCE_DAY05

    cron周期性计划任务 cron周期性计划任务用来定期执行程序,目前最主要的用途是定期备份数据 软件包名:cronie.crontabs 服务名:crond 日志文件:/var/log/cron cr ...

  7. RHCSA_DAY09

    常用特殊符号的使用 Linux系统下通配符起到了很大的作用,对于不确定的文档名称可以使用以下特殊字符表示 *常用的特殊符号,在文件名上,用来代表任意多个任意字符** ? 常用的特殊符号,在文件名上,用 ...

  8. Android音视频开发(1):H264 基本原理

    前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...

  9. Python之replace()方法失效

    1.背景 Titanic存活率预测案例: # 读取数据 df_train = pd.read_csv("./data/train.csv") df_train.head() OUT ...

  10. 【LeetCode】796. 旋转字符串

    796. 旋转字符串 知识点:字符串:KMP算法: 题目描述 给定两个字符串, A 和 B. A 的旋转操作就是将 A 最左边的字符移动到最右边. 例如, 若 A = 'abcde',在移动一次之后结 ...