[设计模式] 3-4.Factory(工厂模式)+Abstract Factory(抽象工厂)

工厂模式

工厂模式,是创建型设计模式的一种,也是最简单的一种。正常情况下,工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,或者需要添加新产品,就不得不修改工厂类的逻辑,这样就会造成逻辑过于复杂的问题,整个系统都会受到影响,并且违背了设计模式的“开闭原则”。

将原来的工厂设计成抽象父类,只负责定义公共接口而不定义创建行为,然后继承出一系列子类,不妨称之为具体工厂,负责创建产品。即将产品的创建行为延迟到具体工厂中完成,由它们决定怎样创建产品。

一旦需要创建新的产品,则新建一个具体工厂,符合了“开闭原则”。

使用步骤

步骤1:创建抽象工厂类,定义公共接口;
步骤2:创建抽象产品类 ,定义公共接口;
步骤3:创建具体产品类(继承抽象产品类),定义具体产品行为;
步骤4:创建具体工厂类(继承抽象工厂类),定义具体工厂行为;
步骤5:外界通过调用具体工厂类class object的方法,创建具体产品类实例

应用实例

 

情景:一间仅生产A型产品的加工厂,随着客户需求的变化,需要生产B类产品。

壁垒:改变原有加工厂的配置成本太大,假设下一次客户需要再发生变化,再次改变将再次增大的成本。

方案:置办分厂B来生产B型产品。

步骤1:创建抽象工厂类,定义公共接口

class Factory {
public:
    virtual Product * Manufacture() = 0;
};

步骤2:创建抽象产品类 ,定义具体产品的公共接口

class Product {
public:
    virtual void Show() = 0;
};

步骤3:创建具体产品类,定义具体产品

//A型产品
class  ProductA : public Product {
public:
    void Show() {
        cout << "生产出了A型产品" << endl;
    }
};

//新增B型产品需求
class  ProductB : public Product {
public:
    void Show() {
        cout << "生产出了B型产品" << endl;
    }
};

步骤4:创建具体工厂类,定义行为 

// 工厂A — 生产A型产品
class  FactoryA : public Factory {
public:
    Product * Manufacture() {
        return new ProductA();
    }
};

// 新建工厂B用于生产B型产品
class  FactoryB : public Factory {
public:
    Product * Manufacture() {
        return new ProductB();
    }
};

步骤5:外部创建具体类对象,创建相应的产品 

int main()
{
    Factory *mFactory = new FactoryB();
    cout << "新增B型产品需求\n";
    cout << "新建工厂B用于生产B型产品\n";
    mFactory->Manufacture()->Show();

    return 0;
}

优点

工厂模式的优点在于,每个具体工厂类只负责创建对应的产品,逻辑简单清晰。需要新增一种产品时,需要增加创建它的具体工厂类,而不是更改原来的代码,符合开闭原则。因为产品和工厂角色都使用了多态,所以外部无需知道具体产品创建的细节就可以实现功能的扩展。

缺点

添加新产品时,除了增加新产品类还要提供对应的具体工厂类,类的个数将成对增加,增加了复杂度和开销。另一个问题是一个具体工厂只能创建一类产品。

抽象工厂模式

工厂模式存在一个严重的问题:一个具体工厂只能创建一类产品,而在实际过程中,一个工厂往往需要生产多类产品。为了解决这个问题,又引入了一种新的设计模式:抽象工厂模式。

抽象工厂模式,提供一个创建一系列相关对象的接口,而无须指定它们具体的类,具体的工厂负责实现具体的产品实例。

允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。

步骤1: 创建抽象工厂类;
步骤2: 创建抽象产品族类;
步骤3: 创建抽象产品类(继承抽象产品族类);
步骤4: 创建具体产品类(继承抽象产品类);
步骤5: 创建具体工厂类(继承抽象工厂类);
步骤6: 外部实例化具体的工厂类,创建具体产品类的实例。

与工厂模式的区别: 多了抽象产品族类,使得每个工厂可以创建多种类的产品,而工厂方法每个工厂只能创建一类。

应用实例

情景:某公司有两间分布在不同区域的工厂产线,A厂负责生产机械臂产品,B厂负责生产计算机产品。随着客户需求的变化,A厂所在地的客户需要计算机产品产品,B厂所在地的客户需要机械臂产品。

壁垒:没有资源和成本在当地分别开设多一家分厂。

解决方案:在原有的两家工厂里增设生产需求的功能,即A、B两厂都能独立生产机械臂+计算机产品。

步骤1: 创建抽象工厂类,定义公共行为 

class Factory {
public:
    virtual Product * ManufactureRobotArm() = 0; //生产机械臂产品
    virtual Product * ManufactureComputer() = 0; //生产计算机产品
};

步骤2: 创建抽象产品族类 ,定义产品的公共接口

class ProductFamily {
public:
    virtual void Show() = 0;
};

步骤3:创建抽象产品类,继承自抽象产品族,这样就可以定义多种种类的产品,这一步除了继承动作不做任何操作

//机械臂抽象产品类
class ProductRobotArm : public ProductFamily {};

//计算机抽象产品类
class ProductComputer : public ProductFamily {};

步骤4:创建具体产品类,继承抽象产品类,定义具体产品

原本的只有两种产品,A厂负责生产机械臂,型号为A型机械臂,B厂负责生产计算机,型号为B型计算机。

//A型机械臂
class RobotArmAType : public ProductRobotArm {	
public:
    void Show() {
        cout << "生产A型机械臂" << endl;
    }
};

//B型计算机
class ComputerBType : public ProductComputer {
public:
    void Show() {
        cout << "生产B型计算机" << endl;
    }
};

现在客户有了新的需求,A厂区域的客户需要计算机产品,定为A型计算机,B厂区域的客户需要机械臂,定为B型机械臂

//新增加的A型计算机产品需求,由A厂负责新增生产计划
class ComputerAType : public ProductComputer {
public:
    void Show() {
        cout << "生产A型计算机" << endl;
    }
};

//新增加的B型机械臂产品需求,由B厂负责新增生产计划
class RobotArmBType : public ProductRobotArm {	
public:
    void Show() {
        cout << "生产B型机械臂" << endl;
    }
};

步骤5:创建具体工厂类,继承自抽象工厂类,定义创建对应具体产品实例的方法

A厂原本只有机械臂生产,随着客户需求的变动,新增加了计算机生产计划。 

//A厂 — 生产A型机械臂+A型计算机产品
class FactoryA : public Factory {
public:
    //原有的机械臂生产
    ProductFamily * ManufactureRobotArm() {
        return new RobotArmAType();
    }

    //新增A型计算机产品生产计划
    ProductFamily * ManufactureComputer() {
        return new ComputerAType();
    }
};

B厂原本只有计算机生产,随着客户需求的变动,新增加了机械臂生产计划。

class FactoryB : public Factory {
public:
	//B厂原有的计算机生产
    ProductFamily * ManufactureComputer() {
        return new ComputerBType();
    }

    //B厂新增加的机械臂生产计划	
    ProductFamily * ManufactureRobotArm() {
        return new RobotArmBType();
    }

};

步骤6:外部通过实例化具体工厂类,创建具体产品 

int main()
{
    //生产工作流程
    Factory *mFactoryA = new FactoryA();
    Factory *mFactoryB = new FactoryB();
	
    std::cout << "A厂原本负责生产机械臂,型号为A型机械臂: " << std::endl;
    mFactoryA->ManufactureRobotArm()->Show();
    std::cout << "A厂新增加计算机生产产线,型号为A型计算机: " << std::endl;
    mFactoryA->ManufactureComputer()->Show();

    std::cout << std::endl;

    std::cout << "B厂原本负责生产计算机,型号为B型计算机: " << std::endl;
    mFactoryB->ManufactureComputer()->Show();
    std::cout << "B厂新增加机械臂生产产线,型号为B型机械臂: " << std::endl;
    mFactoryB->ManufactureRobotArm()->Show();

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值