C++设计模式系列(二)工厂模式

news2024/10/6 22:26:25

文章目录

  • 一、什么是工厂
  • 二、 简单工厂模式
    • UML类图
    • 简单工厂模式结构
    • 代码
      • 一、定义抽象产品类AbstractProduct
      • 二、定义具体产品类
      • 三、定义工厂类和工厂方法
      • 应用
    • 扩展
      • 一、扩展具体产品类
      • 二、扩展工厂类方法
      • 三、扩展应用
      • 优点
      • 缺点
      • 使用场合
  • 三、工厂方法模式
    • UML类图
    • 工厂方法模式结构
    • 代码
      • 一、定义抽象产品类AbstractProduct(和简单工厂一致)
      • 二、定义具体产品类(和简单工厂一致)
      • 三、定义抽象工厂类AbstractFactory
      • 四、定义具体工厂类
      • 五、应用
    • 扩展
      • 一、扩展具体产品类
      • 二、扩展具体工厂类
      • 三、扩展应用
      • 四、增加模板类
      • 五、修改应用
      • 优点
      • 缺点
  • 四、抽象工厂模式
    • UML类图
    • 抽象工厂模式结构
    • 需求
    • 代码
      • 一、定义A类抽象产品类AbstractProductA
      • 二、定义具体A类产品类
      • 三、定义B类抽象产品类AbstractProductB
      • 四、定义具体B类产品类
      • 五、定义C类抽象产品类AbstractProductC
      • 六、定义具体C类产品类
      • 七、定义抽象工厂AbstractFactory
      • 八、定义具体工厂ConcreteProduct
      • 九、应用
      • 优点
      • 缺点
  • 参考学习


一、什么是工厂

  1. 设计一个抽象产品类,它包含一些公共方法的声明
  2. 从抽象产品类中派生出多个具体产品类,具体产品类中实现具体产品生产的相关代码
  3. 设计一个工厂类,工厂类提供一个生产各种产品的创建方法,该方法根据传入参数(产品名称)创建不同的具体产品类对象
  4. 应用只需调用工厂类的这个创建方法,无需知道具体产品的类名,并传入具体产品参数,即可得到一个具体产品对象。
    工厂模式细分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。

二、 简单工厂模式

简单工厂模式是最简单的设计模式之一,其实它并不属于GOF的23种设计模式,但应用也十分频繁,同时也是其余创建型模式的基础,因此有必要先学习简单工厂模式。

UML类图

在这里插入图片描述

简单工厂模式结构

  1. Factory (工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象; 在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product。
  2. Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。
  3. ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

代码

一、定义抽象产品类AbstractProduct

animals类:动物类(AbstractProduct)

class animals_s {
public:
    animals_s() {
    }
    virtual int get_leg_num() {
        return m_leg_num;
    }
    virtual string get_color() {
        return m_color;
    }
    virtual ~animals_s() {
    };
protected:
    int m_leg_num;
    string m_color;
};

二、定义具体产品类

dog类:小狗动物类(Product1)

class dog_s : public animals_s {
public:
    dog_s() : animals_s() {
        m_leg_num = 4;
        m_color = "write";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~dog_s() {
    }
};

cock类:小鸡动物类(Product2)

class cock_s : public animals_s {
public:
    cock_s() : animals_s() {
        m_leg_num = 2;
        m_color = "black";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~cock_s() {
    }
};

三、定义工厂类和工厂方法

animals_factory_s类:动物生产工厂类(Factory)

class animals_factory_s {
public:
    animals_s *create_animals(const string &animals_type) {
        animals_s *p_animals_obj = nullptr;
        if (animals_type == "dog_s") {
            p_animals_obj = new dog_s();
        } else if (animals_type == "cock_s") {
            p_animals_obj = new cock_s();
        }
        return p_animals_obj;
    }
};

应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_s> m_animals_factory(new animals_factory_s());

    unique_ptr<animals_s> dog(m_animals_factory->create_animals("dog_s"));
	unique_ptr<animals_s> cock(m_animals_factory->create_animals("cock_s"));

    int dog_leg_num;
    string dog_color;
    if (dog != NULL) {
        dog_leg_num = dog->get_leg_num();
        dog_color = dog->get_color();
    }
    int cock_leg_num;
    string cock_color;
    if (cock != NULL) {
        cock_leg_num = cock->get_leg_num();
        cock_color = cock->get_color();
    }
    return 0;
}

扩展

增加小猫动物。

一、扩展具体产品类

cat类:小猫动物类(Product3)

class cat_s : public animals_s {
public:
    cat_s() : animals_s() {
        m_leg_num = 4;
        m_color = "grey";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~cat_s() {
    }
};

二、扩展工厂类方法

animals_factory_s类:动物生产工厂类(Factory)

class animals_factory_s {
public:
    animals_s *create_animals(const string &animals_type) {
        animals_s *p_animals_obj = nullptr;
        if (animals_type == "dog_s") {
            AINFO << "create dog_s class ";
            p_animals_obj = new dog_s();
        } else if (animals_type == "cock_s") {
            AINFO << "create cock_s class ";
            p_animals_obj = new cock_s();
        } else if (animals_type == "cat_s") {
            AINFO << "create cat_s class ";
            p_animals_obj = new cat_s();
        }
        return p_animals_obj;
    }
};

三、扩展应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_s> m_animals_factory(new animals_factory_s());

    unique_ptr<animals_s> dog(m_animals_factory->create_animals("dog_s"));
	unique_ptr<animals_s> cock(m_animals_factory->create_animals("cock_s"));
    unique_ptr<animals_s> cat(m_animals_factory->create_animals("cat_s"));

    int dog_leg_num;
    string dog_color;
    if (dog != NULL) {
        dog_leg_num = dog->get_leg_num();
        dog_color = dog->get_color();
    }
    int cock_leg_num;
    string cock_color;
    if (cock != NULL) {
        cock_leg_num = cock->get_leg_num();
        cock_color = cock->get_color();
    }
    int cat_leg_num;
    string cat_color;
    if (cat != NULL) {
        cat_leg_num = cat->get_leg_num();
        cat_color = cat->get_color();
    }
    return 0;
}

优点

  1. 一个调用者想创建一个对象,只要知道其名称就可以了(应用中的"MiPhone"、“iPhone”、“HuaweiPhone”);
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以(参照扩展的内容);
  3. 屏蔽产品的具体实现,调用者只关心产品的接口,实现了创建对象的代码(工厂类的makePhone),与具体的类(手机产品)解耦合的效果。。

缺点

  1. 扩展性差(实例中想增加一种手机产品,除了新增一个手机产品类,还需要修改工厂类方法)这样一来,就需要修改源代码,灵活性非常的差,且违背“开闭原则”。
  2. 不同的产品需要不同额外参数的时候 不支持。

使用场合

  1. 在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式。
  2. 由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。

三、工厂方法模式

工厂方法模式是使用频率最高的工厂模式。
定义一个用于创建对象的接口(virtual animals_m *create_animals() = 0;),但是让子类决定将哪一个类实例化(子类实现create_animals)。工厂方法模式让一个类的实例化延迟到其子类。
简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。

UML类图

在这里插入图片描述

工厂方法模式结构

从工厂方法模式简介中,可以知道该模式有以下几种角色:

  1. 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法
  2. 具体工厂(ConcreteFactory):生产具体产品的工厂
  3. 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
  4. 具体产品(ConcreteProduct):具体的产品类

代码

一、定义抽象产品类AbstractProduct(和简单工厂一致)

animals类:动物类(AbstractProduct)

class animals_m {
public:
    animals_m() {
    }
    virtual int get_leg_num() {
        return m_leg_num;
    }
    virtual string get_color() {
        return m_color;
    }
    virtual ~animals_m(){
    };
protected:
    int m_leg_num;
    string m_color;
};

二、定义具体产品类(和简单工厂一致)

dog类:小狗动物类(Product1)

class dog_m : public animals_m {
public:
    dog_m() : animals_m() {
        m_leg_num = 4;
        m_color = "write";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~dog_m() {
    }
};

cock类:小鸡动物类(Product2)

class cock_m : public animals_m {
public:
    cock_m() : animals_m() {
        m_leg_num = 2;
        m_color = "black";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~cock_m() {
    }
};

三、定义抽象工厂类AbstractFactory

定义一个用于创建对象的接口(virtual animals_m *create_animals() = 0;),当需要扩展时,不需要更改此文件。
AbstractFactory类:生产不同产品的工厂的抽象类

class animals_factory_m {
public:
    virtual animals_m *create_animals() = 0;
    virtual ~animals_factory_m() {}
};

四、定义具体工厂类

让子类决定将哪一个类实例化(子类实现create_animals)

dog_factory_m类:生产小狗动物的工厂类(ConcreteFactory1)

class dog_factory_m : public animals_factory_m
{
public:
    animals_m *create_animals() {
        return new dog_m();
    }
};

cock_factory_m类:生产小鸡动物的工厂类(ConcreteFactory2)
class cock_factory_m : public animals_factory_m
{
public:
    animals_m *create_animals() {
        return new cock_m();
  }
};

五、应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_m> m_dog_factory(new dog_factory_m());
    unique_ptr<animals_factory_m> m_cock_factory(new cock_factory_m());

    unique_ptr<animals_m> cock(m_cock_factory->create_animals());
    unique_ptr<animals_m> dog(m_dog_factory->create_animals());

    int dog_leg_num;
    string dog_color;
    if (dog != NULL) {
        dog_leg_num = dog->get_leg_num();
        dog_color = dog->get_color();
    }
    
    int cock_leg_num;
    string cock_color;
    if (cock != NULL) {
        cock_leg_num = cock->get_leg_num();
        cock_color = cock->get_color();
    }
}

扩展

一、扩展具体产品类

cat类:小猫动物类(Product3)

class cat_m : public animals_m {
public:
    cat_m() : animals_m() {
        m_leg_num = 4;
        m_color = "grey";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~cat_m() {
    }
};

二、扩展具体工厂类

cat_factory_m类:生产小猫动物的工厂类(ConcreteFactory3)

class cat_factory_m : public animals_factory_m
{
public:
    animals_m *create_animals() {
        return new cat_m();
  }
};

三、扩展应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_m> m_dog_factory(new dog_factory_m());
    unique_ptr<animals_m> dog(m_dog_factory->create_animals());
    int dog_leg_num;
    string dog_color;
    if (dog != NULL) {
        dog_leg_num = dog->get_leg_num();
        dog_color = dog->get_color();
    }

    unique_ptr<animals_factory_m> m_cock_factory(new cock_factory_m());
    unique_ptr<animals_m> cock(m_cock_factory->create_animals());
    int cock_leg_num;
    string cock_color;
    if (cock != NULL) {
        cock_leg_num = cock->get_leg_num();
        cock_color = cock->get_color();
    }

    unique_ptr<animals_factory_m> m_cat_factory(new cat_factory_m());
    unique_ptr<animals_m> cat(m_cat_factory->create_animals());
    int cat_leg_num;
    string cat_color;
    if (cat != NULL) {
        cat_leg_num = cat->get_leg_num();
        cat_color = cat->get_color();
    }
}

四、增加模板类

我们每实现一个动物类,就需要实现一个对应的动物工厂类,有点麻烦,其实我们可以通过模板来优化这一步操作。

template <class T>
class factory_t_m : public animals_factory_m
{
public:
    virtual animals_m *create_animals() {
        return new T();
    }
};

五、修改应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_m> m_dog_factory(new factory_t_m<dog_m>());
    unique_ptr<animals_m> dog(m_dog_factory->create_animals());
    int dog_leg_num;
    string dog_color;
    if (dog != NULL) {
        dog_leg_num = dog->get_leg_num();
        dog_color = dog->get_color();
    }

    unique_ptr<animals_factory_m> m_cock_factory(new factory_t_m<cock_m>());
    unique_ptr<animals_m> cock(m_cock_factory->create_animals());
    int cock_leg_num;
    string cock_color;
    if (cock != NULL) {
        cock_leg_num = cock->get_leg_num();
        cock_color = cock->get_color();
    }

    unique_ptr<animals_factory_m> m_cat_factory(new factory_t_m<cat_m>());
    unique_ptr<animals_m> cat(m_cat_factory->create_animals());
    int cat_leg_num;
    string cat_color;
    if (cat != NULL) {
        cat_leg_num = cat->get_leg_num();
        cat_color = cat->get_color();
    }
}

使用模版,在增加动物类时,可以不增加动物工厂类,但是在应用中,需要知道动物类的类名(unique_ptr<animals_factory_m> m_cat_factory(new factory_t_m<cat_m>()))

优点

  1. 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂。
  2. 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键。
  3. 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。

缺点

  1. 添加新产品时需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销。

四、抽象工厂模式

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

简言之,一个工厂可以提供创建多种相关产品的接口,而无需像工厂方法一样,为每一个产品都提供一个具体工厂。

UML类图

在这里插入图片描述

抽象工厂模式结构

抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品:

  1. 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法
  2. 具体工厂(ConcreteFactory):生产具体产品的工厂
  3. 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
  4. 具体产品(ConcreteProduct):具体的产品类

需求

在工厂方法模式基础上,增加系列,比如山地动物,河边动物,丛林动物,那么我们之前的例子就可以分为

山地河边丛林

代码

一、定义A类抽象产品类AbstractProductA

山地动物类:定义山地动物的接口(AbstractPhoneA)

class hill_animals {
public:
    hill_animals() {
    }
    virtual int get_leg_num() {
        return m_leg_num;
    }
    virtual string get_color() {
        return m_color;
    }
    virtual ~hill_animals(){
    };
protected:
    int m_leg_num;
    string m_color;
};

二、定义具体A类产品类

hill_dog类:山地小狗动物类(Product1)

class hill_dog : public hill_animals {
public:
    hill_dog() : hill_animals() {
        m_leg_num = 4;
        m_color = "black";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~hill_dog() {
    }
};

hill_cock类:山地小鸡动物类(Product2)

class hill_cock : public hill_animals {
public:
    hill_cock() : hill_animals() {
        m_leg_num = 2;
        m_color = "black";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~hill_cock() {
    }
};

hill_cat类:山地小猫动物类(Product3)

class hill_cat : public hill_animals {
public:
    hill_cat() : hill_animals() {
        m_leg_num = 4;
        m_color = "black";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~hill_cat() {
    }
};

三、定义B类抽象产品类AbstractProductB

河边动物类:定义河边动物的接口(AbstractPhoneB)

class river_animals {
public:
    river_animals() {
    }
    virtual int get_leg_num() {
        return m_leg_num;
    }
    virtual string get_color() {
        return m_color;
    }
    virtual ~river_animals(){
    };
protected:
    int m_leg_num;
    string m_color;
};

四、定义具体B类产品类

river_dog 类:河流小狗动物类(Product1)

class river_dog : public river_animals {
public:
    river_dog() : river_animals() {
        m_leg_num = 4;
        m_color = "white";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~river_dog() {
    }
};

river_cock 类:河流小鸡动物类(Product2)

class river_cock : public river_animals {
public:
    river_cock() : river_animals() {
        m_leg_num = 2;
        m_color = "white";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~river_cock() {
    }
};

river_cat 类:河流小猫动物类(Product3)

class river_cat : public river_animals {
public:
    river_cat() : river_animals() {
        m_leg_num = 4;
        m_color = "white";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~river_cat() {
    }
};

五、定义C类抽象产品类AbstractProductC

丛林动物类:定义丛林动物的接口(AbstractPhoneC)

class jungle_animals {
public:
    jungle_animals() {
    }
    virtual int get_leg_num() {
        return m_leg_num;
    }
    virtual string get_color() {
        return m_color;
    }
    virtual ~jungle_animals(){
    };
protected:
    int m_leg_num;
    string m_color;
};

六、定义具体C类产品类

jungle_dog类:丛林小狗动物类(Product1)

class jungle_dog : public jungle_animals {
public:
    jungle_dog() : jungle_animals() {
        m_leg_num = 4;
        m_color = "green";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~jungle_dog() {
    }
};

jungle_cock类:丛林小鸡动物类(Product2)

class jungle_cock : public jungle_animals {
public:
    jungle_cock() : jungle_animals() {
        m_leg_num = 2;
        m_color = "green";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~jungle_cock() {
    }
};

jungle_cat 类:丛林小猫动物类(Product3)

class jungle_cat : public jungle_animals {
public:
    jungle_cat() : jungle_animals() {
        m_leg_num = 4;
        m_color = "green";
    }
    int get_leg_num() {
        return m_leg_num;
    }
    string get_color() {
        return m_color;
    }
    virtual ~jungle_cat() {
    }
};

七、定义抽象工厂AbstractFactory

class animals_factory_a {
public:
    virtual hill_animals *create_hill_animals() = 0;
    virtual river_animals *create_river_animals() = 0;
    virtual jungle_animals *create_jungle_animals() = 0;
    virtual ~animals_factory_a() {}
};

八、定义具体工厂ConcreteProduct

小狗工厂类

class dog_factory : public animals_factory_a
{
public:
    virtual hill_animals *create_hill_animals() {
        return new hill_dog();
    }
    virtual river_animals *create_river_animals() {
        return new river_dog();
    }
    virtual jungle_animals *create_jungle_animals() {
        return new jungle_dog();
    }
};

小鸡工厂类

class cock_factory : public animals_factory_a
{
public:
    virtual hill_animals *create_hill_animals() {
        return new hill_cock();
    }
    virtual river_animals *create_river_animals() {
        return new river_cock();
    }
    virtual jungle_animals *create_jungle_animals() {
        return new jungle_cock();
    }
};

小猫工厂类

class cat_factory : public animals_factory_a
{
public:
    virtual hill_animals *create_hill_animals() {
        return new hill_cat();
    }
    virtual river_animals *create_river_animals() {
        return new river_cat();
    }
    virtual jungle_animals *create_jungle_animals() {
        return new jungle_cat();
    }
};

九、应用

int main(int argc, char** argv) {
    unique_ptr<animals_factory_a> dog_bank(new dog_factory());
    unique_ptr<hill_animals> hill_dog(dog_bank->create_hill_animals());
    unique_ptr<river_animals> river_dog(dog_bank->create_river_animals());
    unique_ptr<jungle_animals> jungle_dog(dog_bank->create_jungle_animals());
    int dog_leg_num;
    string dog_color;
    if (hill_dog != NULL) {
        dog_leg_num = hill_dog->get_leg_num();
        dog_color = hill_dog->get_color();
    }
    if (river_dog != NULL) {
        dog_leg_num = river_dog->get_leg_num();
        dog_color = river_dog->get_color();
    }
    if (jungle_dog != NULL) {
        dog_leg_num = jungle_dog->get_leg_num();
        dog_color = jungle_dog->get_color();
    }

    unique_ptr<animals_factory_a> cock_bank(new cock_factory());
    unique_ptr<hill_animals> hill_cock(cock_bank->create_hill_animals());
    unique_ptr<river_animals> river_cock(cock_bank->create_river_animals());
    unique_ptr<jungle_animals> jungle_cock(cock_bank->create_jungle_animals());
    int cock_leg_num;
    string cock_color;
    if (hill_dog != NULL) {
        cock_leg_num = hill_cock->get_leg_num();
        cock_color = hill_cock->get_color();
    }
    if (river_dog != NULL) {
        cock_leg_num = river_cock->get_leg_num();
        cock_color = river_cock->get_color();
    }
    if (jungle_dog != NULL) {
        cock_leg_num = jungle_cock->get_leg_num();
        cock_color = jungle_cock->get_color();
    }
    
    unique_ptr<animals_factory_a> cat_bank(new cat_factory());
    unique_ptr<hill_animals> hill_cat(cat_bank->create_hill_animals());
    unique_ptr<river_animals> river_cat(cat_bank->create_river_animals());
    unique_ptr<jungle_animals> jungle_cat(cat_bank->create_jungle_animals());
    int cat_leg_num;
    string cat_color;
    if (hill_dog != NULL) {
        cat_leg_num = hill_dog->get_leg_num();
        cat_color = hill_dog->get_color();
    }
    if (river_dog != NULL) {
        cat_leg_num = river_cat->get_leg_num();
        cat_color = river_cat->get_color();
    }
    if (jungle_dog != NULL) {
        cat_leg_num = jungle_cat->get_leg_num();
        cat_color = jungle_cat->get_color();
    }
}

优点

抽象工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂。

新加入产品系列时,无需修改原有系统,增强了系统的可扩展性,符合开闭原则。

缺点

在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则。

参考学习

C++设计模式----工厂模式

C++设计模式之工厂模式(创建型模式)

C++工厂模式(简单工厂、工厂方法、抽象工厂)

工厂模式——简单工厂模式 && 智能指针的使用

C++创建型模式-工厂模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/86425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【车间调度】基于GA/PSO/SA/ACO/TS优化算法的车间调度比较(Matlab代码实现)

目录 1 概述 2 FJSP 描述 3 运行结果 3.1 main1运行结果 3.2 main2运行结果 4 参考文献 5 Matlab代码实现 1 概述 柔性作业车间调度问题(Flexible Job shop Sched-uling Problem , FJSP)是在离散制造业和流程工业中应用广泛的一类问题,已被证明是典型的 NP-上hard问题。…

【面试题】宏任务和微任务

1. 宏任务和微任务 宏任务(macroTask)和微任务(microTask)都是异步中API的分类。 宏任务&#xff1a;setTimeout&#xff0c;setInterval&#xff0c;Ajax&#xff0c;DOM事件微任务&#xff1a;Promise&#xff0c;async/await 微任务执行时机比宏任务要早。 console.log(1…

策略 模式

策略模式 参考&#xff1a; 三种新姿势&#xff1a;帮你干掉过多的if-else (qq.com) http://t.csdn.cn/5YeOZ http://t.csdn.cn/HcGYw JAVASE中GUI编程中&#xff0c;布局管理 &#xff1b; Spring框架中&#xff0c;Resource接口&#xff0c;资源访问&#xff1b; javax.…

优美的曲线(含蝴蝶线)-CoCube

复现如下这篇&#xff1a; 优美的曲线-turtlesim 两段视频&#xff1a; 优美的曲线-CoCubebutterfly蝴蝶曲线之CoCube篇如何更深入分析&#xff0c;获得更高精度曲线呢&#xff1f; 对比下面两幅图&#xff1a; 尤其需要注意右图&#xff0c;右下角。 什么原因导致这个控制量…

一个元素纯CSS实现开关按钮【介绍box-shadow、单边或多重阴影、appearance属性】

借助checkbox表单元素、:checked伪类、::before/::after伪元素&#xff0c;就可以只需一个input[type"checkbox"]元素&#xff0c;通过纯CSS实现Switch开关效果的按钮。 主要用到的属性&#xff1a; appearance 默认css元素样式box-shadow 阴影效果transition css动…

ICG maleimide, ICG-MAL,2143933-81-5,ICG和PEG链接可在体内长循环.

英文名&#xff1a;ICG maleimide ICG-MAL CAS&#xff1a;2143933-81-5 分子式: C51H56N4O6S 分子量: 853.09 外 观&#xff1a;绿色粉末 溶解度&#xff1a;二氯甲烷 纯 度&#xff1a;95% 结构式&#xff1a; ICG is a tricarbocyanine-type dye with NIR-absorb…

Jenkins自动化测试Robot Framework详解

目录 1. Robot Framework 概念 2. Robot Framework 安装 3. Pycharm Robot Framework 环境搭建 4. Robot Framework 介绍 5. Jenkins 自动化测试 总结 重点&#xff1a;配套学习资料和视频教学 1. Robot Framework 概念 Robot Framework是一个基于Python的&#xff0c;…

MySQL——怎么给字符串字段加索引

现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是本篇文章要讨论的问题。 假设&#xff0c;现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; mysql> create table SUser( ID big…

Hive 分析银行转账风险

文章目录创建数据源基于转账记录&#xff0c;计算 7 天内各个账号的转账金额找出相同收付款人 5 天内连续转账3次或以上的记录创建数据源 数据来源&#xff1a;数据源 drop table transfer_log;CREATE TABLE transfer_log ( log_id bigint, -- idlog_ts timestamp, -- 操作时…

128-152-spark-核心编程-源码

128-spark-核心编程-源码&#xff08;主要以了解基本原理和流程为主&#xff09;&#xff1a; 总体相关 ​ 1.环境准备(Yarn 集群) ​ (1) Driver, Executor ​ 2.组件通信 ​ (1) Driver > Executor ​ (2) Executor > Driver ​ (3) Executor > Executor ​ 3.应用…

Unity异步加载AB包

Unity异步加载AB包写在前面效果关键讲解项目地址写在后面写在前面 最近项目需要在Unity中完成一个非常耗时的工作&#xff0c;所以学习了下异步加载的流程&#xff0c;这里做了一个demo&#xff0c;异步加载AB包&#xff0c;其实异步加载场景等&#xff0c;原理差不多。 效果…

Tomcat的Maven插件使用方法(在idea里面运行Tomcat)

目录 一、概述 二、下载和导入插件 三、测试使用方式 四、总结 一、概述 使用这个插件可以快速的运行Tomcat&#xff0c;比在本地配置快得多。 二、下载和导入插件 1.下载插件Maven Helper ps&#xff1a;已经有下载过这个插件的可以跳过此步骤 &#xff08;1&#xff…

一、导论——可解释性机器学习(DataWhale组队学习)

目录导言一、什么是可解释人工智能?二、学可解释机器学习有什么用?2.1学习可解释机器学习的原因2.2 Machine Teaching :人工智能教人类学习2.3 细粒度图像分类2.4前沿AI三、本身可解释性好的机器学习模型四、传统机器学习算法的可解释性分析五、卷积神经网络的可解释性分析5.…

前端基础(二)_HTML常用标签(块级标签、行级标签、行块级标签)

HTML常用标签 我们可以分为三类&#xff1a; 1.块级标签 2.行级标签 3.行块级标签 一、块级标签 1.1 h系类标签 标题标签 H1~h6 大到小 H1 在同一个页面中只能使用一次 其他标签可以重复 特点&#xff1a;默认宽度100% 高度自适应 独立成行 自带间距加粗 <body><…

java计算机毕业设计ssm制造型企业仓储管理系统i0180(附源码、数据库)

java计算机毕业设计ssm制造型企业仓储管理系统i0180&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&…

[附源码]计算机毕业设计的项目管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

基于小波变换的图像压缩解压缩的matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 图像压缩的类别 对于图像压缩&#xff0c;主要有两类方法&#xff1a;无损的图像压缩以及有损的图像压缩&#xff0c;分别称为lossless image compression and lossy image compression。 对于无…

[附源码]Node.js计算机毕业设计动漫网站Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

第37篇 网络(七)TCP(一)

导语 TCP即TransmissionControl Protocol&#xff0c;传输控制协议。与UDP不同&#xff0c;它是面向连接和数据流的可靠传输协议。也就是说&#xff0c;它能使一台计算机上的数据无差错的发往网络上的其他计算机&#xff0c;所以当要传输大量数据时&#xff0c;我们选用TCP协议…

ssm+Vue计算机毕业设计校园生活服务预约管理系统(程序+LW文档)

ssmVue计算机毕业设计校园生活服务预约管理系统&#xff08;程序LW文档&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;…