zoukankan      html  css  js  c++  java
  • 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
    %s
    ", "以下是可翻译的语言种类,请输入代表数字", "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))
    }
    

    运行结果

    运行结果

    缺点

    1. 违背了开闭原则,以后还可能有法语、俄语、阿拉伯语等其他翻译器,每一次添加翻译器都要在客户端代码增加对应的switch分支,维护成本高。倘若还有不止一处调用了创建逻辑,还要维护多处代码。
    2. 违背了单一职责原则,客户端处理类的职责应该只是负责接收用户的输入并将其打印,现在还负责翻译类的创建逻辑,导致这个类的职责过多。

    改善

    为了解决每次新增翻译类都要修改客户端的问题,我们引入一个很重要的设计原则,可以说每种设计模式都遵循着这个设计原则。

    设计原则:找出用中可能需要变化之处,并把它们独立出来,不要和那些不需要变化的代码混在一起。

    这样的话,每次当新的需求来临,我们只会改动到那些需要变化的地方,而不变的地方就不会被改动影响到。

    显然,翻译应用中容易变化的地方是生成翻译类的逻辑,因此我们把这部分职责抽出来,把它交给另外一个类去做(一般是一个静态方法),这个类就叫翻译工厂。而客户端再需要生成翻译类实例时,仅需调用翻译工厂提供的方法即可。就算以后翻译工厂会提供更多的翻译类,也不会修改到客户端的代码,因此也就有了我们的现在的简单工厂模式。

    简单工厂模式(Simple Factory Pattern)

    又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

    UML类图

    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
    %s
    ", "以下是可翻译的语言种类,请输入代表数字", "1:德语、2:英语、3:日语")
    	fmt.Scanln(&lan)
    
    	fmt.Println("请输入要翻译成中文的文本:")
    	var inputWords string
    	fmt.Scanln(&inputWords)
    
        //客户端只关注如何获取翻译类,而不用关注创建翻译类的细节
    	translator:=CreateTranslator(lan)
    
    	fmt.Println(translator.Translate(inputWords))
    }
    

    优点

    1. 将客户端和创建产品实例解耦开来,使客户端只需要关注如何获取实例。
    2. 符合单一职责。

    缺点

    1. 增加新翻译类时还是需要改动工厂类,没有符合开闭原则。

    应用场景

    当在代码里看到switch的时候,就应该思考是否用简单工厂模式。

    作者:胡金生
    出处:www.aprilboy.com
    版权所有,欢迎保留原文链接进行转载:)

    www.aprilboy.com
  • 相关阅读:
    Node.js系列基础学习-----回调函数,异步
    Git版本控制工具学习
    大三下学期计划
    JavaScript基础插曲---apply,call和URL编码等方法
    JavaScript基础插曲-练习
    Jira内存调整
    IntelliJ IDEA 简单设置
    介绍一个国内强大的API接口文档写作网站showdoc
    使用IntelliJ IDEA 配置Maven(入门)
    Jira内存调整
  • 原文地址:https://www.cnblogs.com/SpiderShrimp/p/10621896.html
Copyright © 2011-2022 走看看