c++抽象工廠方法

本文通過運用設計模式比沒用設計模式的優勢在哪?

設計模式主要是要抓住穩定部分和易變部分,文章結尾會指出。

數據庫操作爲例,以下是原有老代碼

#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;
}

普通工廠方法有弊端,就是如果無法阻止傳入MySqlConnectFactoryOracleCommandFactory

所以抽象工廠出現了,專門解決一系列對象必須同時被使用。

#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數據庫,而在添加操作就很難。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章