最近开发中用来很多级联的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);
}
}