最近开发中用来很多级联的if-else和switch case,在这样的代码中,如果你想增加新的功能,必定会在原来的代码下接着增加if-else或者case,这样不符合“封闭开放原则”,因为修改了自己写好的类。下面介绍下自己优化的思路。
1、典型的switch case场景
#include <stdio.h>
enum class User { //定义三个用户
jiongkai = 0,
sywei = 1,
zj = 2,
};
int main() {
User user = User::jiongkai;
switch (user) //不同的用户,有不同的操作(op)
{
case User::jiongkai:
printf("hello jiongkai\n");//假设操作为简单的if-else
break;
case User::sywei:
printf("hello sywei\n");
break;
case User::zj:
printf("hello Zj\n");
break;
default:
break;
}
}
2、注册回调机制的初步使用
#include <stdio.h>
enum class User {
jiongkai = 0,
sywei = 1,
zj = 2,
};
void JiongKaiOp() {
printf("hello jiongkai\n");
}
void SyweiOp() {
printf("hello sywei\n");
}
void ZjOp() {
printf("hello zj\n");
}
typedef void(*pfunc)();//定义一个函数指针
pfunc PFuncArr[10];//定义个函数指针数组
void Register() {//将swtich case下的每个op独立为一个函数,并把函数指针储存在函数指针数组中
PFuncArr[(int)User::jiongkai] = JiongKaiOp;
PFuncArr[(int)User::sywei] = SyweiOp;
PFuncArr[(int)User::zj] = ZjOp;
}
int main() {
User user = User::jiongkai;
Register();
PFuncArr[(int)user]();//根据user,取出对应的函数指针即可,这样主函数中就不再需要switch case了
}
3、由面向过程到面向对象
#include <stdio.h>
enum class User {
jiongkai = 0,
sywei = 1,
Zj = 2,
};
class ManageUsers {
private:
typedef void(*pfunc)();
pfunc PFuncArr[10];
public:
void Register() {
PFuncArr[(int)User::jiongkai] = JiongkaiOp;
PFuncArr[(int)User::sywei] = syweiOp;
PFuncArr[(int)User::Zj] = zjOp;
}
static void JiongkaiOp() {
printf("hello jiokngkai\n");
}
static void syweiOp() {
printf("hello sywei\n");
}
static void zjOp() {
printf("hello zj\n");
}
void UserOp(int user) {
PFuncArr[user]();
}
};
int main() {
User user = User::jiongkai;
ManageUsers manager;
manager.Register();
manager.UserOp((int)user);
}
3.2 使用非静态成员函数
/********************由面向过程到面向对象*********************************/
#include <stdio.h>
enum class User {
jiongkai = 0,
sywei = 1,
zj = 2,
};
class ManageUsers {
private:
typedef void(ManageUsers::*pfunc)();
pfunc PFuncArr[10];
public:
void Register() {
PFuncArr[(int)User::jiongkai] = &ManageUsers::JiongkaiOp;
PFuncArr[(int)User::sywei] = &ManageUsers::SyweiOp;
PFuncArr[(int)User::zj] = &ManageUsers::ZjOp;
}
void JiongkaiOp() {
printf("hello jiokngkai\n");
}
void SyweiOp() {
printf("hello sywei\n");
}
void ZjOp() {
printf("hello zj\n");
}
void UserOp(int user) {
(this->*PFuncArr[user])();
}
};
int main() {
User user = User::jiongkai;
ManageUsers manager;
manager.Register();
manager.UserOp((int)user);
}
4、封闭开放原则(将静态成员函数进一步封装成类)
#include <stdio.h>
#include <map>
using namespace std;
enum class UserName {
jiongkai = 0,
sywei = 1,
zj = 2,
};
class User{
protected:
int name;
public:
virtual void Op() {};
};
class UsersRegister {
private:
map<int,User*>UsersMap;
static UsersRegister* instance;
UsersRegister(){};
public:
static UsersRegister*GetInstance() {
if(instance==NULL) {
instance = new UsersRegister();
}
return instance;
}
void Register(User *user,int name) {
UsersMap[name] = user;
}
void GetUser(int name) {
UsersMap[name]->Op();
}
};
UsersRegister* UsersRegister::instance = NULL;
class Jiongkai : public User{
public:
Jiongkai(){
name = (int)UserName::jiongkai;
}
void Op() {
printf("hello jiokngkai\n");
}
};
int main() {
UserName user = UserName::jiongkai;
Jiongkai *puser = new Jiongkai;//新建一个用户
UsersRegister::GetInstance()->Register(puser,(int)user);//将用户注册进去
UsersRegister::GetInstance()->GetUser((int)user);
}
4.2 、初步优化(在构造函数中自动完成注册)
#include <stdio.h>
#include <map>
using namespace std;
enum class UserName {
jiongkai = 0,
sywei = 1,
zj = 2,
};
class User{
protected:
int name;
public:
virtual void Op() {};
};
class UsersRegister {
private:
map<int,User*>UsersMap;
static UsersRegister* instance;
UsersRegister(){};
public:
static UsersRegister*GetInstance() {
if(instance==NULL) {
instance = new UsersRegister();
}
return instance;
}
void Register(User *user,int name) {
UsersMap[name] = user;
}
void GetUser(int name) {
UsersMap[name]->Op();
}
};
UsersRegister* UsersRegister::instance = NULL;
class Jiongkai : public User{
public:
static Jiongkai * instance;
Jiongkai(){
name = (int)UserName::jiongkai;
UsersRegister::GetInstance()->Register(this,name);
}
void Op() {
printf("hello jiokngkai\n");
}
};
Jiongkai* Jiongkai::instance = new Jiongkai();
class Sywei : public User{
public:
static Sywei* instance;
Sywei(){
name = (int)UserName::sywei;
UsersRegister::GetInstance()->Register(this,name);
}
void Op() {
printf("hello Sywei\n");
}
};
Sywei* Sywei::instance = new Sywei();
int main() {
srand((unsigned)time(NULL));
UserName user = UserName(rand()%2);//随机创建一个用户
UsersRegister::GetInstance()->GetUser((int)user);
}
5、进一步优化(注册方法,不注册生成的好的指针)
#include <stdio.h>
#include <map>
using namespace std;
enum class UserName {
jiongkai = 0,
sywei = 1,
zj = 2,
};
class User{
protected:
int name;
public:
virtual void Op() {};
};
class Factory{
public:
virtual User* CreatUser() {};
};
class UsersRegister {
private:
map<int,Factory*>UsersMap;
static UsersRegister* instance;
UsersRegister(){};
public:
static UsersRegister*GetInstance() {
if(instance==NULL) {
instance = new UsersRegister();
}
return instance;
}
void Register(Factory *user,int name) {
UsersMap[name] = user;
}
void GetUser(int name) {
UsersMap[name]->CreatUser()->Op();
}
};
UsersRegister* UsersRegister::instance = NULL;
class Jiongkai : public User{
public:
Jiongkai(){
name = (int)UserName::jiongkai;
}
void Op() {
printf("hello jiokngkai\n");
}
};
class JiongkaiFactory : public Factory {
public:
static JiongkaiFactory *instance;
User* CreatUser() {
return new Jiongkai;
}
JiongkaiFactory() {
UsersRegister::GetInstance()->Register(this,(int)UserName::jiongkai);
}
};
JiongkaiFactory* JiongkaiFactory::instance = new JiongkaiFactory;
int main() {
srand((unsigned)time(NULL));
UserName user = UserName(rand()%1);//随机创建一个用户
UsersRegister::GetInstance()->GetUser((int)user);
}
}