面向对象 Object-Oriented:Design Patterns:工厂设计模式:简单工厂模式、工厂模式、抽象工厂模式

最近面试的时候被问到了设计模型-工厂模式,虽然是老掉牙的问题了,但又回头翻了翻书,温故知新吧!

就像学了C++中类的基础知识就应该让自己习惯写出一个“较好”的类来:设计一个较好的类,会通过类来管理资源,即RAII(Resource Acquisition Is Initialization)原则,考虑类的复制构造函数,重载赋值=操作符等,会考虑C++中的内存管理、防止内存泄漏等问题。那么好了,设计好一个类,然后呢?我们的程序需要组合多个类,这些类需要协调工作才能完美地解决问题!

OO(Object-Oriented)设计模式就是针对一些经典场景下,解决面向对象程序设计特定问题的类间关系的设计模板!

通过类之间的关系(继承、组合、聚合、依赖),以体现OO的优势,使得程序的设计满足开放-封闭的原则(对扩展开放接口,对修改封闭:即不希望对程序做大的改动)

一下代码与类图参考文献[1]程杰. 大话设计模式[M]. 清华大学出版社, 2007.

复习基本的UML图:

概念:

  1. 继承
  2. 组合(对象同生命周期,具体在类中怎写?)
  3. 聚合(对象不同生命周期,二者的创建与销毁独立)(组合和聚合应该是用类嵌套(对象成员)与类指针成员的方式实现)
  4. 依赖(仅仅是一个类的对象会使用另外一个类对象的方法,二者连嵌套关系都没有)

下面针对简单工厂模式、工厂模式、抽象工厂模式,以OO的思想写一些实现计算器的类,通过OO的三大特性:封装、继承、多态,降低程序的耦合度,用设计模式的模板方法使得写出来的代码易于修改(扩充)、复用!

题目:利用面向对象语言实现一个计算器控制台程序,要求输入两个数及运算符,输出运算结果!

计算器版本1:

// calculator1.cpp : 定义控制台应用程序的入口点。
//
//最Low版本的计算器实现两个数相加!
#include "stdafx.h"
#include<iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
	double A, B, result;
	char op;
 
	cout << "请输入数字A,按回车键确认输入:" << endl;
	cin >> A;
 
	try{
		if (cin.fail())
			throw 1;
	}
	catch (int)
	{
		cin.clear();
		cin.sync();
		cout << "输入错误" << endl;
 
	}
	cout << "请输入运算符(+,-,*,/),按回车键确认输入:" << endl;
	cin >> op;
	cout << "请输入数字B,,按回车键确认输入:" << endl;
	cin >> B;
 
	if (op == '+')
		result = A + B;
	if (op == '-')
		result = A - B;
	if (op == '*')
		result = A*B;
	if (op == '/')
		result = A / B;
 
	cout << A << op << B << "=" << result << endl;
	
	/*
请输入数字A,按回车键确认输入:
1
请输入运算符(+,-,*,/),按回车键确认输入:
/
请输入数字B,,按回车键确认输入:
0
1/0=1.#INF
请按任意键继续. . .
	*/
	
	system("pause");
	return 0;
}
 

计算器版本2:

// calculator2.cpp : 定义控制台应用程序的入口点。
//计算器版本2
 
#include "stdafx.h"
#include<iostream>
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
	double NumberA, NumberB, result;
	char op;
 
	while (1)
	{
		cout << "请输入数字A,按回车键确认输入:" << endl;
		cin >> NumberA;
		try{
			if (cin.fail())
				throw 1;
		}
		catch (int)
		{
			cin.clear();
			cin.sync();
			cout << "输入错误,请重新输入:" << endl;
			continue;
		}
 
		break;
 
	}
 
	while (1)
	{
		cout << "请输入运算符(+,-,*,/),按回车键确认输入:" << endl;
		cin >> op;
		try
		{
			if (cin.fail())
				throw 1;
		}
		catch (int)
		{
			cin.clear();
			cin.sync();
			cout << "输入错误,请重新输入:" << endl;
			continue;
		}
		break;
	}
 
	while (1)
	{
		cout << "请输入数字B,按回车键确认输入:" << endl;
		cin >> NumberB;
		try{
			if (cin.fail())
				throw 1;
		}
		catch (int)
		{
			cin.clear();
			cin.sync();
			cout << "输入错误,请重新输入:" << endl;
			continue;
		}
		break;
	}
 
	try{
		switch (op)
		{
		case'+':
			result = NumberA + NumberB;
			break;
		case'-':
			result = NumberA - NumberB;
			break;
		case'*':
			result = NumberA*NumberA;
			break;
		case'/':
			if (NumberB == 0)
			{
				throw 1;
			}
			else
			{
				result = NumberA / NumberB;
			}
			break;
		default:
			;
		}
		cout << NumberA<<op<<NumberB<<"=" << result << endl;
	}
	catch (int )
	{
		cout << "除数不能为零!" << endl;
		//exit(1);
	}
	
	system("pause");
	return 0;
}

上面的版本只实现了加法和减法,要求程序可扩展,以后能实现对乘法、除法、幂次方、取余数等的功能扩展。

1.简单工厂模式

// SimpleFactory2.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include<iostream>
using namespace std;
 
class Operation
{
private:
	double NumberA;
	double NumberB;
public:
	virtual double getResult() = 0;/*这里必须是纯虚函数!!(纯虚函数与抽象类!)*/
	void setNumberA(double a)
	{
		NumberA = a;
	}
	void setNumberB(double b)
	{
		NumberB = b;
	}
	double getNumberA()
	{
		return NumberA;
	}
	double getNumberB()
	{
		return NumberB;
	}
};
 
class OperationAdd :public Operation
{
public:
	double getResult()/*不同的Operation子类具体实现纯虚函数getReuslt()这个接口!*/
	{
		return getNumberA() + getNumberB();
	}
 
};
 
class OperationSub :public Operation
{
public:
	double getResult()
	{
		return getNumberA() - getNumberB();
	}
};
 
class SimpleFactory
{
private:
	Operation* oper = nullptr;
public:
	Operation* creationOperation(char op)
	{
		switch (op)
		{
		case '+':
			oper = new OperationAdd();
			break;
		case '-':
			oper = new OperationSub();
			break;
 
		default:
			;
		}
		return oper;//oper是指向堆对象的指针,不是栈对象,所有可以返回!
	}
};
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	/*计算器类的客户端*/
	Operation* oper;/*多态的实现,基类指针指向不同类型的子类!在调用方法是是调用子类的方法!*/
	SimpleFactory simpleFacory;
	oper = simpleFacory.creationOperation('+');
	oper->setNumberA(1);
	oper->setNumberB(2);
	double result = oper->getResult();
	cout << "result=" << result << endl;
	getchar();
 
 
	return 0;
}
 

2.工厂模式

// Factory.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include<iostream>
using namespace std;
 
 
class Operation
{
private:
	double NumberA;
	double NumberB;
public:
	virtual double getResult() = 0;/*这里必须是纯虚函数!!(纯虚函数与抽象类!)*/
	void setNumberA(double a)
	{
		NumberA = a;
	}
	void setNumberB(double b)
	{
		NumberB = b;
	}
	double getNumberA()
	{
		return NumberA;
	}
	double getNumberB()
	{
		return NumberB;
	}
};
 
class OperationAdd :public Operation
{
public:
	double getResult()/*不同的Operation子类具体实现纯虚函数getReuslt()这个接口!*/
	{
		return getNumberA() + getNumberB();
	}
 
};
 
class OperationSub :public Operation
{
public:
	double getResult()
	{
		return getNumberA() - getNumberB();
	}
};
 
class IFactory
{
public:
	virtual Operation* CreateOperation() = 0;
};
 
class AddFactory :public IFactory
{
public:
	Operation* CreateOperation()
	{
		return new OperationAdd();
	}
};
 
class SubFactory :public IFactory
{
public:
	Operation* CreateOperation()
	{
		return new OperationSub();
	}
};
 
 
 
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	IFactory* operationFactory = new AddFactory();
	Operation* oper = operationFactory->CreateOperation();
	oper->setNumberA(1);
	oper->setNumberB(2);
	double result = oper->getResult();
	cout << "retult=" << result << endl;
	getchar();
	return 0;
}
 

2.工厂方法

工厂方法(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到其子类。

工厂方法设计模式实现时,客户端需要决定实例化哪一个工厂类来实现运算类,选择判断的问题依然存在,只不过是从简单工厂里的内部逻辑判断(switch语句)移到了客户端代码来进行。要想加运行类的具体产品,本来是要修改工厂类的,现在是修改客户端!

面向对象OO,设计模式

猜你喜欢

转载自blog.csdn.net/m0_37357063/article/details/81541853