El modelo de fábrica del patrón de diseño C ++ (3)

  El patrón de fábrica es un patrón de creación, que se puede dividir en tres categorías, patrón de fábrica simple, patrón de método de fábrica y patrón de fábrica abstracto; estos tres tipos de patrones son de fácil a difícil, de simple a complejo. Expliquemos brevemente estos tres modos de fábrica

Patrón de fábrica simple

Introducción

  El modelo de fábrica simple es el tipo más simple del modelo de fábrica; es una fábrica que produce muchos productos diferentes; los detalles de implementación de los productos están ocultos desde el exterior y solo los tipos de productos requeridos están expuestos. El cliente proporciona el tipo de producto del producto requerido a la fábrica, y el producto correspondiente será devuelto. Los clientes solo deben preocuparse por la clase base del producto y no necesitan saber qué subclase obtienen.
  Escenario de uso: se utiliza a menudo en una variedad de casos del mismo tipo. Estas clases pueden ocultarse y proporcionar la misma interfaz, lo que es beneficioso para el mantenimiento y la modificación.
  Ventajas: 1. Los detalles de la creación de objetos están ocultos y la instanciación del producto se implementa en la subclase; 2. El cliente no necesita preocuparse por qué tipo de producto se utiliza, solo necesita saber qué fábrica y solo debe proporcionar lo necesario. El tipo de producto del producto 3. Facilitar la expansión de nuevos productos 4. Seguir el principio de inversión de dependencia.
  Desventajas: 1. Violando el principio de apertura y cierre, cada producto nuevo debe expandirse; 2. Todos los productos solo se pueden producir de una manera. Si un producto necesita ser instanciado de múltiples formas o formas diferentes, no Ser aplicable.
Patrón de fábrica simple

código

 enum Production_en {
     Production_0 = 0,
     Production_1,
     Production_2
 }; // Production_en

 class Production {
 public:
     virtual void product_fun() = 0;
 }; // production


 class Pro_0 : public Production {
 public:
     void product_fun();
 }; // Pro_0

 class Pro_1 : public Production {
 public:
     void product_fun();
 }; // Pro_1


 class Pro_2 : public Production {
 public:
     void product_fun() override;
 }; // Pro_2


 class SampleFactory {
 public:
     Production *create_fun(Production_en pro_type);
 }; // sample_factory



void Pro_0::product_fun() {
    std::cout << "Pro_0 production" << std::endl;
}


void Pro_1::product_fun() {
    std::cout << "Pro_1 production" << std::endl;
}


void Pro_2::product_fun() {
    std::cout << "Pro_2 production" << std::endl;
}

Production *SampleFactory::create_fun(Production_en pro_type) {
    std::shared_ptr<Production> pro = nullptr;
    switch (pro_type) {
        case Production_en::Production_0:
            pro = std::make_shared<Pro_0>();
            break;
        case Production_en::Production_1:
            pro = std::make_shared<Pro_1>();
            break;
        case Production_en::Production_2:
            pro = std::make_shared<Pro_2>();
            break;
        default:
            std::cout << "Don't support this type " << pro_type << std::endl;
            return nullptr;
    }
    return pro.get();
}

int main(){
    std::shared_ptr<SampleFactory> factory = std::make_shared<SampleFactory>();
    factory->create_fun(Production_en::Production_0)->product_fun();
    factory->create_fun(Production_en::Production_1)->product_fun();
    factory->create_fun(Production_en::Production_2)->product_fun();
    return 0;
}

Patrón de método de fábrica

Introducción

  Modo método de fábrica: se refiere a una fábrica que produce solo un tipo de producto; si necesita agregar un nuevo producto, solo necesita agregar una fábrica correspondiente, para que se cumpla con el principio de apertura y cierre.
  Escenario de uso: Consistente con el modelo de fábrica simple, excepto que el modelo de método de fábrica cumple con el principio de apertura y cierre, haciéndolo más flexible. La instanciación se pospone a la subclase, y la subclase decide instanciar el objeto.
  ** Ventajas: ** En comparación con el modelo simple de fábrica, existe un cumplimiento más del principio de apertura y cierre, lo que lo hace más flexible.
  ** Desventajas: ** Cada vez que agrega un producto, necesita agregar una fábrica. Si hay demasiados productos, la fábrica también tendrá una cantidad correspondiente.
Patrón de método de fábrica

código

class ProBasic {
public:
    virtual void product_fun() = 0;
}; // ProBasic

class Pro_0 : public ProBasic {
public:
    void product_fun() override;
}; //Pro_0

class Pro_1 : public ProBasic {
public:
    void product_fun() override;
}; //Pro_1

class Pro_2 : public ProBasic {
public:
    void product_fun() override;
}; //Pro_2


class FactoryBasic {
public:
    virtual std::shared_ptr<ProBasic> create() = 0;
}; // FactoryBasic

class Factory_0 : public FactoryBasic {
public:
    std::shared_ptr<ProBasic> create() override;
}; // Factory_0

class Factory_1 : public FactoryBasic {
public:
    std::shared_ptr<ProBasic> create() override;
}; // Factory_1

class Factory_2 : public FactoryBasic {
public:
    std::shared_ptr<ProBasic> create() override;
}; // Factory_2


void Pro_0::product_fun() {
    std::cout << "Pro_0" << std::endl;
}

void Pro_1::product_fun() {
    std::cout << "Pro_1" << std::endl;
}

void Pro_2::product_fun() {
    std::cout << "Pro_2" << std::endl;
}

std::shared_ptr<ProBasic> Factory_0::create() {
    std::cout << "Factory_0 product Pro_0" << std::endl;
    return std::make_shared<Pro_0>();
}

std::shared_ptr<ProBasic> Factory_1::create() {
    std::cout << "Factory_1 product Pro_1" << std::endl;
    return std::make_shared<Pro_1>();
}

std::shared_ptr<ProBasic> Factory_2::create() {
    std::cout << "Factory_2 product Pro_2" << std::endl;
    return std::make_shared<Pro_2>();
}

int main(){
    std::shared_ptr<Factory_0> factory_0 = std::make_shared<Factory_0>();
    factory_0->create();
    std::shared_ptr<Factory_1> factory_1 = std::make_shared<Factory_1>();
    factory_1->create();
    std::shared_ptr<Factory_2> factory_3 = std::make_shared<Factory_2>();
    factory_1->create();
    return 0;
}

Patrón de fábrica abstracto

Introducción

  En comparación con los dos primeros patrones de fábrica, el patrón de fábrica abstracto es más complicado; al igual que los métodos simples de fábrica y de fábrica mencionados anteriormente, las subclases de productos deben ser del mismo tipo y tener métodos comunes, lo que limitará la expansión de las categorías de productos; Para mejorar la escalabilidad, la fábrica abstracta clasifica los productos de la misma categoría en una categoría (es decir, un grupo de productos) y luego combina productos de diferentes grupos en familias. En este momento, el cliente no necesita saber qué fábrica produce qué familia de productos cuando lo usa. Cada fábrica de subcategoría solo produce una familia de productos. Producir los productos de la subcategoría especificada a través de la fábrica de la subcategoría especificada.
  Ventajas: 1. La creación del producto está encapsulada, por lo que no es necesario saber qué producto es, solo de qué fábrica. 2. Puede admitir diferentes tipos de productos, lo que hace que el modelo sea más flexible. 3. Es muy conveniente utilizar diferentes tipos de productos en una familia.
   Desventajas: 1. La estructura está demasiado hinchada, si hay más tipos de productos o familias de productos, no es propicia para la expansión y el mantenimiento. 2. Cada vez que agrega un grupo de productos, todas las clases de fábrica deben agregar un método, que viola el principio abierto-cerrado. Por lo tanto, generalmente se aplica a situaciones en las que la cartera y la familia de productos no han cambiado mucho.
Patrón de fábrica abstracto

código


class ProductionBasicA{
public:
    virtual void create_a() = 0;
};

class ProductionA_1 : public ProductionBasicA{
public:
    void create_a() override;
};

class ProductionA_2 : public ProductionBasicA{
public:
    void create_a() override;
};



class ProductionBasicB{
public:
    virtual void create_b() = 0;
};

class ProductionB_1 : public ProductionBasicB{
public:
    void create_b() override;
};

class ProductionB_2 : public ProductionBasicB{
public:
    void create_b() override;
};



class FactoryBasic{
public:
    virtual std::shared_ptr<ProductionBasicA> create_production_a() = 0;
    virtual std::shared_ptr<ProductionBasicB> create_production_b() = 0;
};

class Factory1: public FactoryBasic{
public:
    std::shared_ptr<ProductionBasicA> create_production_a() override;
    std::shared_ptr<ProductionBasicB> create_production_b() override;
};

class Factory2: public FactoryBasic{
public:
    std::shared_ptr<ProductionBasicA> create_production_a() override;
    std::shared_ptr<ProductionBasicB> create_production_b() override;
};

void ProductionA_1::create_a() {
    std::cout << "ProductionA_1" << std::endl;
}

void ProductionA_2::create_a() {
    std::cout << "ProductionA_2" << std::endl;
}

void ProductionB_1::create_b() {
    std::cout << "ProductionB_1" << std::endl;
}

void ProductionB_2::create_b() {
    std::cout << "ProductionB_2" << std::endl;
}

std::shared_ptr<ProductionBasicA> Factory1::create_production_a() {
    std::cout << "Factory1 product ProductionA_1" << std::endl;
    return std::make_shared<ProductionA_1>();
}

std::shared_ptr<ProductionBasicB> Factory1::create_production_b() {
    std::cout << "Factory1 product ProductionB_1" << std::endl;
    return std::make_shared<ProductionB_1>();
}

std::shared_ptr<ProductionBasicA> Factory2::create_production_a() {
    std::cout << "Factory2 product ProductionA_2" << std::endl;
    return std::make_shared<ProductionA_2>();
}

std::shared_ptr<ProductionBasicB> Factory2::create_production_b() {
    std::cout << "Factory2 product ProductionB_2" << std::endl;
    return std::make_shared<ProductionB_2>();
}


int main(){
    std::shared_ptr<Factory1> factory_1 = std::make_shared<Factory1>();
    factory_1->create_production_a();
    factory_1->create_production_b();
    std::shared_ptr<Factory2> factory_2 = std::make_shared<Factory2>();
    factory_2->create_production_a();
    factory_2->create_production_b();
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/CFH1021/article/details/109113386
Recomendado
Clasificación