Golang设计模式—简单工厂模式(Simple Factory Pattern)
Golang设计模式——简单工厂模式
背景
假设我们在做一款小型翻译软件,软件可以将德语、英语、日语都翻译成目标中文,并显示在前端。
思路
我们会有三个具体的语言翻译结构体,或许以后还有更多,但现在分别是GermanTranslater、EnglishTranslater、JapaneseTranslater,他们都共同实现了一个接口Translator。
//翻译接口
type Translator interface {
Translate(string) string
}
//德语翻译类
type GermanTranslator struct{}
func (*GermanTranslator) Translate(words string) string {
return "德语"
}
//英语翻译类
type EnglishTranslator struct{}
func (*EnglishTranslator) Translate(words string) string {
return "英语"
}
//日语翻译类
type JapaneseTranslator struct{}
func (*JapaneseTranslator) Translate(words string) string {
return "日语"
}
接下来在程序入口获取用户输入的文本,并将其翻译
package main
import (
"fmt"
"time"
)
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
time.Sleep(3 * time.Second)
}()
var lan int
fmt.Printf("%s\r\n%s\r\n", "以下是可翻译的语言种类,请输入代表数字", "1:德语、2:英语、3:日语")
fmt.Scanln(&lan)
fmt.Println("请输入要翻译成中文的文本:")
var inputWords string
fmt.Scanln(&inputWords)
var translator Translator
//根据不同的语言种类,实例化不同的翻译类
switch lan {
case 1:
translator = new(GermanTranslator)
case 2:
translator = new(EnglishTranslator)
case 3:
translator = new(JapaneseTranslator)
default:
panic("no such translator")
}
fmt.Println(translator.Translate(inputWords))
}
运行结果

缺点
- 违背了开闭原则,以后还可能有法语、俄语、阿拉伯语等其他翻译器,每一次添加翻译器都要在客户端代码增加对应的switch分支,维护成本高。倘若还有不止一处调用了创建逻辑,还要维护多处代码。
- 违背了单一职责原则,客户端处理类的职责应该只是负责接收用户的输入并将其打印,现在还负责翻译类的创建逻辑,导致这个类的职责过多。
改善
为了解决每次新增翻译类都要修改客户端的问题,我们引入一个很重要的设计原则,可以说每种设计模式都遵循着这个设计原则。
设计原则:找出用中可能需要变化之处,并把它们独立出来,不要和那些不需要变化的代码混在一起。
这样的话,每次当新的需求来临,我们只会改动到那些需要变化的地方,而不变的地方就不会被改动影响到。
显然,翻译应用中容易变化的地方是生成翻译类的逻辑,因此我们把这部分职责抽出来,把它交给另外一个类去做(一般是一个静态方法),这个类就叫翻译工厂。而客户端再需要生成翻译类实例时,仅需调用翻译工厂提供的方法即可。就算以后翻译工厂会提供更多的翻译类,也不会修改到客户端的代码,因此也就有了我们的现在的简单工厂模式。
简单工厂模式(Simple Factory Pattern)
又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
UML类图

于是我们根据简单工厂模式再完善之前的代码,如下所示。
工厂代码
func Create(lan int) Translator {
var translator Translator
//根据不同的语言种类,实例化不同的翻译类
switch lan {
case 1:
translator = new(GermanTranslator)
case 2:
translator = new(EnglishTranslator)
case 3:
translator = new(JapaneseTranslator)
default:
panic("no such translator")
}
return translator
}
客户端代码
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
}
time.Sleep(3 * time.Second)
}()
var lan int
fmt.Printf("%s\r\n%s\r\n", "以下是可翻译的语言种类,请输入代表数字", "1:德语、2:英语、3:日语")
fmt.Scanln(&lan)
fmt.Println("请输入要翻译成中文的文本:")
var inputWords string
fmt.Scanln(&inputWords)
//客户端只关注如何获取翻译类,而不用关注创建翻译类的细节
translator:=CreateTranslator(lan)
fmt.Println(translator.Translate(inputWords))
}
优点
- 将客户端和创建产品实例解耦开来,使客户端只需要关注如何获取实例。
- 符合单一职责。
缺点
- 增加新翻译类时还是需要改动工厂类,没有符合开闭原则。
应用场景
当在代码里看到switch的时候,就应该思考是否用简单工厂模式。
作者:胡金生
出处:www.aprilboy.com
版权所有,欢迎保留原文链接进行转载:)
Golang设计模式—简单工厂模式(Simple Factory Pattern)的更多相关文章
- 【设计模式】简单工厂模式 Simple Factory Pattern
简单工厂模式Simple Factory Pattern[Simple Factory Pattern]是设计模式里最简单的一个模式,又叫静态工厂模式[Static Factory Pattern], ...
- 大白话简单工厂模式 (Simple Factory Pattern)
大白话简单工厂模式 (Simple Factory Pattern) 从买车经历说起 毕业两年,码农张小两口无法忍受挤公交,凌晨起床抢火车票的痛苦,遂计划买车.逛了多家4S店,最终定下日产某车型的轿车 ...
- Net设计模式实例之简单工厂模式(Simple Factory Pattern)
一.简单工厂模式简介(Bref Introduction) 简单工厂模式(Simple Factory Pattern)的优点是,工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类, ...
- 设计模式之简单工厂模式(Simple Factory Pattern)
一.简单工厂模式的由来 所有设计模式都是为解决某类问题而产生的,那么简单工厂模式是为解决什么问题呢?我们假设有以下业务场景: 在一个学生选课系统中,文科生用户选课时,我们要获得文科生的所有课程列表:理 ...
- 设计模式之—简单工厂模式<Simple Factory Pattern >
简单工厂模式结构图: 简单工厂模式以简单的加减乘除运算为例: 运算符类(Operation): namespace CalcTest.Simple_Factory_patterns { class O ...
- 【UE4 设计模式】简单工厂模式 Simple Factory Pattern
概述 描述 又称为静态工厂方法 一般使用静态方法,根据参数的不同创建不同类的实例 套路 创建抽象产品类 : 创建具体产品类,继承抽象产品类: 创建工厂类,通过静态方法根据传入不同参数从而创建不同具体产 ...
- 简单工厂模式(Simple Factory Pattern)
简单工厂模式概述 定义:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类 在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被 ...
- 六个创建模式之简单工厂模式(Simple Factory Pattern)
定义: 定义一个工厂类,它可以根据参数的不同生成对应的类的实例:被创建的类的实例通常有相同的父类.因为该工厂方法尝尝是静态的,所以又被称为静态工厂方法(Static Factory Method) 结 ...
- 【java设计模式】【创建模式Creational Pattern】简单工厂模式Simple Factory Pattern(静态工厂方法模式Static Factory Method Pattern)
public class Test { public static void main(String[] args){ try{ Factory.factory("A").doSt ...
随机推荐
- 风险管理,未雨绸缪——《代码之殇》读书笔记II
这次的内容主要是关于软件开发过程中的风险管理,包括项目用时估计.产品的发布与更新.承诺兑现的重要性. ①项目用时估计 有人会质疑项目用时估计的可靠性,因为就事而言,这次的任务可能和上次不一样了,开发环 ...
- SQL Server ->> 条件筛选做法之 -- IN(VALUE1,VALUE2,...)与INNER JOIN STRING_SPLIT()性能对比
在以逗号拼接而成的字符串,传入给IN字句的元素字符串中包涵了1400多个元素 两种做法分别为 AND e.ssPfCityId IN ( SELECT CAST(value AS INT) FROM ...
- asp.net MVC4 框架揭秘 读书笔记系列3
IIS/ASP.net管道 本节全部用图形表示便于理解和记忆 1.3.1 IIS5.x与asp.net 1.3.2 IIS 6.0与asp.net 1.3.3 IIS7.0与asp.net 基于IIS ...
- Error creating bean with name xxxx,xxxx must be provided
原因: 继承父类的bean注入是set,get方法 问题: 自己的controller不能创建,因为需要的bean没有创建 解决方法: bean 注入,通过构造函数调用父类的set方法
- MVC5开发环境的配置
如果你打算在VS2012上开发MVC5,请通过WPI来安装此组件:ASP.NET and Web Tools 2013.1 version
- IDL创建泰森多边形
结果图: 附加源码: PRO testVoronoi idx = 0 ; 创建离散点 CASE idx OF ; 随机离散点 0: BEGIN N = 36 X = RANDOMN(seed, N) ...
- JS和css实现检测移动设备方向的变化并判断横竖屏幕
这篇文章主要介绍了JS和css实现检测移动设备方向的变化并判断横竖屏幕,本文分别给出实现代码,需要的朋友可以参考下 方法一:用触发手机的横屏和竖屏之间的切换的事件 [自测可用, chrome , 手 ...
- IIS : Add the server variable name to the allowed server variable list.
IIS下设置反向代理访问时报错:将服务器变量名添加到允许的服务器变量列表中. 1.打开IIS: 2.打开要添加变量的站点: 3.打开URL Rewrite: 4.在右列上,选择“查看服务器变量(Vie ...
- docker学习笔记:简单构建Dockerfile【Docker for Windows】
参考与入门推荐:https://www.cnblogs.com/ECJTUACM-873284962/p/9789130.html#autoid-0-0-9 最近学习docker,写一个简单构建Doc ...
- Curator 基本API
package bjsxt.curator.base; import java.util.List; import java.util.concurrent.ExecutorService; impo ...