设计模式概念学习

这篇具有很好参考价值的文章主要介绍了设计模式概念学习。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


以下为学习时对各种设计模式的简单理解,还没有深入学习和实际应用,推荐1个 很棒的网站学习设计模式,每个模式都有遇到的痛点和解决的方法,还有2~3个应用场景,各种语言的代码示例,简明准确的UML类图,精美可爱的配图,推荐大家去看。

创建类型

单例模式

饿汉

构建时就创建

懒汉

  1. 单线程-访问到的时候才创建
  2. 多线程-低效率
    做法:加锁->若未创建则创建->获取资源->解锁
    缺点:效率低,每次访问之前都要加锁,资源创建之后不能被同时被多个线程访问
  3. 多线程-双重判断
    做法:判断资源未存在->加锁->二次判断资源未存在->创建资源->解锁->获取资源
    原因:先判断资源是否存在,只有第1次判断到资源不存在才需要加锁,当资源创建之后就不用再加锁了,多线程在大部分情况下可同时访问,提高资源访问效率;在加锁之后需要再次判断资源是否存在,可能在第1次判断和拿到锁的时间间隙中资源已经被其他线程访问和创建了,因此需要二次判断。
openbmc项目实际应用

在bmcweb/include/sessions.hpp中,有1个类用来管理web session的类SessionStore。其创建方式就是单例模式,且是第一次使用到这个对象才会创建这个对象:

class SessionStore
{
  public:
    static SessionStore& getInstance()
    {
        static SessionStore sessionStore;
        return sessionStore;
    }
    ...
};

其他类需要用到此类方法时,都需通过getInstance()方法来获得SessionStore类唯一的对象sessionStore,如有1个用户登录web之后,需要新增1个web session,则需要通过getInstance()方法,将新的web session的信息保留在SessionStore唯一的对象中:

    // User is authenticated - create session
    std::shared_ptr<persistent_data::UserSession> session =
        persistent_data::SessionStore::getInstance().generateUserSession(
            username, req.ipAddress, clientId,
            persistent_data::PersistenceType::TIMEOUT, isConfigureSelfOnly);

项目中为什么使用单例模式呢?

  1. 作为全局管理对象:SessionStore作为管理类,起到的是全局统领的作用,只需要1个对象就够了,多个对象反而使管理变得混乱
  2. 节约资源:SessionStore中保存着所有web session的信息,若可创建多个对象,则会引起相同web session拷贝,session发生变化还要使用一些同步机制保证不同SessionStore对象的同步。
  3. 统一文件的访问:在关闭BMC前可能连接着一些web session,关闭前需要将这些数据保存到起来,重启后要重新获取,单例保证只有1个对象对文件进行读写,避免重复读写。

工厂方法

当多种产品都继承于同1个基类,如美的空调和海尔空调都继承空调类,则可使用工厂方法。让多个工厂类继承于同1个工厂基类,对应去生产不同产品。

简单工厂方法

参考链接
多种产品继承同1个基类,可创建1个工厂类,根据不同的参数,以调用不同产品类的构造函数,来创建出不同的产品

openbmc项目实际应用

phosphor-pid-control是风扇控制模块,根据当前温度传感器/风扇转速/调速参数,使用PID算法来设置风扇目标转速。此模块中的主要类图如下:

  1. Controller:控制器,为纯虚类,作用是通过inputProc获取输入值,通过process和获得的输入值以计算输出值,通过outputProc让输出值起作用。
  2. PIDController:PID控制器,将输入值和目标值作为PID算法的参数,以获取输出值。
  3. StepwiseController:简单的温度控制器,维护1个阶梯式的温度-转速的表格,每个温度范围对应1个目标转速。输入值为多个传感器温度的最大值,输出值为最大温度对应的目标转速,会将目标转速交给FanController处理。
  4. ThermalController:温度控制器,采用PID算法,将所有温度传感器获得的最大温度作为输入值,但不设目标值,根据PID算法计算最终的目标转速,会将目标转速交给FanController处理。
  5. FanController:风扇控制器,采用PID算法,将所有温度控制器获得的目标转速的最大值作为目标值,将风扇当前值作为输入值,根据PID算法计算最终的目标转速,并将此值写入风扇背板的CPLD寄存器中,最终控制风扇转速。
  6. zone:将物理区域抽象成1个类,每个区域都有一至多个硬件温度传感器和风扇,一至多个虚拟温度控制器和风扇控制,控制风扇转速以确保每个区域的硬件在适宜温度内。

在phosphor-pid-control/pid/builder.cpp中的buildZones函数,用来创建zone对象,根据json文件中的控制器类型的配置值来决定创建的控制器类型。创建zone的函数其实就可以视为1个简单工厂,创建控制器对象时,获取的参数均是用户在json文件中的配置。

std::unordered_map<int64_t, std::shared_ptr<ZoneInterface>>
    buildZones(...)
{
		...
        // For each PID create a Controller and a Sensor.
        for (const auto& [name, info] : pidConfig)
        {
        	...
            if (info.type == "fan")
            {
            	...
                auto pid = FanController::createFanPid(zone.get(), name, inputs,
                                                       info.pidInfo);
				zone->addFanPID(std::move(pid));
            	...
            }
            else if (isThermalType(info.type))
            {
            	...
                auto pid = ThermalController::createThermalPid(
                    zone.get(), name, inputs, info.setpoint, info.pidInfo,
                    getThermalType(info.type));
                zone->addThermalPID(std::move(pid));
            	...
            }
            else if (info.type == "stepwise")
            {
            	...
                auto stepwise = StepwiseController::createStepwiseController(
                    zone.get(), name, inputs, info.stepwiseInfo);
                zone->addThermalPID(std::move(stepwise));
               ...
            }
    }
}

创建具体控制器对象方法的createXXXController其实是每个控制器类的静态成员函数。

static std::unique_ptr<Controller> StepwiseController::createStepwiseController(
    ZoneInterface* owner, const std::string& id,
    const std::vector<std::string>& inputs, const ec::StepwiseInfo& initial)
{
    // StepwiseController requires at least 1 input
    if (inputs.empty())
    {
        throw ControllerBuildException("Stepwise controller missing inputs");
    }

    auto thermal = std::make_unique<StepwiseController>(id, inputs, owner);
    thermal->setStepwiseInfo(initial);

    return thermal;
}

为什么这个场景像简单工厂模式:文章来源地址https://www.toymoban.com/news/detail-701330.html

  1. 系统耦合度较低:用户想创建控制器对象时,只需要根据规范,在json文件中配置控制器的属性如下:type"fan"则会创建1个风扇控制器,不用关注任何代码层面的细节,而且所有控制器。根本就不是了啦!
"pids": [
    {
        "name": "fan1-5",
        "type": "fan",
        "inputs": ["fan1", "fan5"],
        "setpoint": 90.0,
    }
]

抽象工厂

到了这里,关于设计模式概念学习的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包