06: 抽象工廠模式

博瑜图形發表於2024-09-16

1. 案例 在Access和SQL server分別插入User表和Department表

2. 抽象工廠模式結構

- 抽象產品(AbstractProduct):所有產品的基類,提供產品類的公共方法

struct User
{
    std::string m_sName = "";
    uint32_t m_uiID = 0;
};

class IUser
{
public:
    virtual void InsertUser(std::shared_ptr<User> spUser);
    virtual const std::shared_ptr<User> GetUserByID(uint32_t iID) const;
private:
    std::unordered_map<uint32_t, std::shared_ptr<User>> m_mapUser;
};
struct Department
{
    std::string m_sName = "";
    uint32_t m_uiID = 0;
};

class IDepartment
{
public:
    virtual void InsertDepartment(std::shared_ptr<Department> spDepartment);
    virtual const std::shared_ptr<Department> GetDepartmentByID(uint32_t iID)const;
private:
    std::unordered_map<uint32_t, std::shared_ptr<Department>> m_mapDepartment;
};

- 具體產品(ConcreteProduct):具體產品類

class AccessUser :
    public IUser
{
public:
    void InsertUser(std::shared_ptr<User> spUser) override;
    const std::shared_ptr<User> GetUserByID(uint32_t iID) const override;
};

void AccessUser::InsertUser(std::shared_ptr<User> spUser)
{
    std::cout << "在Access中給User表增加了一條記錄" << std::endl;
    IUser::InsertUser(spUser);
}

const std::shared_ptr<User> AccessUser::GetUserByID(uint32_t iID) const
{
    std::cout << "在Access中根據ID得到User表一條記錄" << std::endl;
    return IUser::GetUserByID(iID);
}
class SqlServerUser :
    public IUser
{
public:
    void InsertUser(std::shared_ptr<User> spUser) override;
    const std::shared_ptr<User> GetUserByID(uint32_t iID) const override;
};

void SqlServerUser::InsertUser(std::shared_ptr<User> spUser)
{
    std::cout << "在SQL Server中給User表增加了一條記錄:" << std::endl;
    IUser::InsertUser(spUser);
}

const std::shared_ptr<User> SqlServerUser::GetUserByID(uint32_t iID) const
{
    std::cout << "在SQL Server中根據ID得到User表一條記錄" << std::endl;
    return IUser::GetUserByID(iID);
}
class AccessDepartment :
    public IDepartment
{
public:
    void InsertDepartment(std::shared_ptr<Department> spDepartment) override;
    const std::shared_ptr<Department> GetDepartmentByID(uint32_t iID)const override;
};

void AccessDepartment::InsertDepartment(std::shared_ptr<Department> spDepartment)
{
    std::cout << "在Access中給Department表增加了一條記錄" << std::endl;
    IDepartment::InsertDepartment(spDepartment);
}

const std::shared_ptr<Department> AccessDepartment::GetDepartmentByID(uint32_t iID) const
{
    std::cout << "在Access中根據ID得到Department表一條記錄" << std::endl;
    return IDepartment::GetDepartmentByID(iID);
}
class SqlServerDepartment :
    public IDepartment
{
public:
    void InsertDepartment(std::shared_ptr<Department> spDepartment) override;
    const std::shared_ptr<Department> GetDepartmentByID(uint32_t iID)const override;
};

void SqlServerDepartment::InsertDepartment(std::shared_ptr<Department> spDepartment)
{
    std::cout << "在SQL Server中給Department表增加了一條記錄:" << std::endl;
    IDepartment::InsertDepartment(spDepartment);
}

const std::shared_ptr<Department> SqlServerDepartment::GetDepartmentByID(uint32_t iID) const
{
    std::cout << "在SQL Server中根據ID得到Department表一條記錄" << std::endl;
    return IDepartment::GetDepartmentByID(iID);
}

- 抽象工廠(AbstractFactory): 所有生產具體產品的工廠類的基類,提供工廠類的公共方法

struct IUser;
struct IDepartment;
class Factory
{
public:
    virtual std::shared_ptr<IUser> CreatUser() = 0;
    virtual std::shared_ptr<IDepartment> CreatDepartment() = 0;
};

- 具體工廠(ConcreteFactory):生產具體的產品

class AccessFactory :
    public Factory
{
public:
    // 透過 Factory 繼承
    std::shared_ptr<IUser> CreatUser() override;
    std::shared_ptr<IDepartment> CreatDepartment() override;
};

std::shared_ptr<IUser> AccessFactory::CreatUser()
{
    return std::make_shared<AccessUser>();
}

std::shared_ptr<IDepartment> AccessFactory::CreatDepartment()
{
    return std::make_shared<AccessDepartment>();
}
class SqlServerFactory :
    public Factory
{
public:
    // 透過 Factory 繼承
    std::shared_ptr<IUser> CreatUser() override;
    std::shared_ptr<IDepartment> CreatDepartment() override;
};

std::shared_ptr<IUser> SqlServerFactory::CreatUser()
{
    return std::make_shared<SqlServerUser>();
}

std::shared_ptr<IDepartment> SqlServerFactory::CreatDepartment()
{
    return std::make_shared<SqlServerDepartment>();
}

3. 用法

    auto spUser = std::make_shared<User>();
    spUser->m_sName = "小白";
    spUser->m_uiID = 1;
    auto spDepartment = std::make_shared<Department>();
    spDepartment->m_sName = "小白";
    spDepartment->m_uiID = 1;

    {
        auto spServerFactory = std::make_shared<SqlServerFactory>();
        auto spServerUser = spServerFactory->CreatUser();
        auto spServerDepartment = spServerFactory->CreatDepartment();
        spServerUser->InsertUser(spUser);
        spServerDepartment->InsertDepartment(spDepartment);
        auto userGet = spServerUser->GetUserByID(1);
        std::cout << "客戶端獲取:ID= " << userGet->m_uiID << " Name=" << userGet->m_sName << std::endl;
        auto departmentGet = spServerDepartment->GetDepartmentByID(1);
        std::cout << "客戶端獲取:ID= " << departmentGet->m_uiID << " Name=" << departmentGet->m_sName << std::endl;
    }

    {
        auto spServerFactory = std::make_shared<AccessFactory>();
        auto spServerUser = spServerFactory->CreatUser();
        auto spServerDepartment = spServerFactory->CreatDepartment();
        spServerUser->InsertUser(spUser);
        spServerDepartment->InsertDepartment(spDepartment);
        auto userGet = spServerUser->GetUserByID(1);
        std::cout << "客戶端獲取:ID= " << userGet->m_uiID << " Name=" << userGet->m_sName << std::endl;
        auto departmentGet = spServerDepartment->GetDepartmentByID(1);
        std::cout << "客戶端獲取:ID= " << departmentGet->m_uiID << " Name=" << departmentGet->m_sName << std::endl;
    }

相關文章