《设计模式的艺术》笔记 - 简单工厂模式

介绍

        定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有相同的父类。因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又被称为静态工厂方法模式,属于类创建型模式

实现

class Product {
public:
    void methodSame() { // 公共方法的实现
        std::cout << "methodSame" << std::endl;
    }

    virtual void methodDiff() = 0;  // 抽象方法的声明,由具体产品实现
};

class ConcreteProductA : public Product {
public:
    void methodDiff() override {
        std::cout << "ConcreteProductA" << std::endl;
    }
};

class ConcreteProductB : public Product {
public:
    void methodDiff() override {
        std::cout << "ConcreteProductB" << std::endl;
    }
};

class Factory {
public:
    static Product *getProduct(std::string arg) {
        Product *product = NULL;
        if (arg == "A") {
            product = new ConcreteProductA();
        } else if (arg == "B") {
            product = new ConcreteProductB();
        }
        return product;
    }
};


int main() {
    Product *A = Factory::getProduct("A");
    A->methodSame();
    A->methodDiff();
    Product *B = Factory::getProduct("B");
    B->methodSame();
    B->methodDiff();
    return 0;
}

简单工厂模式的简化

        将Factory合并到父类Product中,此时必须分别在头文件和源代码文件中分开编写,不然编译报错

class Product {
public:
    void methodSame();

    virtual void methodDiff() = 0;  // 抽象方法的声明,由具体产品实现

    static Product *getProduct(std::string arg);
};

class ConcreteProductA : public Product {
public:
    void methodDiff() override;
};

class ConcreteProductB : public Product {
public:
    void methodDiff() override;
};
#include "myclass.h"

void Product::methodSame() { // 公共方法的实现
    std::cout << "methodSame" << std::endl;
}

Product* Product::getProduct(std::string arg) {
    Product *product = NULL;
    if (arg == "A") {
        product = new ConcreteProductA();
    } else if (arg == "B") {
        product = new ConcreteProductB();
    }
    return product;
}

void ConcreteProductA::methodDiff() {
    std::cout << "ConcreteProductA" << std::endl;
}

void ConcreteProductB::methodDiff() {
    std::cout << "ConcreteProductB" << std::endl;
}

总结

        优点:       

        1. 工厂类包含必要的判断逻辑,可以决定什么时候创建哪一个产品类的实例。

        2. 客户端无须知道所创建的具体产品类的类名,只需要知道对应的参数即可。

        3. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

        缺点:

        1. 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。

        2. 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。

        3. 系统扩展困难。一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

        4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

练习

        使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制draw()和擦除erase()两个方法,要求在绘制不支持的几何图形时,提示一个UnSupportedShapeException。

myclass.h

//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_CLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>

class Graphical {
public:
    virtual void draw() = 0;

    virtual void erase() = 0;

    static Graphical *getGraphical(std::string arg);
};

class Circle : public Graphical {
public:
    void draw() override;

    void erase() override;
};

class Square : public Graphical {
public:
    void draw() override;

    void erase() override;
};

class Triangle : public Graphical {
public:
    void draw() override;

    void erase() override;
};

class UnSupportedShapeException : public std::exception {
public:
    UnSupportedShapeException() {};
    ~UnSupportedShapeException() {};
    const char* what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT override;
};

#endif //DESIGNPATTERNS_CLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"

Graphical* Graphical::getGraphical(std::string arg) {
    if (arg == "circle") {
        return new Circle();
    } else if (arg == "square") {
        return new Square();
    } else if (arg == "triangle") {
        return new Triangle();
    } else {
        throw UnSupportedShapeException();
    }
}

void Circle::draw() {
    std::cout << "Draw circle" << std::endl;
}

void Circle::erase() {
    std::cout << "Erase circle" << std::endl;
}

void Square::draw() {
    std::cout << "Draw square" << std::endl;
}

void Square::erase() {
    std::cout << "Erase square" << std::endl;
}

void Triangle::draw() {
    std::cout << "Draw triangle" << std::endl;
}

void Triangle::erase() {
    std::cout << "Erase triangle" << std::endl;
}

const char* UnSupportedShapeException::what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT {
    return "Unsupported shape";
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Graphical *graph;
    try {
        graph = Graphical::getGraphical("circle");
        graph->draw();
        graph->erase();
        graph = Graphical::getGraphical("square");
        graph->draw();
        graph->erase();
        graph = Graphical::getGraphical("triangle");
        graph->draw();
        graph->erase();
        graph = Graphical::getGraphical("unknown");
        graph->draw();
        graph->erase();
    } catch (const std::exception &e) {
        std::cout << e.what() << std::endl;
    }
    return 0;
}

相关推荐

  1. 设计模式艺术笔记 - 工厂方法模式

    2024-01-13 06:50:02       48 阅读
  2. 设计模式艺术笔记 - 抽象工厂模式

    2024-01-13 06:50:02       50 阅读
  3. 设计模式艺术笔记 - 原型模式

    2024-01-13 06:50:02       51 阅读
  4. 设计模式艺术笔记 - 适配器模式

    2024-01-13 06:50:02       48 阅读
  5. 设计模式艺术笔记 - 外观模式

    2024-01-13 06:50:02       49 阅读
  6. 设计模式艺术笔记 - 组合模式

    2024-01-13 06:50:02       37 阅读
  7. 设计模式艺术笔记 - 装饰模式

    2024-01-13 06:50:02       52 阅读
  8. 设计模式艺术笔记 - 命令模式

    2024-01-13 06:50:02       50 阅读
  9. 设计模式艺术笔记 - 备忘录模式

    2024-01-13 06:50:02       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-13 06:50:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-13 06:50:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-13 06:50:02       82 阅读
  4. Python语言-面向对象

    2024-01-13 06:50:02       91 阅读

热门阅读

  1. 树莓派 gpio 安装及简单使用

    2024-01-13 06:50:02       72 阅读
  2. Seata 以 Nacos 为注册中心启动

    2024-01-13 06:50:02       68 阅读
  3. 【算法题】49. 字母异位词分组

    2024-01-13 06:50:02       58 阅读
  4. 服务优雅停机SpringBoot

    2024-01-13 06:50:02       60 阅读
  5. 关于@KafkaListener动态订阅消费topic的调研

    2024-01-13 06:50:02       56 阅读
  6. 编程笔记 html5&css&js 036 CSS应用方式

    2024-01-13 06:50:02       53 阅读
  7. 基于多媒体的深度学习 Midreport自我总结分析

    2024-01-13 06:50:02       57 阅读
  8. 计算机网络概述

    2024-01-13 06:50:02       65 阅读
  9. 逢试必考的二分查找(算法村第九关青铜挑战)

    2024-01-13 06:50:02       59 阅读