工厂设计模式:

  顾名思义,该模式是用来生产对象的。在面向对象的设计模式中,万物皆对象,若使用new来创建对象,就会对该对象产生强耦合,假如我们需要更换该对象,那么使用该对象的对象都需要进行修改,这显然违背了开闭原则(OCP)。如果我们使用工厂来产生对象,我们只需要与这个工厂打交道就可以了,无需关心具体的对象,达到解耦的目的。

  接下来我们从实际的案例出发,从无工厂到有工厂的区别。

eg

有一个销售管理系统支持多种支付方式,如现金支付,信用卡支付,代金券支付等。

在设计过如果不使用简单工厂模式,可能会存在如下的支付方式。

void pay(string pay_type)
{
    if(pay_type==现金)
    {
    	现金支付处理手段
    }
    else if(pay_type==信用卡)
    {
    	信用卡支付处理
    }
    else  if(pay_type==代金券)
    {
    	代金券处理
    }
	........
}

简单工厂模式包含三个角色:

  1. 工厂角色(Factory)

  2. 抽象产品角色(Product)

  3. 具体产品角色(ConcreteProduct)

简单工厂模式优缺点:

  1. 由代码可以看出,虽然简单工厂模式一定程度上减少了因需求变更而导致的代码更改,但是实际仍违背了OCP原则。
  2. 所以简单工厂模式只适合产品对象相对较少,且产品固定的需求,对产品变化无常的需求来说显然不适合。

使用:

//	将各种支付方式写成统一的抽象方法,为各种支付方式提供统一的接口
class AbstractPay
{
public:
	virtual void pay() = 0;
};

//	将每种支付方式封装在一个独立的类中,各个支付方式类相对独立修改其一对于其他类没有任何影响,
//	这些独立的支付方式类充当具体的产品类角色。是抽象类的派生类
class CashPay :public AbstractPay
{
public:
	void pay()
	{
		cout << "现金支付" << endl;
	}
};
 
class CreditcardPay :public AbstractPay
{
public:
	void pay()
	{
		cout << "信用卡支付" << endl;
	}
};

//	将针对于个种支付方式的对象的创建封装成一个统一的方法中,即:工厂化。
class PayMethodFactory
{
public:
	AbstractPay* getPayMethod(string type)
	{
		if (type == "cash")
		{
			return new CashPay();
		}
		else
		{
			return new CreditcardPay();
		}
	}
};


int main()
{
	PayMethodFactory *pmf = new PayMethodFactory(); 
    //基类指针指向带有虚函数的派生类对象形成多态
	AbstractPay* p = pmf->getPayMethod("cash");
	//假定现在是现金支付
	p->pay();
	system("pause");
	return 0;
}

工厂方法设计模式:

披萨项目需求变更,客户点披萨时可以点不同口味的披萨。

  工厂方法模式的优缺点:

  1. 让父类的实现延迟到子类中去,减少判断。
  2. 换汤不换药,和简单工厂模式类似,一般适用于产品对象相对较少,且产品固定的需求。
  3. 工厂方法一定程度上减轻了工厂的职责,将职责细化,避免工厂类无法正常运行而导致程序崩溃。

eg:

class Operation {
public:
		Operation():mNumA(0),mNumB(0){};
		virtual ~Operation(){};
		virtual double getResult() {
			double result = 0;
			return result;
		}

	double mNumA;
	double mNumB;
};
class OperationAdd:public Operation{
public:
	double getResult(){
		double result = 0;
		result = mNumA + mNumB;
		return result;
	}
	OperationAdd();
	virtual ~OperationAdd();
};
 
class OperationSub:public Operation{
public:
	double getResult(){
		double result = 0;
		result = mNumA - mNumB;
		return result;
	}
 
   	OperationSub();
	virtual ~OperationSub();
};
//---------------------------------

class IFactory {
public:
	IFactory();
	virtual ~IFactory();
	virtual Operation* CreateOperation() = 0;
};

class AddFactory : public IFactory{
public:
	AddFactory();
	virtual ~AddFactory();
	Operation* CreateOperation(){
		return new OperationAdd();
	}
 
};
 
class SubFactory : public IFactory{
public:
	SubFactory ();
	virtual ~SubFactory ();
	Operation* CreateOperation(){
		return new OperationSub();
	}
 
};
//---------------------------------
//use
	IFactory *f =new AddFactory();
	Operation *oper =f->CreateOperation();
	oper->mNumA=1;
	oper->mNumB=2;
	cout<< oper->getResult()<<endl;