SimpleFactory模式

在面向对象系统设计中经常可以遇到以下的两类问题:

1、为了提高内聚和降低耦合,我们经常会抽象出一些类的公共接口以形成抽象基类或接口。这样我们可以通过声明

     一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的一个问题就是n多的子类继承

    自抽象基类,我们不得不在每次要用到的子类的地方就编写诸如new xxx;这样的代码。这里带来两个问题:

     1)客户程序员必须知道实际子类的名称;

    2)程序的扩展性和维护性变得越来越困难

2、还有一种情况就是父类中并不知道具体要实例化哪一个具体的子类。这里的意思就是,假设我们在类A里要使用到

      B,B是一个抽象父类,在A中并不知道具体要实例化哪一个B的子类,但是在类A的子类D中是可以知道的。在

     A中我们没有办法直接使用类似于new xxx的语句,因为根本不知道xxx是什么。


以上两个问题也就引出了Factory模式的两个最重要的功能:

1、定义创建对象的接口,封装了对象的创建;

2、使得具体化类的工作延迟到了子类中。


对于上面给出的两个问题,我们通常使用SimpleFactory模式来解决下面就以大话设计模式上的例子来讲讲吧。大

话上的例子是这样的:用面向对象语言实现一个计算器控制台程序,要求输入两个数和运算符,得到结果。那么这里

我们可以抽象出运算操作以及操作数。于是我声明一个抽象基类Operation具体声明见后面给出的代码然后每一种

运算都当作它的一个子类。接下来我们需要做的就是声明一个工厂类OperationFactory,来生产运算类到这里我们

就解决了第一个问题了,实现代码如下:


#include <iostream>
#include <string>
using namespace std;

class Operation
{
public:
	virtual double GetResult()=0;

	void Set(double x, double y)
	{
		num1 = x;
		num2 = y;
	}
	
protected:
	double num1, num2;
};

class OperationAdd:public Operation
{
public:
	double GetResult()
	{
		double result = 0.0;
		result = num1 + num2;
		return result;
	}
};

class OperationSub:public Operation
{
	double GetResult()
	{
		double result = 0.0;
		result = num1 - num2;
		return result;
	}
};

class OperationMul:public Operation
{
	double GetResult()
	{
		double result = 0.0;
		result = num1 * num2;
		return result;
	}
};

class OperationDiv:public Operation
{
	double GetResult()
	{
		double result = 0.0;
		if (0 == num2)
		{
			cout << "除数不能为0!" << endl;
			return 0.0;
		}
		else
		{
			result = num1 / num2;
			return result;
		}
	}
};

class OperationFactory
{
public:
	static Operation* CreateOperation(string operation)
	{
		Operation* oper = NULL;
		
		if ("+" == operation)
			oper = new OperationAdd();
		else if ("-" == operation)
			oper = new OperationSub();
		else if ("*" == operation)
			oper = new OperationMul();
		else if ("/" == operation)
			oper = new OperationDiv();

		return oper;
	}
};

int main()
{
	Operation* oper;
	oper = OperationFactory::CreateOperation("+");
	oper->Set(10, 15);
	cout << oper->GetResult() << endl;

	system("pause");
	return 0;
}

实现代码中只实现了加减乘除运算,但很显然,只要我们需要添加运算功能的时候,只需声明一个运算符子类继承自

抽象基类Operation并在工厂类中添加一判断分支即可但是这里也不是很完善了,显然工厂类违背了开放-封闭

原则(软件实体可以扩展,但是不可以修改)。每当我们添加运算功能的时候,就必须修改工厂类的判断分支,也就是

说需要对其进行修改。为了解决这个问题,我们可以定义一个抽象基类,创建运算类的接口定义为纯虚函数,定义

如下:


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

之后为每个运算功能添加一个类工厂,继承自上面的抽象基类:


class AddFactory:public IFactory
{
	Operation* CreateOperation()
	{
		return new OperationAdd();
	}
};

class SubFactory:public IFactory
{
	Operation* CreateOperation()
	{
		return new OperationSub();
	}
};

class MulFactory:public IFactory
{
	Operation* CreateOperation()
	{
		return new OperationMul();
	}
};

class DivFactory:public IFactory
{
	Operation* CreateOperation()
	{
		return new OperationDiv();
	}
};

这样每当我们需要添加运算功能的时候,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类

就可以了。当我们要使用某个运算功能的时候,代码如下:


IFactory* operFactory = new AddFactory;
Operation* oper = operFactory->CreateOperation();

oper->Set(15, 30);
cout << oper->GetResult() << endl;



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值