zoukankan      html  css  js  c++  java
  • Abstract Factory 抽象工厂模式

    提供一个创建一些列相关或相互依赖对象的接口,而无需指定它们具体的类。

    抽象工厂顾名思义就是对工厂的抽象,它提供了一组创建抽象产品对象的操作接口,我们实际使用的是抽象工厂的派生类,派生类中提供了操作的具体实现,创建一组具体的对象。

    以下情况可以使用抽象工厂模式:

    • 一个系统要独立于它的产品的创建、组合和表示时。
    • 一个系统要由多个产品系列中的一个来配置时。
    • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
    • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

    抽象工厂模式的优缺点:

    • 他分离了具体的类
    • 它使得易于交换产品系列
    • 它有利于产品的一致性
    • 难以支持新种类的产品

    在实现时最好将工厂作为单件。

    如果有多个可能的产品系列,具体工厂也可以使用Prototype原型模式来实现。具体工厂使用产品系列中每一个产品的实例来初始化,且通过复制它的原型来创建新的产品。在基于原型的方法中,使得不是每个新的产品系列都需要一个新的具体工厂类。

    定义可扩展的工厂。比如用参数指定将被创建的对象的种类。注意所有的产品都将返回相同类型的抽象接口给用户,可以用dynamic_cast进行类型转换,但是也有可能失败。

     1 #include <iostream>
     2 #include <string>
     3 
     4 class AbstractProduct {
     5 public:
     6     virtual ~AbstractProduct() {}
     7     virtual void message() = 0;
     8 };
     9 class Product : public AbstractProduct {
    10     virtual ~Product() {}
    11     virtual void message() {
    12         std::cout << "我是一个普通的Product" << std::endl;
    13     }
    14 };
    15 class ProductEx : public AbstractProduct {
    16     virtual ~ProductEx() {}
    17     virtual void message() {
    18         std::cout << "我是加强后的Product" << std::endl;
    19     }
    20 };
    21 
    22 class AbstractObject {
    23 public:
    24     virtual ~AbstractObject() {}
    25     virtual void gao() = 0;
    26 };
    27 class Object : public AbstractObject {
    28     virtual ~Object() {}
    29     virtual void gao() {
    30         std::cout << "虽然叫做Object,但是只是一个普通的Object" << std::endl;
    31     }
    32 };
    33 class ObjectEx : public AbstractObject {
    34     virtual ~ObjectEx() {}
    35     virtual void gao() {
    36         std::cout << "虽然叫做ObjectEx好像很厉害的样子,其实还是一个普通的Object" << std::endl;
    37     }
    38 };
    39 
    40 class AbstractFactory {
    41 public:
    42     virtual AbstractProduct* CreateProduct() = 0;
    43     virtual AbstractObject* CreateObject() = 0;
    44     virtual ~AbstractFactory() {}
    45 protected:
    46     AbstractFactory(){}
    47     AbstractFactory(const AbstractFactory&);
    48     AbstractFactory& operator=(const AbstractFactory&);
    49 };
    50 
    51 class ConcreteFactory : public AbstractFactory {
    52 public:
    53     virtual AbstractProduct* CreateProduct() {
    54         return new Product();
    55     }
    56     virtual AbstractObject* CreateObject() {
    57         return new Object();
    58     }
    59     static ConcreteFactory* Instance() {
    60         static ConcreteFactory _instance;
    61         return &_instance;
    62     }
    63 };
    64 
    65 class ExtraFactory : public AbstractFactory {
    66 public:
    67     virtual AbstractProduct* CreateProduct() {
    68         return new ProductEx();
    69     }
    70     virtual AbstractObject* CreateObject() {
    71         return new ObjectEx();
    72     }
    73     static ExtraFactory* Instance() {
    74         static ExtraFactory _instance;
    75         return &_instance;
    76     }
    77 };

    测试代码

     1 #include <iostream>
     2 #include "Abstract_Factory.h"
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     auto fac = ConcreteFactory::Instance();
     9     auto pro = fac->CreateProduct();
    10     auto obj = fac->CreateObject();
    11     pro->message();
    12     obj->gao();
    13 
    14     auto facEx = ExtraFactory::Instance();
    15     auto proEx = facEx->CreateProduct();
    16     auto objEx = facEx->CreateObject();
    17     proEx->message();
    18     objEx->gao();
    19 
    20     system("pause");
    21 }

    测试结果

    1 我是一个普通的Product
    2 虽然叫做Object,但是只是一个普通的Object
    3 我是加强后的Product
    4 虽然叫做ObjectEx好像很厉害的样子,其实还是一个普通的Object
    5 请按任意键继续. . .
  • 相关阅读:
    MongoDB 学习笔记之 Aggregation Pipeline实战实现inner join
    MongoDB 学习笔记之 Aggregation Pipeline
    Shiro学习(3)授权
    Shiro学习(2)身份验证
    Shiro学习(1)简介
    redis常用命令建议
    Redis入门
    导出EXCEL(带数据)
    导出文件中文乱码处理
    poi之Excel上传
  • 原文地址:https://www.cnblogs.com/zinthos/p/3952117.html
Copyright © 2011-2022 走看看