C++设计模式Learning:抽象工厂

写在前面

我们知道,设计模式的终极目标是高内聚,低耦合,好的软件代码必然离不开好的设计。最近在学习设计模式这块的内容,参考的书籍是程杰的《大话设计模式》,这本书对于初学者来说比较友好,易上手,博客里的内容是参考本书以及网络资源整理的。

博客更新基本上是边学边写的过程,写这个专题一是为了作为自己的知识备忘,二是希望能给正在学习设计模式的童鞋一些参考,博客中内容有纰漏或错误之处,还请指出,谢谢。

基本定义

抽象工厂,属于创建型模式。抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

UML图

 抽象工厂包含的角色通常工厂方法一样,有以下4个要素组成,但是抽象工厂中方法个数不同,抽象产品的个数也不同。

包含以下几类角色:

AbstractFactory:抽象工厂角色(接口)。提供创建不同产品的方法接口CreateProduct1,CreateProduct2,...,由具体工厂角色实现。

ConcreteFactory:具体工厂角色。用于实现抽象工厂的抽象方法(CreateProduct1,CreateProduct2,...),完成具体产品的创建,这种具体工厂存在多个。

Product:抽象产品角色,是所有具体产品的父类,定义了产品的规范,主要特性和功能接口等。抽象工厂模式有多个抽象产品。

ConcreteProduct:具体产品角色,实现抽象产品类中定义的接口,具体产品由具体工厂来创建。

抽象工厂模式实例

场景:小明想买个台式机,这里假设台式机由主机+显示器+外设组成,此时可以用抽象工厂模式来模拟生产台式机的工厂,下面展开内容。

UML图

代码实现

 1. 台式机工厂(抽象工厂)

class PcFactory {
public:
    virtual Host* CreateHost() = 0;
    virtual Display* CreateDisplay() = 0;
    virtual Peripherals* CreatePeripherals() = 0;
};

2. 联想台式机工厂(具体工厂1)

class LenovoFactory : public PcFactory {
public:
    Host* CreateHost()
    {
        std::cout << "Create Lenovo Host." << std::endl;
        return new LenovoHost();    
    }
    virtual Display* CreateDisplay()
    {
        std::cout << "Create Lenovo Display." << std::endl;
        return new LenovoDisplay();
    }

    virtual Peripherals* CreatePeripherals()
    {
        std::cout << "Create Lenovo Peripherals." << std::endl;
        return new LenovoPeripherals();        
    }
};

3. 戴尔台式机工厂(具体工厂2)

class DellFactory : public PcFactory {
public:
    Host* CreateHost()
    {
        std::cout << "Create DellHost." << std::endl;
        return new DellHost();    
    }
    virtual Display* CreateDisplay()
    {
        std::cout << "Create Dell Display." << std::endl;
        return new DellDisplay();
    }

    virtual Peripherals* CreatePeripherals()
    {
        std::cout << "Create Dell Peripherals." << std::endl;
        return new DellPeripherals();        
    }
};

4. 抽象主机/联想主机/戴尔主机

class Host {
public:
    virtual void ComputeSomething() = 0;
};

class LenovoHost : public Host {
public:
    void ComputeSomething() {
        std::cout << "LenovoHost Compute Something." << std::endl;
    }
};

class DellHost : public Host {
public:
    void ComputeSomething() {
        std::cout << "DellHost Compute Something." << std::endl;
    }
};

5. 抽象显示器/联想显示器/戴尔显示器

class Display {
public:
    virtual void ShowSomething() = 0;
};

class LenovoDisplay : public Display {
public:
    void ShowSomething() {
        std::cout << "LenovoDisplay Show Something." << std::endl;
    }
};

class DellDisplay : public Display {
public:
    void ShowSomething() {
        std::cout << "DellDisplay Show Something." << std::endl;
    }
};

6. 抽象外设/联想外设/戴尔外设

class Peripherals {
public:
    virtual void ClickSomething() = 0;
};

class LenovoPeripherals : public Peripherals {
public:
    void ClickSomething() {
        std::cout << "LenovoPeripherals Click Something." << std::endl;
    }
};

class DellPeripherals : public Peripherals {
public:
    void ClickSomething() {
        std::cout << "DellPeripherals Click Something." << std::endl;
    }
};

 7. 客户端测试代码

int main(int argc, char* argv[])
{
    PcFactory* lenovoFac = new LenovoFactory();

    //组装电脑
    Host* host = lenovoFac->CreateHost();
    Display* display = lenovoFac->CreateDisplay();
    Peripherals* peripherals = lenovaFac->CreatePeripherals();

    //运行电脑
    host->ComputeSomething();
    display->ShowSomething();
    peripherals->ClickSomething();

    return 0;
}

 测试结果

优缺点和使用场景

优点:

1.具体产品在应用层的代码隔离,无需关系创建的细节。

2. 将一个系列的产品统一到一起创建。

缺点:

1. 类数量可能较多,增加系统复杂度。

2. 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

使用场景:

当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值