设计模式

        设计模式是提高代码的可复用性、可维护性、可读性、稳健性以及安全性的解决方案

设计模式六大原则

        

用抽象构建框架,用实现扩展细节。

• 单⼀职责原则告诉我们实现类要职责单⼀;

• ⾥⽒替换原则告诉我们不要破坏继承体系;

• 依赖倒置原则告诉我们要⾯向接⼝编程;

• 接⼝隔离原则告诉我们在设计接⼝的时候要精简单⼀;

• 迪⽶特法则告诉我们要降低耦合;

• 开闭原则是总纲,告诉我们要对扩展开放,对修改关闭。

工厂模式

        工厂模式是创建型设计模式,提供了一种创建对象的有效方式,在工厂模式中,客户程序不需要了解具体对象是如何创建的,而是使用共同结构体指向新创建的对象,实现创建和使用的分离。

简单工厂模式

        简单工厂模式实际上就是专门定义一个类来创建其他类的实例,能减少客户程序对类创建过程的依赖。简单工厂模式通常涉及三个部分:

        工厂类:负责创建对象实例,通常包含一个静态方法(可以直接通过类名调用),根据传入的参数返回对应的对象实例。

        产品类:工厂类创建的对象类,通常实现相同的接口和继承自相同的基类。

        客户端代码:调用工厂提供的方法创建产品类,并不需要调用产品类的构造函数。

        为了帮助大家理解简单工厂模式,我们来写一份简单工厂模式的代码:

Factory.hpp

#include<iostream>
#include<memory>
#include<string>
class Shape
{
public:
    // const在括号后面,表示不会修改成员变量
    virtual void draw() const = 0; // 纯虚函数,由子类重写从而实现多态
    virtual ~Shape() = default; // 虚析构函数,保证首先调用派生类的析构函数
};
class Circle: public Shape
{
public:
    void draw() const override
    {
        std::cout << "draw a circle" << std::endl;
    }
};
class Rectangle: public Shape
{
public:
    void draw() const override
    {
        std::cout << "draw a rectangle" << std::endl;
    }
};
class Triangle: public Shape
{
public:
    void draw() const override
    {
        std::cout << "draw a triangle" << std::endl;
    }
};
class Factory
{
public:
    static std::unique_ptr<Shape> CreateShape(const std::string &type)
    {
        if(type == "circle")
        {
            return std::make_unique<Circle>();
        }
        else if(type == "rectangle")
        {
            return std::make_unique<Rectangle>();
        }
        else if(type == "triangle")
        {
            return std::make_unique<Triangle>();
        }
        return nullptr;
    }
};

test.cc

#include "Factory.hpp"
int main()
{
    auto shape1 = Factory::CreateShape("circle");
    auto shape2 = Factory::CreateShape("rectangle");
    auto shape3 = Factory::CreateShape("triangle");

    if(shape1) shape1->draw();
    if(shape2) shape2->draw();
    if(shape3) shape3->draw();
}

        

工厂方法模式

        工厂方法模式通过定义一个创建对象的接口,让子类决定实例化哪种具体的类。于是客户程序不依赖某个具体的类,而依赖于工厂接口。工厂方法模式通常涉及以下四个部分:

        产品接口:定义了工厂方法所创建的对象的接口。

        具体产品类:实现产品接口的具体类,一个具体产品对应一种具体实现。

        工厂接口:声明一个工厂方法,用于返回产品类型的对象,该方法是抽象方法,由具体工厂类实现。

        具体工厂类:继承工厂接口,实现工厂方法,返回具体产品类的实例。

        同样的,为了帮助大家理解工厂方法模式,我们写一份工厂方法模式的代码:

#include <iostream>
#include <memory>

// 产品接口
class Document
{
public:
    virtual void open() const = 0;
    virtual ~Document() = default;
};

// 具体产品类
class TXTdocument: public Document
{
public: 
    void open() const override
    {
        std::cout << "make a TXT file" << std::endl;
    }
};

class PDFdocument: public Document
{
public: 
    void open() const override
    {
        std::cout << "make a PDF file" << std::endl;
    }
};

// 工厂接口
class Application
{
public:
    virtual ~Application() = default;
    virtual std::unique_ptr<Document> CreateDocument() = 0;
    void newDocument()
    {
        auto doc = CreateDocument();
        doc->open();
    }
};

// 具体工厂实现
class TxtApplication: public Application
{
public:
    std::unique_ptr<Document> CreateDocument() override
    {
        return std::make_unique<TXTdocument>();
    }
};
class PdfApplication: public Application
{
public:
    std::unique_ptr<Document> CreateDocument() override
    {
        return std::make_unique<PDFdocument>();
    }
};
#include "Factory.hpp"

int main()
{
    auto app1 = std::make_unique<PdfApplication>();
    app1->newDocument();
    
    auto app2 = std::make_unique<TxtApplication>();
    app2->newDocument();
    return 0;
}

        工厂方法模式相对于简单工厂模式的优势是封装性更好,客户程序不需要直到具体的产品类,只需要知道工厂类;并且扩展性更好,增加新的产品类不需要修改工厂类代码。

抽象工厂模式

        抽象工厂模式提供一个接口,用于创建一系列相关的对象,无需指定具体的类,可认为是多个工厂方法模式的组合,用于创建一组相关的对象。抽象工厂模式分为五个部分:

        抽象工厂:定义了创建一系列相关对象的接口。通常会包含多个工厂方法,每个方法负责创建一种产品。

        具体工厂:实现抽象工厂接口,提供创建具体产品对象的实现。每个具体工厂对应一个产品族。

        抽象产品:为一类产品定义接口,这些接口由具体产品实现。

        具体产品:实现抽象产品接口的具体对象。

        客户端:通过使用抽象工厂接口来创建一组相关的产品,而无需直接依赖于具体工厂或具体产品的类。

#include <iostream>
#include <memory>

// 抽象产品
class Button
{
public:
    virtual ~Button() = default;
    virtual void paint() const = 0;
};

class TextBox
{
public:
    virtual ~TextBox() = default;
    virtual void render() const = 0;
};

// 具体产品
class WindowsButton: public Button
{
public:
    void paint() const override
    {
        std::cout << "paint a Windows button" << std::endl;
    }
};

class MacButton: public Button
{
public:
    void paint() const override
    {
        std::cout << "paint a Mac button" << std::endl;
    }
};

class WindowsTextBox: public TextBox
{
public:
    void render() const override
    {
        std::cout << "render a Windows textbox" << std::endl;
    }
};

class MacTextBox: public TextBox
{
public:
    void render() const override
    {
        std::cout << "render a Mac textbox" << std::endl;
    }
};

// 抽象工厂
class Factory
{
public:
    virtual std::unique_ptr<Button> CreateButton() = 0;
    virtual std::unique_ptr<TextBox> CreateTextBox() = 0;
};

// 具体工厂实现
class WindowsFactory: public Factory
{
public:
    std::unique_ptr<Button> CreateButton() override
    {
        return std::make_unique<WindowsButton>();
    }
    std::unique_ptr<TextBox> CreateTextBox() override
    {
        return std::make_unique<WindowsTextBox>();
    }
};
class MacFactory: public Factory
{
public:
    std::unique_ptr<Button> CreateButton() override
    {
        return std::make_unique<MacButton>();
    }
    std::unique_ptr<TextBox> CreateTextBox() override
    {
        return std::make_unique<MacTextBox>();
    }
};
#include "Factory.hpp"

void CreateUI(Factory &factory)
{
    auto button = factory.CreateButton();
    auto textbox = factory.CreateTextBox();

    button->paint();
    textbox->render();
}
int main()
{
    WindowsFactory wf;
    MacFactory mf;

    CreateUI(wf);
    CreateUI(mf);
    return 0;
}

        抽象工厂模式相对于工厂方法模式的优势在于,提供了更高层次的抽象,支持同时创建多个产品族的对象,能处理更复杂的情况;并且增加新的产品族非常容易,只需要添加新的具体工厂和产品类。

三种模式的总结

        简单工厂模式:适用于创建对象种类少,创建逻辑简单的情况。缺点是扩展性差,适合小型系统。

        工厂方法模式:适用于产品种类多,且需要频繁扩展产品种类的情况。每个工厂类负责生产单一产品,易于扩展和维护。

        抽象工厂模式:适用于需要创建一组相关联对象的场景,并需要保持产品族的一致性。扩展新的产品族容易,但扩展产品类型复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值