2026/1/7 12:46:22
网站建设
项目流程
网上如何建网站卖量具,欧米茄表官方官网,无锡公司网站设计,wp wordpress教程设计模式模块详解 #x1f3a8; 一句话概括#xff1a;设计模式模块提供了单例模式和观察者模式的现成实现#xff0c;让你的代码更优雅、更易维护。 #x1f4da; 目录
什么是设计模式#xff1f;模块组件一览单例模式 - Singleton延迟单例 - DelayedSingleton引用延迟单…设计模式模块详解一句话概括设计模式模块提供了单例模式和观察者模式的现成实现让你的代码更优雅、更易维护。 目录什么是设计模式模块组件一览单例模式 - Singleton延迟单例 - DelayedSingleton引用延迟单例 - DelayedRefSingleton观察者模式 - Observer模式对比与选择使用示例与最佳实践1. 什么是设计模式1.1 通俗理解设计模式就像建筑图纸不用每次都从零开始设计经过验证的解决方案让其他开发者一看就懂1.2 c_utils 提供的设计模式单例变体设计模式Singleton饿汉式DelayedSingleton懒汉式智能指针DelayedRefSingleton懒汉式裸指针单例模式Singleton观察者模式Observer2. 模块组件一览组件类型特点线程安全Singleton饿汉式单例程序启动时创建✅DelayedSingleton懒汉式单例首次使用时创建智能指针管理✅DelayedRefSingleton懒汉式单例首次使用时创建裸指针管理✅Observable被观察者维护观察者列表发送通知✅Observer观察者接收通知执行更新-3. 单例模式 - Singleton3.1 什么是单例模式单例模式确保一个类只有一个实例并提供全局访问点。单例类唯一实例GetInstanceGetInstanceGetInstance普通类对象1new MyClassnew MyClass对象2new MyClass对象33.2 Singleton饿汉式特点程序启动时就创建实例简单但可能浪费资源。SingletonT-static T instance_GetInstance()实现原理templatetypenameTclassSingleton:publicNoCopyable{public:staticTGetInstance(){returninstance_;}private:staticT instance_;// 静态成员程序启动时初始化};templatetypenameTT SingletonT::instance_;使用方式#includesingleton.h// 方式1使用宏声明classConfigManager{DECLARE_SINGLETON(ConfigManager)public:voidLoadConfig(){/* ... */}std::stringGetValue(conststd::stringkey){/* ... */}};// 使用ConfigManagerconfigSingletonConfigManager::GetInstance();config.LoadConfig();// 方式2手动实现classLogger{public:staticLoggerGetInstance(){returnSingletonLogger::GetInstance();}voidLog(conststd::stringmsg){std::coutmsgstd::endl;}private:friendSingletonLogger;Logger()default;~Logger()default;Logger(constLogger)delete;Loggeroperator(constLogger)delete;};// 使用Logger::GetInstance().Log(Hello);3.3 生命周期main()静态初始化Singleton实例程序启动创建实例实例已存在GetInstance()返回引用GetInstance()返回同一引用程序结束销毁实例main()静态初始化Singleton实例4. 延迟单例 - DelayedSingleton4.1 概述DelayedSingleton是懒汉式单例特点⏰延迟创建首次调用 GetInstance 时才创建线程安全双重检查锁定DCL自动管理使用 shared_ptr 管理内存4.2 类结构DelayedSingletonT-static std::shared_ptrT instance_-static std::mutex mutex_GetInstance()DestroyInstance()4.3 实现原理templatetypenameTclassDelayedSingleton:publicNoCopyable{public:staticstd::shared_ptrTGetInstance(){if(instance_nullptr){// 第一次检查无锁std::lock_guardstd::mutexlock(mutex_);// 加锁if(instance_nullptr){// 第二次检查有锁std::shared_ptrTtemp(new(std::nothrow)T);instance_temp;}}returninstance_;}staticvoidDestroyInstance(){std::lock_guardstd::mutexlock(mutex_);if(instance_!nullptr){instance_.reset();instance_nullptr;}}private:staticstd::shared_ptrTinstance_;staticstd::mutex mutex_;};4.4 双重检查锁定DCL否是否是GetInstanceinstance_ nullptr?返回 instance_加锁instance_ nullptr?解锁创建实例instance_ 新实例为什么需要两次检查线程1线程2互斥锁instance_nullptr检查1: nullptr? ✓检查1: nullptr? ✓获取锁 等待锁...检查2: nullptr? ✓创建实例释放锁 获取锁 检查2: nullptr? ✗不再创建释放锁 线程1线程2互斥锁instance_4.5 使用方式#includesingleton.hclassDatabasePool{DECLARE_DELAYED_SINGLETON(DatabasePool)public:voidConnect(){/* ... */}voidQuery(conststd::stringsql){/* ... */}};// 实现构造和析构DatabasePool::DatabasePool(){std::cout数据库连接池创建std::endl;}DatabasePool::~DatabasePool(){std::cout数据库连接池销毁std::endl;}// 使用voidUseDatabasePool(){// 获取实例首次调用时创建autopoolDelayedSingletonDatabasePool::GetInstance();pool-Connect();pool-Query(SELECT * FROM users);// 可以主动销毁DelayedSingletonDatabasePool::DestroyInstance();}4.6 shared_ptr 的优势shared_ptrshared_ptrGetInstanceGetInstance引用计数管理自动释放普通指针裸指针GetInstanceGetInstance谁来 delete?可能泄漏或重复释放5. 引用延迟单例 - DelayedRefSingleton5.1 概述DelayedRefSingleton与 DelayedSingleton 类似但返回引用而不是智能指针⚠️手动管理不会自动销毁5.2 类结构DelayedRefSingletonT-static T* instance_-static std::mutex mutex_GetInstance()5.3 与 DelayedSingleton 对比特性DelayedSingletonDelayedRefSingleton返回类型shared_ptrTT内存管理自动引用计数手动DestroyInstance✅ 有❌ 无使用方式-访问.访问适用场景需要灵活管理生命周期全程序生命周期5.4 使用方式#includesingleton.hclassAppConfig{DECLARE_DELAYED_REF_SINGLETON(AppConfig)public:voidLoad(){/* ... */}std::stringGet(conststd::stringkey){returnvalue;}};AppConfig::AppConfig(){std::cout配置加载std::endl;}AppConfig::~AppConfig(){std::cout配置卸载std::endl;}// 使用voidUseAppConfig(){// 获取引用AppConfigconfigDelayedRefSingletonAppConfig::GetInstance();config.Load();std::string valueconfig.Get(key);}6. 观察者模式 - Observer6.1 什么是观察者模式观察者模式定义了对象间的一对多依赖关系当一个对象状态改变时所有依赖它的对象都会收到通知。观察者模式通知通知通知Observer1Subject被观察者Observer2Observer36.2 生活中的例子微信公众号推送文章推送文章推送文章关注关注关注用户1Observer公众号Observable用户2Observer用户3Observer6.3 类结构通知1*使用接收«struct»ObserverArgvirtual ~ObserverArg()Observable#std::setshared_ptrObserver obs#std::mutex mutex_-bool changed_AddObserver(o)RemoveObserver(o)RemoveAllObservers()NotifyObservers()NotifyObservers(arg)GetObserversCount() : int#HasChanged() : bool#SetChanged()#ClearChanged()«interface»ObserverUpdate(o, arg) : void6.4 核心方法Observable被观察者方法说明AddObserver(o)添加观察者RemoveObserver(o)移除观察者RemoveAllObservers()移除所有观察者NotifyObservers()通知所有观察者无参数NotifyObservers(arg)通知所有观察者带参数SetChanged()标记状态已改变ClearChanged()清除改变标记HasChanged()检查是否有改变Observer观察者方法说明Update(o, arg)收到通知时的回调纯虚函数6.5 通知流程SubjectObserver1Observer2状态改变SetChanged()NotifyObservers(arg)ClearChanged()Update(this, arg)处理通知Update(this, arg)处理通知不通知alt[HasChanged() true][HasChanged() false]SubjectObserver1Observer26.6 使用示例定义被观察者#includeobserver.h#includeiostreamusingnamespaceOHOS;// 自定义参数structStockPriceArg:publicObserverArg{std::string symbol;doubleprice;StockPriceArg(conststd::strings,doublep):symbol(s),price(p){}};// 股票行情被观察者classStockMarket:publicObservable{public:voidUpdatePrice(conststd::stringsymbol,doubleprice){std::cout股票 symbol 价格更新: pricestd::endl;SetChanged();// 标记状态改变StockPriceArgarg(symbol,price);NotifyObservers(arg);// 通知所有观察者}};定义观察者// 投资者观察者classInvestor:publicObserver{public:Investor(conststd::stringname):name_(name){}voidUpdate(constObservable*o,constObserverArg*arg)override{auto*priceArgdynamic_castconstStockPriceArg*(arg);if(priceArg){std::coutname_ 收到通知: priceArg-symbol priceArg-pricestd::endl;// 根据价格做出决策if(priceArg-price100){std::coutname_: 买入std::endl;}elseif(priceArg-price150){std::coutname_: 卖出std::endl;}}}private:std::string name_;};使用voidObserverDemo(){// 创建被观察者StockMarket market;// 创建观察者autoinvestor1std::make_sharedInvestor(张三);autoinvestor2std::make_sharedInvestor(李四);autoinvestor3std::make_sharedInvestor(王五);// 注册观察者market.AddObserver(investor1);market.AddObserver(investor2);market.AddObserver(investor3);std::cout观察者数量: market.GetObserversCount()std::endl;// 更新价格自动通知所有观察者market.UpdatePrice(AAPL,95.0);std::cout---std::endl;market.UpdatePrice(AAPL,160.0);// 移除一个观察者market.RemoveObserver(investor2);std::cout---std::endl;market.UpdatePrice(AAPL,120.0);}输出观察者数量: 3 股票 AAPL 价格更新: 95 张三 收到通知: AAPL 95 张三: 买入 李四 收到通知: AAPL 95 李四: 买入 王五 收到通知: AAPL 95 王五: 买入 --- 股票 AAPL 价格更新: 160 张三 收到通知: AAPL 160 张三: 卖出 李四 收到通知: AAPL 160 李四: 卖出 王五 收到通知: AAPL 160 王五: 卖出 --- 股票 AAPL 价格更新: 120 张三 收到通知: AAPL 120 王五 收到通知: AAPL 1207. 模式对比与选择7.1 单例模式选择指南程序启动首次使用是否智能指针引用需要单例何时创建?Singleton饿汉式需要销毁?DelayedSingleton智能指针返回类型?DelayedRefSingleton裸指针7.2 三种单例对比特性SingletonDelayedSingletonDelayedRefSingleton创建时机程序启动首次使用首次使用线程安全✅✅ DCL✅ DCL返回类型Tshared_ptrT可销毁❌✅❌内存管理自动自动手动性能最高中等中等适用场景必须存在的全局对象可选的全局对象全程序生命周期7.3 何时使用观察者模式flowchart TB A[场景分析] -- B{一对多关系?} B --|否| C[不适用] B --|是| D{状态变化需通知?} D --|否| C D --|是| E{松耦合要求?} E --|否| F[直接调用可能更简单] E --|是| G[✅ 使用观察者模式]适用场景 消息订阅系统 数据绑定MVC/MVVM 事件通知 股票行情推送 聊天室消息广播8. 使用示例与最佳实践8.1 单例模式最佳实践✅ 推荐做法// 1. 使用宏简化声明classMyService{DECLARE_DELAYED_SINGLETON(MyService)public:voidDoWork();};// 2. 正确使用 DelayedSingletonautoserviceDelayedSingletonMyService::GetInstance();if(service){// 检查是否创建成功service-DoWork();}// 3. 在适当时机销毁voidCleanup(){DelayedSingletonMyService::DestroyInstance();}// 4. 饿汉式用于必须存在的对象classLogger{DECLARE_SINGLETON(Logger)public:voidLog(conststd::stringmsg);};❌ 避免的错误// 错误1: 手动 new 单例类MyService*servicenewMyService();// ❌ 破坏单例// 错误2: 忘记检查 nullptrautoserviceDelayedSingletonMyService::GetInstance();service-DoWork();// ❌ 如果内存不足service 可能为 nullptr// 错误3: 在析构函数中访问其他单例MyService::~MyService(){// ❌ 其他单例可能已经销毁SingletonLogger::GetInstance().Log(Service destroyed);}// 错误4: 循环依赖classA{DECLARE_DELAYED_SINGLETON(A)voidInit(){DelayedSingletonB::GetInstance();// A 依赖 B}};classB{DECLARE_DELAYED_SINGLETON(B)voidInit(){DelayedSingletonA::GetInstance();// B 依赖 A → }};8.2 观察者模式最佳实践✅ 推荐做法// 1. 使用 shared_ptr 管理观察者autoobserverstd::make_sharedMyObserver();subject.AddObserver(observer);// 2. 在析构前移除观察者classMyObserver:publicObserver{public:~MyObserver(){if(subject_){subject_-RemoveObserver(shared_from_this());}}};// 3. 检查参数类型voidUpdate(constObservable*o,constObserverArg*arg)override{auto*myArgdynamic_castconstMyArg*(arg);if(myArg){// 安全使用}}// 4. 记得 SetChangedvoidNotifyPriceChange(doubleprice){SetChanged();// ✅ 必须先设置NotifyObservers(arg);}❌ 避免的错误// 错误1: 忘记 SetChangedvoidNotifyPriceChange(doubleprice){NotifyObservers(arg);// ❌ 不会通知任何人}// 错误2: 在 Update 中修改观察者列表voidUpdate(constObservable*o,constObserverArg*arg)override{o-RemoveObserver(this);// ❌ 可能导致迭代器失效}// 错误3: 观察者泄漏voidSomeFunction(){autoobserverstd::make_sharedMyObserver();subject.AddObserver(observer);// ❌ 函数结束后 observer 被销毁但 subject 还持有引用}8.3 综合示例配置管理系统#includesingleton.h#includeobserver.h#includemap#includestringusingnamespaceOHOS;// 配置变更参数structConfigChangeArg:publicObserverArg{std::string key;std::string oldValue;std::string newValue;};// 配置管理器单例 被观察者classConfigManager:publicObservable{DECLARE_DELAYED_SINGLETON(ConfigManager)public:voidSet(conststd::stringkey,conststd::stringvalue){std::string oldValueconfigs_[key];configs_[key]value;// 通知观察者SetChanged();ConfigChangeArg arg{key,oldValue,value};NotifyObservers(arg);}std::stringGet(conststd::stringkey){returnconfigs_[key];}private:std::mapstd::string,std::stringconfigs_;};ConfigManager::ConfigManager()default;ConfigManager::~ConfigManager()default;// 配置监听器classConfigListener:publicObserver{public:ConfigListener(conststd::stringname):name_(name){}voidUpdate(constObservable*o,constObserverArg*arg)override{auto*configArgdynamic_castconstConfigChangeArg*(arg);if(configArg){std::coutname_ 检测到配置变更: configArg-key configArg-newValue (原值: configArg-oldValue)std::endl;}}private:std::string name_;};// 使用voidConfigDemo(){autoconfigMgrDelayedSingletonConfigManager::GetInstance();// 添加监听器autolistener1std::make_sharedConfigListener(UI模块);autolistener2std::make_sharedConfigListener(网络模块);configMgr-AddObserver(listener1);configMgr-AddObserver(listener2);// 修改配置configMgr-Set(theme,dark);configMgr-Set(language,zh-CN);// 清理configMgr-RemoveAllObservers();DelayedSingletonConfigManager::DestroyInstance();} API 速查表Singleton 宏宏说明DECLARE_SINGLETON(MyClass)声明为饿汉式单例DECLARE_DELAYED_SINGLETON(MyClass)声明为延迟单例shared_ptrDECLARE_DELAYED_REF_SINGLETON(MyClass)声明为延迟引用单例Singleton 类方法说明返回值SingletonT::GetInstance()获取实例TDelayedSingletonT::GetInstance()获取实例shared_ptrDelayedSingletonT::DestroyInstance()销毁实例voidDelayedRefSingletonT::GetInstance()获取实例TObservable 类方法说明AddObserver(o)添加观察者RemoveObserver(o)移除观察者RemoveAllObservers()移除所有观察者NotifyObservers()通知观察者无参数NotifyObservers(arg)通知观察者带参数GetObserversCount()获取观察者数量SetChanged()设置改变标记ClearChanged()清除改变标记HasChanged()检查改变标记Observer 类方法说明Update(o, arg)接收通知的回调纯虚函数 总结记住这三点饿汉式简单高效懒汉式节省资源DelayedSingleton用 shared_ptr可以销毁DelayedRefSingleton用裸指针不能销毁观察者模式通知前必须调用SetChanged()