前面的文章C++设计模式之单例模式详解(懒汉模式、饿汉模式、双重锁)讲了设计模式中最简单的单例模式,有需要的可以点击链接去看看,用C++详细的实现了单例模式包括懒汉式、饿汉式、双重锁等方式。今天讲讲另外一种简单的设计模式:简单工厂模式。
在实际的工作场景中,程序员写的代码实现基本功能仅仅是第一步,更重要的是代码的可维护性、可复用性和灵活性。对于C++程序员,我们要想的如何利用面向对象的编程思想,用好C++的三大特性(封装、继承和多态)来写出符合要求的代码,这点需要我们在实际工作中不断思考、探索。下面具体讲讲今天的主题:简单工厂模式,说白了就是先给出一个基类,然后利用多态实现几个派生类实现不同的操作,另外再设置一个单独的工厂类来做创造具体实例的过程,这样如果需要新增功能,只需在工厂类中添加语句,并新衍生一个派生类即可,减少了代码的复用,对于修改也不会影响到其他的操作,灵活性强。talk is cheap,show me your code:
#include
using namespace std;
/*简单工厂模式(工厂类中作判断):先有一个抽象类(父类),然后子类继承父类并重写虚函数,最后再有一个工厂类,根据传入类型返回不同类型的对象*/
enum CTYPE{huawei,xiaomi,vivo,oppo};//枚举
class Phone {//父类
public:
virtual void func() = 0;//纯虚函数(抽象类,不能实例化对象,子类如果不重写虚函数,也是抽象类)
};
class HUAWEI :public Phone {
public:
void func()//重写虚函数(必须返回类型、函数名、参数列表与父类虚函数一模一样)
{
cout << "生产华为手机" << endl;
}
};
class XIAOMI :public Phone {
public:
void func()//重写虚函数(必须返回类型、函数名、参数列表与父类虚函数一模一样)
{
cout << "生产小米手机" << endl;
}
};
class OPPO :public Phone {
public:
void func()//重写虚函数(必须返回类型、函数名、参数列表与父类虚函数一模一样)
{
cout << "生产oppo手机" << endl;
}
};
class VIVO:public Phone {
public:
void func()//重写虚函数(必须返回类型、函数名、参数列表与父类虚函数一模一样)
{
cout << "生产vivo手机" << endl;
}
};
class Factory {
//工厂类(简单工厂违背了开放封闭原则,扩展需要修改工厂类)
public:
Phone* get_phone(enum CTYPE type)
{
//根据传入的符号实例化不同的对象
switch (type)
{
case huawei:
return new HUAWEI();
break;
case xiaomi:
return new XIAOMI();
break;
case vivo:
return new VIVO();
break;
case oppo:
return new OPPO();
break;
default:
return nullptr;
break;
}
}
};
//操作类
class Operation {
private:
int numberA;
int numberB;//两个私有数据
public:
//四个公有方法来设置和获取数据
int getNumberA()
{
return numberA;
}
void setNumberA(int value)
{
numberA=value;
}
int getNumberB()
{
return numberB;
}
void setNumberB(int value)
{
numberB = value;
}
virtual int getresult() = 0;//纯虚函数
};
//加法类
class Add :public Operation {
public:
int getresult()
{
return getNumberA()+ getNumberB();
}
};
//减法类
class Sub:public Operation {
public:
int getresult()
{
return getNumberA() - getNumberB();
}
};
//除法类
class Div :public Operation {
public:
int getresult()
{
if (getNumberB() == 0)
{
cout << "除数不能为0" << endl;
return 0;
}
return getNumberA()/getNumberB();
}
};
//乘法类
class Prod :public Operation {
public:
int getresult()
{
return getNumberA() * getNumberB();
}
};
//用一个单独的类来做这个创造实例的过程,这就是工厂(简单工厂不符合开放封闭原则,破坏了对修改关闭的原则)
class Factoryoper {
public:
Operation* getresult(char c)
{
switch (c)
{
case '+':
return new Add();
case '-':
return new Sub();
case '/':
return new Div();
case '*':
return new Prod();
default:
return nullptr;
break;
}
}
};
int main()
{
Factory F;
//根据传入的参数不同,生成不同的对象,调用不同的方法(像工厂一样)
Phone* xm = F.get_phone(xiaomi);
xm->func();
Phone* hw = F.get_phone(huawei);
hw->func();
Phone* vo = F.get_phone(vivo);
vo->func();
Phone* op = F.get_phone(oppo);
op->func();
//根据传入的参数不同,生成不同的对象,调用不同的方法(像工厂一样)
Factoryoper Foper;
Operation* add = Foper.getresult('+');
add->setNumberA(10);
add->setNumberB(20);
int res=add->getresult();
cout << res << endl;
Operation* div = Foper.getresult('/');
div->setNumberA(30);
div->setNumberB(15);
cout << div->getresult() << endl;
Operation* prod = Foper.getresult('*');
prod->setNumberA(15);
prod->setNumberB(20);
cout << prod->getresult() << endl;
system("pause");
return 0;
}
以上代码实现了两个不同的简单工厂案例,上面注释中添加了一个关于虚函数相关的注意事项,主要是提醒自己。简单工厂模式存在的最主要问题是不符合开放封闭的原则,因为如果增加新的实例,需要在工厂类中修改才行,违背了对修改关闭的原则。下期会介绍另外一种设计模式:工厂方法模式,它将实例化的过程下放到客户端去,这样就能解决简单工厂违背设计原则的问题了。
好了,今天的就到这里,欢迎大家交流指正。