[设计模式、C++、go]简单工厂模式

简单工厂

介绍

简单工厂模式并不是一个标准的设计模式,但是它十分的简单而且很常用。
其定义:
提供一个创建对象实例的功能,而无需关心其具体实现。被创建实例的类型可以是接口,抽象类,也可以是具体的类。

意图: 避免让模块外部知道模块内部的具体实现。
主要代码:
在模块内部新建一个类,外部应用可以通过这个类来获取相应的对象,操作其方法。

类图:

在这里插入图片描述
Client: 即外部应用
Factory: 即我们在模块内部新建的那个类,可以给Client使用
Api: 接口,封装有Client要使用的方法;在go中就是interface ;在C++中可以是一个纯虚类(即有纯虚函数,不能实例化出对象的类)
ImplA,ImplB : 具体实现Api的类

代码实现

我们在模块内部实现一个 计算器(能够完成 + - * \ ) 功能,外部调用工厂类进行计算

C++

简单工厂代码:
enum OperatorType{
	ADD=0,
	SUB,
	MUL,
	DIV
};

//纯虚函数类即类图当中的Api  
//有一个获取结果的函数GetResult
class Operator{
public:
	int numA;
	int numB;
	virtual int GetResult() = 0;
};
//具体实现 加,减,乘,除的类
class OperatorAdd:public Operator{
public:
	int GetResult(){
		return numA + numB;
	}
};
class OperatorSub :public Operator{
public:
	int GetResult(){
		return numA - numB;
	}
};
class OperatorMul :public Operator{
public:
	int GetResult(){
		return numA * numB;
	}
};
class OperatorDiv :public Operator{
public:
	int GetResult(){
		if (numB == 0){
			printf("除数不能为0\n");
		}
		return numA / numB;
	}
};
//简单工厂类
class OperatorFactory{
public:
//本代码中将此方法定义为static,可以不用实例化简单工厂对象,调用此方法
	static Operator* CreateOpator( OperatorType op){
		if (op == ADD){
			return new OperatorAdd;
		}else if (op == SUB){
			return new OperatorSub;
		}else if (op == MUL){
			return new OperatorMul;
		}else if (op == DIV){
			return new OperatorDiv;
		}

		return nullptr;
	}

};

外部调用:
int main(){

	Operator * add = OperatorFactory::CreateOpator(ADD);
	add->numA = 1;
	add->numB = 1;
	cout<<add->GetResult()<<endl;
	Operator * sub = OperatorFactory::CreateOpator(SUB);
	sub->numA = 1;
	sub->numB = 1;
	cout << sub->GetResult() << endl;
	Operator * mul = OperatorFactory::CreateOpator(MUL);
	mul->numA = 1;
	mul->numB = 1;
	cout << mul->GetResult() << endl;
	Operator * div = OperatorFactory::CreateOpator(DIV);
	div->numA = 1;
	div->numB = 1;
	cout << div->GetResult() << endl;
	return 0;
}

go

简单工厂代码:
package SimpleFactory
import(
   "errors"
)
//接口 ,定义外部应用调用的方法即类图中的Api
type Result interface{
     GetResult(a,b int)(int,error)
}
//具体的实现类,积累图中的ImpleA,B...
type operatorAdd struct{
}

func (o *operatorAdd)GetResult(a,b int)(int,error){
     return a+b,nil
}
type operatorSub struct{

}
func (o *operatorSub)GetResult(a,b int)(int,error){
     return a-b,nil
}
type operatorMul struct{

}
func (o *operatorMul)GetResult(a,b int)(int,error){
     return a*b,nil
}
type operatorDiv struct{
}
func (o *operatorDiv)GetResult(a,b int)(int,error){
     if b==0{
       return 0,errors.New("除数不能为0");
     }
     return a/b,nil
}
//简单工厂类
type OperatorFactory struct{

}
func (o *OperatorFactory)CreateOperator(str string)Result{
      if str=="+" {
           return &operatorAdd{}
      }else if str=="-" {
           return &operatorSub{}
      }else if str=="*" {
           return &operatorMul{}
      }else if str=="\\" {
           return &operatorDiv{}
      }
      return nil
}

外部调用:
import(
   "fmt"
   ss "SimpleFactory"
)

func main(){
   var opt ss.OperatorFactory
   add:=opt.CreateOperator("+")
   result,_ := add.GetResult(1,1)
   fmt.Println(result)
   sub:=opt.CreateOperator("-")
   result,_ = sub.GetResult(2,1)
   fmt.Println(result)
   mul:=opt.CreateOperator("*")
   result,_ = mul.GetResult(3,1)
   fmt.Println(result)
   div:=opt.CreateOperator("\\")
   result,_ = div.GetResult(4,1)
   fmt.Println(result)
}

优缺点

优点:

  1. 帮助封装
    能够帮助我们实现组件的封装,让外部能够真正的面向接口编程
  2. 解耦
    通过简单工厂模式,实现了外部应用和具体实现类的解耦
    外部应用不知道具体有谁来实现,也不知道具体是如何实现的,客户端只是通过工厂来获取它需要的接口对象
    缺点:
    代码扩展性不好
    倘若我们想在上面的计算器中增加一个求x^y的计算方法,就需要修改工厂类,倘若具体实现类过多,那么if-else if的分支也会变得庞大无比.

应用场景

如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无须关心具体的实现。
如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多的、不相关的对象,可以把对外创建对象的职责集中到个简单工厂来,从而实现集中管理和控制。

扩展:

面对简单工厂代码扩展性问题:我们可以采用读取配置文件的方式来解决,增加了具体实现类,我们只需要修改配置文件即可

参考:
《研磨设计模式》、《大话设计模式》

如果本篇博客有任何错误和建议,欢迎伙伴们留言哦
此外,

可以点个赞,留下你的足迹哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值