在熟悉工厂模式之前,首先要明白在写c++程序前的六大准则
- 开闭原则:不修改已存在代码,只添加代码。
- 依赖倒转原则:不用具体类解决问题,使用抽象类。(隔离变化,封装变化)
- 里氏代换原则:任何基类可以出现的地方,子类一定可以出现。
- 接口隔离原则:使用接口抽离逻辑,目的也是为了降低耦合。
- 迪米特法则:类和类之间不发生相互作用,使得功能互相独立。
- 单一职责原则:一个类只有一个可以引起它变化的原因
工厂模式分为三类,以下将会介绍简单工厂和工厂模式
简单工厂
只有一个抽象类,所以它存在的缺点是工厂类中集中了所有的创建逻辑,高内聚的问题并没有得到解决。当需要增加产品时,工厂类需要进行修改,违背了六大准则第一条开闭原则,没有良好的扩展性。但它存在并非偶然,优点是对外隐藏了内部的创建,有利于整个结构的优化。
例:四则运算
四则运算,说明了一共有四种不同的运算方式,当你选择某一种时,每个都是不同的逻辑。然而四则运算的前提是需要一个计算器。所以,简单工厂模式将会根据你输入的运算符,去执行不同的逻辑。代码如下
#include
#include
class Cal//计算器类
{
public:
virtual void getResult(int a, int b) = 0;
};
class Add :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a + b << std::endl;
}
};
class Sub :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a - b << std::endl;
}
};
class Mul :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a * b << std::endl;
}
};
class Div :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a / b << std::endl;
}
};
class EasyFactory
{
public:
Cal* createobj(char op)//定义父类指针,访问子类函数
{
switch (op)
{
case'+':
{
return new Add();
break;
}
case'-':
{
return new Sub();
break;
}
case'*':
{
return new Mul();
break;
}
case'/':
{
return new Div();
break;
}
}
}
};
int main()
{
int a = 8, b = 2;
char op;
std::cin >> op;
Cal* cal = EasyFactory().createobj(op);//通过不同的运算符获取返回不同对象
cal->getResult(a,b);
return 0;
}
工厂模式
回想一下刚才的四则运算,如果要增加一个取余的运算,应该如何增加呢?
很明显首先要定义一个取余类继承Cal类。其次在EasyFactory中需要增加一个case节点,很明显改变了这个EasyFactory类,违反了开闭原则。所以我们需要将EasyFactory类也进行隔离,故产生了工厂模式。代码如下
#include <iostream>
#include <string>
class Cal//计算器类
{
public:
virtual void getResult(int a, int b) = 0;
};
class Add :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a + b << std::endl;
}
};
class Sub :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a - b << std::endl;
}
};
class Mul :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a * b << std::endl;
}
};
class Div :public Cal
{
public:
void getResult(int a, int b)
{
std::cout << a / b << std::endl;
}
};
class AbsFactory
{
public:
virtual Cal* createobj() = 0;
};
class AddFactory :public AbsFactory
{
public:
Cal* createobj()
{
return new Add();
}
};
class SubFactory :public AbsFactory
{
public:
Cal* createobj()
{
return new Sub();
}
};
class MulFactory :public AbsFactory
{
public:
Cal* createobj()
{
return new Mul();
}
};
class DivFactory :public AbsFactory
{
public:
Cal* createobj()
{
return new Div();
}
};
int main()
{
int a = 8, b = 2;
char op;
Cal* cal;
AbsFactory* factory = nullptr;
std::cin >> op;
switch (op)
{
case'+':
{
factory = new AddFactory();
break;
}
case'-':
{
factory = new SubFactory();
break;
}
case'*':
{
factory = new MulFactory();
break;
}
case'/':
{
factory = new DivFactory();
break;
}
default:
{
break;
}
}
cal = factory->createobj();
cal->getResult(a,b);
return 0;
}