1.接口
从语法上看:
对于C++而言,是一种特殊的抽象类,是一个纯虚的类。
从软件设计的意义上来说:
接口定义了类的外观,相当于一种契约,根据外部应用的功能,约定了实现类应该要实现的功能。
软件开发中,永恒的主题是“变化”,而接口就是封装变化,即隔离变化,只要接口不变,内部实现的变化就不会影响外部应用,从而使得系统具有好的扩展性和可维护性
2.没有设计模式的写法
UML:
代码:
//不用设计模式实现
#include <iostream>
#include <string>
using namespace std;
class API
{
public:
virtual void test(string s) = 0;
protected:
API(){} //屏蔽构造函数,体现接口
};
class Impl:public API
{
public:
void test(string s) override
{
cout << "Impl的test函数执行:" <<s<< endl;
}
};
//测试客户端
int main()
{
API* pAPI = new Impl();
pAPI->test("测试运行");
system("pause");
return 0;
}
这种写法的问题:
封装性被破坏掉了:客户端在使用的过程中既知道存在Impl类,也知道它当中的test方法完成功能,即使得客户端已经知道了内部结构的细节
3.简单工厂实现
(1)简单工厂的定义
提供一个创建对象实例的功能,而无需关心其内部具体实现,被创建的类可以是接口,抽象类,具体的类
(2)UML
(3)代码
#include <iostream>
#include <string>
using namespace std;
class API
{
public:
virtual void test(string s) = 0;
protected:
API(){} //屏蔽构造函数,体现接口
};
class ImplOne:public API
{
public:
void test(string s) override
{
cout << "从数据库中读入:" <<s<< endl;
}
};
class ImplTwo :public API
{
public:
void test(string s) override
{
cout << "从文本文件中读入:" << s << endl;
}
};
class Factory
{
public:
static API* createAPI(int type)
{
API* pAPI = nullptr;
if (type == 1)
{
pAPI = new ImplOne();
}
if (type == 2)
{
pAPI = new ImplTwo();
}
return pAPI;
}
};
//测试客户端
//示例接口规范书写
//传入参数1:可以实现从数据库中读入
//传入参数2:可以实现从文本文件中读入
int main()
{
API* pAPI = Factory::createAPI(1);
pAPI->test("简单工厂方法重构");
pAPI = Factory::createAPI(2);
pAPI->test("简单工厂方法重构");
system("pause");
return 0;
}
运行结果:
(4)分析
这段代码中就是将new对象的工作剥离出来放到Factory当中,这样实现了ImplOne和ImplTwo的解耦和
客户端用户只知道API接口和Factory,不知道ImplOne和ImplTwo的存在,客户端不知道你源代码怎么实现,他只能根据你的接口规范来调用
另外在比如说想更改ImplOne和ImplTwo中的内容时,客户端中的接口不变,我们只需要更改它们各自类当中的内容,而不需要更改客户端,这也就是隔离变化,而这种变化的隔离也就是通过Factory类来实现
4.简单工厂在实际应用中的有价值的扩展
问题需求:
上述代码中还需要传入参数1和2来创建对象,我们想动态地,任意地创建工厂,从而实现ImplOne和ImplTwo的完全解耦和
代码:
待更新