本文通過運用設計模式比沒用設計模式的優勢在哪?
設計模式主要是要抓住穩定部分和易變部分,文章結尾會指出。
數據庫操作爲例,以下是原有老代碼
#include <iostream>
using namespace std;
//數據庫連接抽象類
class IDbConnect {
public:
virtual void connect() = 0;
virtual ~IDbConnect() = default;
};
//數據庫命令抽象類
class IDbCommand {
public:
virtual void command(IDbConnect *db) = 0;
virtual ~IDbCommand() = default;
};
//數據庫結果抽象類
class IDbGetResult {
public:
virtual void getResult(IDbCommand *cmd) = 0;
virtual ~IDbGetResult() = default;
};
//MySql數據庫
class MySqlConnect : public IDbConnect{
public:
void connect() override {
cout << "mysql connect" << endl;
}
};
class MySqlCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "mysql command" << endl;
}
};
class MySqlGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "mysql get result" << endl;
}
};
//MySql數據庫
class OracleConnect : public IDbConnect{
public:
void connect() override {
cout << "oracle connect" << endl;
}
};
class OracleCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "oracle command" << endl;
}
};
class OracleGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "oricle get result" << endl;
}
};
class DbOperator {
public:
void insertData(void *data) {
IDbConnect *db = new MySqlConnect;
db->connect();
IDbCommand *cmd = new MySqlCommand;
cmd->command(db);
IDbGetResult *result = new MySqlGetResult;
result->getResult(cmd);
delete(result);
delete(cmd);
delete(db);
}
};
int main()
{
DbOperator op;
op.insertData(nullptr);
return 0;
}
普通工廠方法
#include <iostream>
using namespace std;
//數據庫連接抽象類
class IDbConnect {
public:
virtual void connect() = 0;
virtual ~IDbConnect() = default;
};
//數據庫命令抽象類
class IDbCommand {
public:
virtual void command(IDbConnect *db) = 0;
virtual ~IDbCommand() = default;
};
//數據庫結果抽象類
class IDbGetResult {
public:
virtual void getResult(IDbCommand *cmd) = 0;
virtual ~IDbGetResult() = default;
};
//新增數據庫連接工廠
class DbConnectFactory {
public:
virtual IDbConnect* creatDbConnect() = 0;
virtual ~DbConnectFactory() = default;
};
//新增數據庫命令工廠
class DbCommandFactory {
public:
virtual IDbCommand* creatDbCommand() = 0;
virtual ~DbCommandFactory() = default;
};
//新增數據庫結果工廠
class DbGetResultFactory {
public:
virtual IDbGetResult* creatDbGetResult() = 0;
virtual ~DbGetResultFactory() = default;
};
//MySql數據庫
class MySqlConnect : public IDbConnect{
public:
void connect() override {
cout << "mysql connect" << endl;
}
};
class MySqlCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "mysql command" << endl;
}
};
class MySqlGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "mysql get result" << endl;
}
};
//新增MySql工廠
class MySqlConnectFactory : public DbConnectFactory {
public:
IDbConnect *creatDbConnect() override {
return new MySqlConnect;
}
};
class MySqlCommandFactory : public DbCommandFactory {
public:
IDbCommand *creatDbCommand() override {
return new MySqlCommand;
}
};
class MySqlGetResultFactory : public DbGetResultFactory {
public:
IDbGetResult *creatDbGetResult() override {
return new MySqlGetResult;
}
};
//Oracle數據庫
class OracleConnect : public IDbConnect{
public:
void connect() override {
cout << "oracle connect" << endl;
}
};
class OracleCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "oracle command" << endl;
}
};
class OracleGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "oricle get result" << endl;
}
};
//新增Oracle工廠
class OracleConnectFactory : public DbConnectFactory {
public:
IDbConnect *creatDbConnect() override {
return new OracleConnect;
}
};
class OracleCommandFactory : public DbCommandFactory {
public:
IDbCommand *creatDbCommand() override {
return new OracleCommand;
}
};
class OracleGetResultFactory : public DbGetResultFactory {
public:
IDbGetResult *creatDbGetResult() override {
return new OracleGetResult;
}
};
class DbOperator {
public:
DbOperator(DbConnectFactory *connectFactory,
DbCommandFactory *commandFactory,
DbGetResultFactory *resultFactory) :
connectFactory(connectFactory),
commandFactory(commandFactory),
resultFactory(resultFactory) {}
void insertData(void *data) {
IDbConnect *db = connectFactory->creatDbConnect();
db->connect();
IDbCommand *cmd = commandFactory->creatDbCommand();
cmd->command(db);
IDbGetResult *result = resultFactory->creatDbGetResult();
result->getResult(cmd);
delete(result);
delete(cmd);
delete(db);
}
private:
DbConnectFactory *connectFactory;
DbCommandFactory *commandFactory;
DbGetResultFactory *resultFactory;
};
int main()
{
MySqlConnectFactory connectFactory;
MySqlCommandFactory commandFactory;
MySqlGetResultFactory resultFactory;
DbOperator op(&connectFactory, &commandFactory, &resultFactory);
op.insertData(nullptr);
return 0;
}
普通工廠方法有弊端,就是如果無法阻止傳入MySqlConnectFactory
和OracleCommandFactory
。
所以抽象工廠出現了,專門解決一系列對象必須同時被使用。
#include <iostream>
using namespace std;
//數據庫連接抽象類
class IDbConnect {
public:
virtual void connect() = 0;
virtual ~IDbConnect() = default;
};
//數據庫命令抽象類
class IDbCommand {
public:
virtual void command(IDbConnect *db) = 0;
virtual ~IDbCommand() = default;
};
//數據庫結果抽象類
class IDbGetResult {
public:
virtual void getResult(IDbCommand *cmd) = 0;
virtual ~IDbGetResult() = default;
};
//抽象工廠
class DbFactory {
public:
virtual IDbConnect* creatDbConnect() = 0;
virtual IDbCommand* creatDbCommand() = 0;
virtual IDbGetResult* creatDbGetResult() = 0;
virtual ~DbFactory() = default;
};
//MySql數據庫
class MySqlConnect : public IDbConnect{
public:
void connect() override {
cout << "mysql connect" << endl;
}
};
class MySqlCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "mysql command" << endl;
}
};
class MySqlGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "mysql get result" << endl;
}
};
//新增MySql工廠
class MySqlFactory : public DbFactory {
public:
IDbConnect *creatDbConnect() override {
return new MySqlConnect;
}
IDbCommand *creatDbCommand() override {
return new MySqlCommand;
}
IDbGetResult *creatDbGetResult() override {
return new MySqlGetResult;
}
};
//Oracle數據庫
class OracleConnect : public IDbConnect{
public:
void connect() override {
cout << "oracle connect" << endl;
}
};
class OracleCommand : public IDbCommand {
public:
void command(IDbConnect *db) override {
cout << "oracle command" << endl;
}
};
class OracleGetResult : public IDbGetResult {
public:
void getResult(IDbCommand *cmd) override {
cout << "oricle get result" << endl;
}
};
//新增Oracle工廠
class OracleFactory : public DbFactory {
public:
IDbConnect *creatDbConnect() override {
return new OracleConnect;
}
IDbCommand *creatDbCommand() override {
return new OracleCommand;
}
IDbGetResult *creatDbGetResult() override {
return new OracleGetResult;
}
};
class DbOperator {
public:
DbOperator(DbFactory *factory) : factory(factory) {}
void insertData(void *data) {
IDbConnect *db = factory->creatDbConnect();
db->connect();
IDbCommand *cmd = factory->creatDbCommand();
cmd->command(db);
IDbGetResult *result = factory->creatDbGetResult();
result->getResult(cmd);
delete(result);
delete(cmd);
delete(db);
}
private:
DbFactory *factory;
};
int main()
{
MySqlFactory factory;
DbOperator op(&factory);
op.insertData(nullptr);
return 0;
}
穩定部分是IDbConnect/IDbCommand/IDbGetResult/DbFactory
類,抽象部分是它們的子類。
抽象工廠方法添加一系列產品很輕鬆,比如mongodb
或者redis
數據庫,而在添加操作就很難。