项目日志——相关技术补充(2)

设计类的六大原则

  • 单一职责原则
    • 就是说每一个类只做一件事情,职责划分清晰
    • 两个不一样的功能就不能放在同一个类中,一个类中应当是一组相关性很高的函数、数据
  • 开闭原则
    • 对扩展开放,只添加新内容,对修改封闭,不修改旧内容
  • 里氏替换原则
    • 简单说就是父类能够出现完成的任务,子类也应当能够出现完成
    • 在继承类的时候,需要重写父类中的所有方法,尤其需要注意父类中的protected方法,子类尽量不要暴露自己的public方法给外界调用
  • 依赖倒置原则
    • 就是说高层模块不应该依赖底层模块,而应该依赖他原本的抽象类
    • 相同层模块之间的依赖应当通过接口来完成
  • 迪米特法则
    • 尽量减少对象之间的交互,来降低类之间的耦合度
  • 接口隔离原则
    • 不要对外部暴露没有实际意义的接口,并且接口应当精简、单一

四种设计模式及其实现

设计模式我们已经在之前有介绍过了,这里我们介绍并实现具体的四种设计模式

单例模式

一个类只能创建一个对象

在整个系统中只有一个实例,并且提供一个访问它的全局访问点,这个实例被所有程序模块共享

饿汉模式

程序启动的时候就会创建实例对象,因为单例对象已经确定了,因此比较适用于多线程环境中

多线程获取单例对象不需要加锁,可以有效避免资源竞争

class Singleton
{
public:
    static Singleton &GetInstance()
    {
        return _eton;
    }

    int GetData()
    {
        return _data;
    }

private:
    Singleton() : _data(114) {};
    ~Singleton() {};
    Singleton(const Singleton &) = delete;
    static Singleton _eton;

    int _data;
};

Singleton Singleton::_eton;

int main()
{
    std::cout << Singleton::GetInstance().GetData() << std::endl;
    return 0;
}
懒汉模式

在effective C++中有一种更加简单优雅的单例模式,静态变量能够在满足线程安全的前提下完成懒汉模式的设计

这是在C++11之后才支持的,定义的是静态局部对象

class Singleton
{
public:
    static Singleton& GetInstance()
    {
        static Singleton _eton;
        return _eton;
    }

    int GetData()
    {
        return _data;
    }

private:
    Singleton() : _data(114) {

    };
    ~Singleton() {};
    Singleton(const Singleton &) = delete;

    int _data;
};

工厂模式

工厂模式是一种创建类型的设计模式,主要是用于创建对象

因此在工厂模式中,我们创建对象时不会对上层暴露创建的逻辑,而是用一个共同的结构来指向新创建的对象,以此来实现创建于使用的分离

简单说就是,我们我们可以通过创建一个工厂,再交给他一个类型,让这个工厂来创建对应类型的实例

简单工程模式

简单工厂模式指的是,由一个工厂对象,通过类型决定创建出来的产品类的实例

假设有一个工厂可以生产水果,就可以告诉工厂我们需要的水果品类,他就可以给我们生产了

#include <iostream>
#include <memory>

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        std::cout << "苹果" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        std::cout << "香蕉" << std::endl;
    }
};

class FruitFactory
{
public:
    static std::shared_ptr<Fruit> create(const std::string &name)
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else
        {
            return std::make_shared<Banana>();
        }

    }
};

int main()
{
    std::shared_ptr<Fruit> fruit1 = FruitFactory::create("苹果");
    std::shared_ptr<Fruit> fruit2 = FruitFactory::create("香蕉");
    fruit1->name();
    fruit2->name();
    return 0;
}

这种方式的缺点就是,当产生了新的子类时,就需要重新对create继续开发了

工厂方法模式

一个产品对应一个工厂,新增一个产品的时候,就新增一个工厂

#include <iostream>
#include <memory>

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        std::cout << "苹果" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        std::cout << "香蕉" << std::endl;
    }
};

class FruitFactory
{
    public:
        virtual std::shared_ptr<Fruit> create() = 0;
};

class AppleFactory : public FruitFactory
{
    std::shared_ptr<Fruit> create() override
    {
        return std::make_shared<Apple>();
    }
};

class BananaFactory : public FruitFactory
{
    std::shared_ptr<Fruit> create() override
    {
        return std::make_shared<Banana>();
    }
};

int main()
{
    std::shared_ptr<FruitFactory> ff1(new AppleFactory());
    std::shared_ptr<Fruit> fruit1 = ff1->create();
    std::shared_ptr<FruitFactory> ff2(new BananaFactory());
    std::shared_ptr<Fruit> fruit2 = ff2->create();
    fruit1->name();
    fruit2->name();
    return 0;
}

这里不好的地方就是,当类比较多时,需要创建的工厂就比较多,比较浪费

抽象工厂模式

简单理解就是,有一个超级工厂,可以生产工厂子类,再由工厂子类生产具体产品,如果你玩过钢铁雄心4的话,就能理解,民用工厂可以生产军用工厂,军用工厂可以生产具体装备

大工厂生产小工厂,小工厂生产产品

#include <iostream>
#include <memory>

class Fruit
{
public:
    virtual void name() = 0;
};

class Apple : public Fruit
{
public:
    void name() override
    {
        std::cout << "苹果" << std::endl;
    }
};

class Banana : public Fruit
{
public:
    void name() override
    {
        std::cout << "香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void name() = 0;
};

class Cat : public Animal
{
public:
    void name() override
    {
        std::cout << "小猫" << std::endl;
    }
};

class Dog : public Animal
{
public:
    void name() override
    {
        std::cout << "小狗" << std::endl;
    }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> CreateFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> CreateAnimal(const std::string &name) = 0;
};

class AnimalFactory : public Factory
{
public:
    std::shared_ptr<Fruit> CreateFruit(const std::string &name) override
    {
        return nullptr;
    }
    std::shared_ptr<Animal> CreateAnimal(const std::string &name) override
    {
        if (name == "小猫")
        {
            return std::make_shared<Cat>();
        }
        else
        {
            return std::make_shared<Dog>();
        }
    }
};

class FruitFactory : public Factory
{
public:
    std::shared_ptr<Fruit> CreateFruit(const std::string &name) override
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else
        {
            return std::make_shared<Banana>();
        }
    }
    std::shared_ptr<Animal> CreateAnimal(const std::string &name) override
    {
        return nullptr;
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> create(const std::string &name)
    {
        if (name == "动物工厂")
            return std::make_shared<AnimalFactory>();
        else
            return std::make_shared<FruitFactory>();
    }
};

int main()
{
    // 创建动物工厂
    std::shared_ptr<Factory> animalFactory = FactoryProducer::create("动物工厂");
    std::shared_ptr<Animal> cat = animalFactory->CreateAnimal("小猫");
    std::shared_ptr<Animal> dog = animalFactory->CreateAnimal("小狗");

    cat->name(); // 输出“小猫”
    dog->name(); // 输出“小狗”

    // 创建水果工厂
    std::shared_ptr<Factory> fruitFactory = FactoryProducer::create("水果工厂");
    std::shared_ptr<Fruit> apple = fruitFactory->CreateFruit("苹果");
    std::shared_ptr<Fruit> banana = fruitFactory->CreateFruit("香蕉");

    apple->name();  // 输出“苹果”
    banana->name(); // 输出“香蕉”

    return 0;
}

建造者模式

建造者模式是一种创建型的设计模式,用多个简单的对象一步步构建成一个复杂的对象

能够将一个纷杂的对象的构建和他的表示分离,提供一种创建对象的最佳方式

主要用于解决对象构建过于复杂的问题

建造者模式主要基于四个核心类的实现

  • 抽象产品类
  • 具体产品类:一个具体的产品对象类
  • 抽象Builder类:创建一个产品对象所需要的各个部件的抽象接口
  • 具体产品的Builder类:实现抽象接口,构建各个部件
  • 指挥者Director类:统一构建过程,提供给调用者使用,通过指挥者来获取产品
#include <iostream>
#include <string>
#include <memory>

// 抽象产品类:Phone
class Phone
{
public:
    Phone() {}
    void setBoard(const std::string &board)
    {
        _board = board;
    }
    void setDisplay(const std::string &display)
    {
        _display = display;
    }
    void show()
    {
        std::cout << "OS: " << _os << " | Board: " << _board << " | Display: " << _display << std::endl;
    }
    virtual void setOs() = 0;

protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

// 具体产品类:iPhone
class iPhone : public Phone
{
public:
    void setOs() override
    {
        _os = "iOS 17";
    }
};

// 抽象Builder类
class Builder
{
public:
    virtual void buildBoard(const std::string &board) = 0;
    virtual void buildDisplay(const std::string &display) = 0;
    virtual void buildOs() = 0;
    virtual std::shared_ptr<Phone> build() = 0;
};

// 具体产品的Builder类:iPhoneBuilder
class iPhoneBuilder : public Builder
{
public:
    iPhoneBuilder() : _phone(std::make_shared<iPhone>()) {}

    void buildBoard(const std::string &board) override
    {
        _phone->setBoard(board);
    }

    void buildDisplay(const std::string &display) override
    {
        _phone->setDisplay(display);
    }

    void buildOs() override
    {
        _phone->setOs();
    }

    std::shared_ptr<Phone> build() override
    {
        return _phone;
    }

private:
    std::shared_ptr<Phone> _phone;
};

// Director类:用于控制构建流程
class Director
{
public:
    Director(Builder *bd) : _builder(bd) {}

    void construct(const std::string &board, const std::string &display)
    {
        _builder->buildBoard(board);
        _builder->buildDisplay(display);
        _builder->buildOs();
    }

private:
    Builder *_builder;
};

// 主函数
int main()
{
    // 创建iPhone构建器
    Builder *builder = new iPhoneBuilder();
    
    // 通过Director构建iPhone
    std::unique_ptr<Director> director(new Director(builder));
    director->construct("华硕", "三星");

    // 获取构建好的iPhone
    std::shared_ptr<Phone> iphone = builder->build();
    iphone->show();

    delete builder; // 释放内存
    return 0;
}

代理模式

有些对象不适宜被直接访问,就可以让代理对象在中间起一个中介的作用

这里代理也分为静态代理和动态代理,可以分别对应上面的饿汉模式和懒汉模式,是类似的

动态代理还涉及到许多其他知识,这里我们先不做介绍

#include <iostream>
#include <string>

class RentHouse
{
public:
    virtual void rentHouse() = 0;
};

class Landlord : public RentHouse
{
public:
    void rentHouse() override
    {
        std::cout << "租房子了" << std::endl;
    }
};

class Intermediary : public RentHouse
{
public:
    void rentHouse() override
    {
        std::cout << "发布公告" << std::endl;
        std::cout << "看房" << std::endl;
        _landlord.rentHouse();
        std::cout << "售后" << std::endl;
    }

private:
    Landlord _landlord;
};

int main()
{
    Intermediary intermediary;
    intermediary.rentHouse();
    return 0;
}

这里主要是给功能加强的意思

让原来的对象,能够完成他功能以外的模式

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栖林_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值