最近開發中用來很多級聯的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);
}
}