接口学习一,简单的接口实现对比
/**
* @brief 假设要实现一个登陆功能,登陆方式可以是用户名-密码、用户名-指纹、dna三种方式
* @note 现在比对两种编程方式的优劣
* 方式一:每个功能对应一个接口,但实现是集中的
* 方式二:一个接口定义三个功能,实现也是集中的
* @date 2021/01/16
* @author lee
*/
#include <iostream>
#include <string>
using namespace std;
/*************************************************************************************
* @brief 方式一
*************************************************************************************/
/**
* @brief 密码登陆接口
*/
class IPassword
{
public:
virtual int loginPasswd(const string &loginName, const string &password) = 0;
protected:
virtual ~IPassword() {}
};
/**
* @brief 指纹登陆接口
*/
class IFInger
{
public:
virtual int loginFinger(const string &loginName, const string &finger) = 0;
protected:
virtual ~IFInger() {}
};
/**
* @brief dna登陆接口
*/
class IDna
{
public:
virtual int loginDna(const string &loginDna) = 0;
protected:
virtual ~IDna() {}
};
class CLogin : public IPassword, public IFInger, public IDna
{
public:
CLogin();
virtual ~CLogin();
virtual int loginPasswd(const string &loginName, const string &password);
virtual int loginFinger(const string &loginName, const string &finger);
virtual int loginDna(const string &loginDna);
};
CLogin::CLogin() {}
CLogin::~CLogin() {}
int CLogin::loginPasswd(const string &loginName, const string &password)
{
cout << "login Password" << endl;
}
int CLogin::loginFinger(const string &loginName, const string &finger)
{
cout << "login finger" << endl;
}
int CLogin::loginDna(const string &loginDna)
{
cout << "login dna" << endl;
}
/*************************************************************************************
* @brief 方式二
*************************************************************************************/
/**
* @brief 基类---登录接口声明
*/
class ILogin2
{
public:
virtual int loginPasswd(const string &loginName, const string &password) = 0;
virtual int loginFinger(const string &loginName, const string &finger) = 0;
virtual int loginDna(const string &loginDna) = 0;
// virtual int loginFace(const string &faceCharacter) = 0; // 假设这里新增了功能,而没有被派生类实现,会引发错误导致程序运行失败
protected:
virtual ~ILogin2() {}
};
/**
* @brief 派生类---实现登录接口
*/
class CLogin2 : public ILogin2
{
public:
CLogin2();
virtual ~CLogin2();
virtual int loginPasswd(const string &loginName, const string &password);
virtual int loginFinger(const string &loginName, const string &finger);
virtual int loginDna(const string &loginDna);
};
CLogin2::CLogin2() {}
CLogin2::~CLogin2() {}
int CLogin2::loginPasswd(const string &loginName, const string &password)
{
cout << "method 2, login password" << endl;
}
int CLogin2::loginFinger(const string &loginName, const string &finger)
{
cout << "method 2, login finger" << endl;
}
int CLogin2::loginDna(const string &loginDna)
{
cout << "method 2, login dna" << endl;
}
int main()
{
// 方式一
IPassword *loginPWD = new CLogin();
IFInger *loginFinger = new CLogin();
IDna *loginDna = new CLogin();
string loginName = "Jhon";
string pwd = "123";
string finger = "qaz";
string dna = "Dna";
loginPWD->loginPasswd(loginName, pwd);
loginFinger->loginFinger(loginName, finger);
loginDna->loginDna(dna);
// 方式二
ILogin2 *login2 = new CLogin2();
login2->loginPasswd(loginName, pwd);
login2->loginFinger(loginName, finger);
login2->loginDna(dna);
return 0;
}
两种方式优劣对比
-
采用方式二,提供给用户的是ILogin2.h,而CLogin2.h/cpp的实现封装在库里,因为与登录相关的功能都集中在接口ILogin2中当需要新增功能,例如加一个“虹膜登录”功能或“人脸识别登录”功能,首先接口文件ILogin2.h需要新增,而对于实现文件CLogin2.h/cpp而言,也需要实现接口新增的功能,修改的地方有两个
-
采用方式一,提供给用户的是三个独立的接口(密码、指纹、dna),而实现都是通过一个CLogin.h/cpp实现,新增功能的时候,需要在源文件中继承新功能接口,并且提供新功能实现,而对于用户而言,只是添加了一个新的功能接口头文件。
-
①假设采用方式一(直接修改接口头文件),在ILogin2.h中新增了一个函数loginFace(),如果程序链接的库里没有实现这个新函数,整个程序就跑不了,因为原来#include "Ilogin2.h"的地方会引入了一个未实现的纯虚函数loginFace()。
-
②假设采用方式二(增加新的接口头文件),新增的接口头文件是专门声明新函数loginFace()的,此时如果程序链接的库里没有实现,在原来的程序不改动的情况下,不会影响原程序的使用。(这个应该就是好处了吧)