工布江达网站建设网站的建设与颜色搭配
2026/4/18 16:33:05 网站建设 项目流程
工布江达网站建设,网站的建设与颜色搭配,阿里云备案多个网站,新人做外贸哪个平台好做文章目录1. 造人派#xff08;创建型#xff09;1.1 单例模式#xff08;Singleton#xff09;#xff1a;朕的江山只有一位#xff01;干啥用#xff1f;核心奥义猫哥上代码猫哥点评1.2 工厂模式#xff08;Factory#xff09;#xff1a;对象量产流水线#xff01…文章目录1. 造人派创建型1.1 单例模式Singleton朕的江山只有一位干啥用核心奥义猫哥上代码猫哥点评1.2 工厂模式Factory对象量产流水线1.2.1 简单工厂小作坊啥都能搓两下啥时候用猫哥上代码1.2.2 工厂方法开分店各管一摊啥时候用猫哥上代码1.2.3 抽象工厂集团大厂成套出货啥时候用猫哥上代码2. 搭积木派结构型2.1 适配器模式Adapter万能转接头干啥用猫哥上代码对象适配器 - 推荐猫哥点评2.2 装饰器模式Decorator给对象穿新马甲干啥用猫哥上代码给咖啡加料猫哥点评2.3 代理模式Proxy找个替身挡子弹干啥用猫哥上代码虚拟代理 保护代理猫哥点评3. 拉关系派行为型3.1 策略模式Strategy算法七十二变干啥用猫哥上代码排序算法大比拼猫哥点评3.2 观察者模式Observer一个咳嗽全群感冒干啥用猫哥上代码股票价格变动通知股民猫哥点评3.3 状态模式State看我七十二变状态干啥用猫哥上代码自动贩卖机状态流转猫哥点评猫哥总结设计模式是调味料不是大米饭最后猫哥叨叨几句写在前头设计模式是啥玩意儿设计模式听着高大上别慌说白了就是前踩人坑总结的代码“模板”专门对付那些写代码写到头秃的场景。就像你拼乐高总有些现成的拼法套路省得你每次都从零开始瞎捣鼓。在C江湖里混这玩意儿用好了真能救命它们分三大门派各有绝活造人派创建型专管怎么造对象。比如单例只生一个、工厂量产对象。搭积木派结构型专管对象怎么“勾肩搭背”。比如适配器让插头对插座、装饰器给对象穿新马甲。拉关系派行为型专管对象怎么“眉来眼去”。比如策略算法随便换、观察者一个咳嗽全群感冒、状态不同状态不同嘴脸。猫哥这就带你盘一盘C里最实用的几个模式保证看完代码不再“乱炖”变“佛跳墙”1. 造人派创建型1.1 单例模式Singleton朕的江山只有一位干啥用当你铁了心要让某个类这辈子只出一个对象就得用它场景日志大哥整个程序就一个日志管家谁也别想另起炉灶。配置大总管全局配置就一份改一处大家伙儿都知道。数据库连接池管好一池子连接生多了会撑死。核心奥义构造函数藏起来private不让外人乱new。整一个静态方法当“门童”专门给你发这个唯一对象。线程安全很重要别让多线程整出好几个“朕”来那江山就乱了C11以后局部静态变量初始化是线程安全的省心猫哥上代码#includeiostreamclassSingleton{public:// 想见朕走这个门儿全局唯一入口staticSingletongetInstance(){staticSingleton instance;// C11保证这货只生一次线程安全returninstance;}// 朕能干点啥示例方法voiddoSomething(){std::cout朕单例正在批阅奏折...std::endl;}private:Singleton(){std::cout新皇登基单例诞生std::endl;}// 藏好不准外人new// 以下统统禁用防止克隆、篡位Singleton(constSingleton)delete;Singletonoperator(constSingleton)delete;Singleton(Singleton)delete;Singletonoperator(Singleton)delete;};// 用起来intmain(){Singletonemperor1Singleton::getInstance();// 第一次请安emperor1.doSomething();Singletonemperor2Singleton::getInstance();// 第二次请安emperor2.doSomething();// 看看是不是同一个皇帝std::coutemperor1和emperor2是同一个吗 (emperor1emperor2?是吾皇万岁:不是有反贼)std::endl;return0;}猫哥点评优点省内存只有一个好找全局访问点懒加载用的时候才登基。缺点有点“独裁”违反单一职责又管生又管事。测试难伺候依赖全局状态。用不好容易搞成“全局垃圾场”到处乱用全局状态代码变浆糊。1.2 工厂模式Factory对象量产流水线工厂模式就是造对象的流水线分三种款式1.2.1 简单工厂小作坊啥都能搓两下啥时候用产品种类少变化不大。客户想造啥报个型号ProductType就行不用管里面螺丝怎么拧的。猫哥上代码#includeiostream#includememory// 产品基类抽象产品classProduct{public:virtual~Product()default;virtualvoiduse()const0;// 必须会“用”};// 产品A螺丝刀classScrewdriver:publicProduct{public:voiduse()constoverride{std::cout拧螺丝中... (来自螺丝刀)std::endl;}};// 产品B锤子classHammer:publicProduct{public:voiduse()constoverride{std::cout8080... (来自锤子)std::endl;}};// 产品型号enumclassToolType{Screwdriver,Hammer};// 简单工厂小作坊classToolFactory{public:staticstd::unique_ptrProductcreateTool(ToolType type){switch(type){caseToolType::Screwdriver:returnstd::make_uniqueScrewdriver();caseToolType::Hammer:returnstd::make_uniqueHammer();default:throwstd::invalid_argument(老板没这型号);}}};// 用起来intmain(){// 老板来个螺丝刀automyScrewdriverToolFactory::createTool(ToolType::Screwdriver);myScrewdriver-use();// 老板再整个锤子automyHammerToolFactory::createTool(ToolType::Hammer);myHammer-use();return0;}1.2.2 工厂方法开分店各管一摊啥时候用产品种类多以后还要加新货。每个分店具体工厂只造一种特定产品具体产品。客户想造啥找对应的分店经理就行。猫哥上代码#includeiostream#includememory// 产品基类同上classProduct{...};// 同上省略classScrewdriver:publicProduct{...};// 同上classHammer:publicProduct{...};// 同上// 工厂基类抽象工厂classFactory{public:virtual~Factory()default;virtualstd::unique_ptrProductcreateProduct()const0;// 必须会“造”};// 螺丝刀分店classScrewdriverFactory:publicFactory{public:std::unique_ptrProductcreateProduct()constoverride{returnstd::make_uniqueScrewdriver();// 专心造螺丝刀}};// 锤子分店classHammerFactory:publicFactory{public:std::unique_ptrProductcreateProduct()constoverride{returnstd::make_uniqueHammer();// 专心造锤子}};// 用起来intmain(){// 去螺丝刀分店买螺丝刀std::unique_ptrFactoryscrewdriverShopstd::make_uniqueScrewdriverFactory();autoscrewdriverscrewdriverShop-createProduct();screwdriver-use();// 去锤子分店买锤子std::unique_ptrFactoryhammerShopstd::make_uniqueHammerFactory();autohammerhammerShop-createProduct();hammer-use();return0;}1.2.3 抽象工厂集团大厂成套出货啥时候用要造一整套相关产品比如造Windows风格UI按钮窗口或者Mac风格UI按钮窗口。客户找集团抽象工厂下单集团派不同风格的大厂具体工厂给你造全套。猫哥上代码#includeiostream#includememory// 抽象产品A按钮classButton{public:virtual~Button()default;virtualvoidrender()const0;};// 抽象产品B窗口classWindow{public:virtual~Window()default;virtualvoiddisplay()const0;};// Windows风按钮classWindowsButton:publicButton{public:voidrender()constoverride{std::cout画了个Windows按钮 (带开始菜单味)std::endl;}};// Mac风按钮classMacButton:publicButton{public:voidrender()constoverride{std::cout画了个Mac按钮 (圆角带光效)std::endl;}};// Windows风窗口classWindowsWindow:publicWindow{public:voiddisplay()constoverride{std::cout弹了个Windows窗口 (蓝屏预备中...)std::endl;}};// Mac风窗口classMacWindow:publicWindow{public:voiddisplay()constoverride{std::cout弹了个Mac窗口 (果里果气)std::endl;}};// 抽象工厂集团classUIFactory{public:virtual~UIFactory()default;virtualstd::unique_ptrButtoncreateButton()const0;// 会造按钮virtualstd::unique_ptrWindowcreateWindow()const0;// 会造窗口};// Windows大厂classWindowsUIFactory:publicUIFactory{public:std::unique_ptrButtoncreateButton()constoverride{returnstd::make_uniqueWindowsButton();}std::unique_ptrWindowcreateWindow()constoverride{returnstd::make_uniqueWindowsWindow();}};// Mac大厂classMacUIFactory:publicUIFactory{public:std::unique_ptrButtoncreateButton()constoverride{returnstd::make_uniqueMacButton();}std::unique_ptrWindowcreateWindow()constoverride{returnstd::make_uniqueMacWindow();}};// 用起来intmain(){// 找Windows大厂下单造一套Windows UIstd::unique_ptrUIFactorywindowsFactorystd::make_uniqueWindowsUIFactory();autowinButtonwindowsFactory-createButton();autowinWindowwindowsFactory-createWindow();winButton-render();winWindow-display();// 找Mac大厂下单造一套Mac UIstd::unique_ptrUIFactorymacFactorystd::make_uniqueMacUIFactory();automacButtonmacFactory-createButton();automacWindowmacFactory-createWindow();macButton-render();macWindow-display();return0;}2. 搭积木派结构型2.1 适配器模式Adapter万能转接头干啥用接口不匹配插头插座对不上上适配器它就是个“转接头”把已有的类Adaptee的接口转换成客户期望的接口Target。让原本不兼容的哥俩能愉快玩耍。猫哥上代码对象适配器 - 推荐#includeiostream// 客户期望的插座 (Target)classUSBSocket{public:virtual~USBSocket()default;virtualvoidchargeWithUSB()const0;// 期望用USB充电};// 已有的老式插头 (Adaptee - 它只有TypeC口)classTypeCPlug{public:voidchargeWithTypeC()const{std::cout正在用TypeC口充电...std::endl;}};// USB转TypeC适配器 (Adapter - 对象适配器)classUSBToTypeCAdapter:publicUSBSocket{private:TypeCPlug*plug;// 组合一个已有的TypeC插头public:explicitUSBToTypeCAdapter(TypeCPlug*p):plug(p){}voidchargeWithUSB()constoverride{std::cout适配器把USB请求转成TypeC... ;plug-chargeWithTypeC();// 调用老插头的功能}};// 用起来intmain(){TypeCPlug myOldPlug;// 我有一个老式TypeC插头USBToTypeCAdapteradapter(myOldPlug);// 搞个转接头适配器// 客户只想用USB口充电并不知道里面是TypeCUSBSocket*socketadapter;socket-chargeWithUSB();return0;}猫哥点评优点废物利用复用老代码接口隔离客户和老代码解耦灵活。缺点用多了系统变蜘蛛网类变多。类适配器多重继承限制多不推荐。2.2 装饰器模式Decorator给对象穿新马甲干啥用想给对象动态加点功能又不想改它祖宗代码装饰器来也一层层套娃包装每层加一点新料。避免“子类爆炸”比如Car,CarWithAC,CarWithGPS,CarWithACAndGPS… 想想就头大。猫哥上代码给咖啡加料#includeiostream#includememory#includestring// 核心饮料基类 (Component)classBeverage{public:virtual~Beverage()default;virtualstd::stringgetDescription()const0;virtualdoublecost()const0;};// 具体饮料浓缩咖啡 (ConcreteComponent)classEspresso:publicBeverage{public:std::stringgetDescription()constoverride{return浓缩咖啡;}doublecost()constoverride{return1.99;}};// 装饰器基类 (Decorator)classCondimentDecorator:publicBeverage{protected:std::unique_ptrBeveragebeverage;// 核心包裹一个饮料对象public:explicitCondimentDecorator(std::unique_ptrBeverageb):beverage(std::move(b)){}// 描述和价格留给具体装饰器实现};// 具体装饰器牛奶 (加牛奶要钱)classMilk:publicCondimentDecorator{public:explicitMilk(std::unique_ptrBeverageb):CondimentDecorator(std::move(b)){}std::stringgetDescription()constoverride{returnbeverage-getDescription(), 加牛奶;}doublecost()constoverride{returnbeverage-cost()0.50;// 牛奶钱}};// 具体装饰器摩卡 (加摩卡也要钱)classMocha:publicCondimentDecorator{public:explicitMocha(std::unique_ptrBeverageb):CondimentDecorator(std::move(b)){}std::stringgetDescription()constoverride{returnbeverage-getDescription(), 加摩卡;}doublecost()constoverride{returnbeverage-cost()0.70;// 摩卡钱}};// 用起来点一杯豪华咖啡intmain(){// 先来个基础浓缩咖啡std::unique_ptrBeveragemyCoffeestd::make_uniqueEspresso();std::coutmyCoffee-getDescription() myCoffee-cost()std::endl;// 加一份牛奶 (套一层装饰器)myCoffeestd::make_uniqueMilk(std::move(myCoffee));std::coutmyCoffee-getDescription() myCoffee-cost()std::endl;// 再加两份摩卡(套两层装饰器)myCoffeestd::make_uniqueMocha(std::move(myCoffee));// 第一份摩卡myCoffeestd::make_uniqueMocha(std::move(myCoffee));// 第二份摩卡std::cout终极豪华版: myCoffee-getDescription() myCoffee-cost()std::endl;return0;}猫哥点评优点动态加功能爽避免子类爆炸爽不破坏老代码爽开闭原则缺点小类会变多一层层小包装。顺序很重要先加奶还是先加摩卡搞错顺序可能出锅。2.3 代理模式Proxy找个替身挡子弹干啥用不想直接碰真身对象想加点控制找个代理代理跟真身长得一样同接口但能在见真身前/后搞点事情。常用替身类型虚拟代理真身太贵创建开销大先让替身顶着用到真身再请延迟加载。保护代理替身查你身份访问控制没权限别想见真身远程代理真身在千里之外网络另一边替身负责通信。猫哥上代码虚拟代理 保护代理#includeiostream#includememory#includestring// 明星接口 (Subject)classStar{public:virtual~Star()default;virtualvoidperform()const0;// 必须会表演};// 真·大明星 (RealSubject - 出场费贼贵)classSuperstar:publicStar{public:voidperform()constoverride{std::cout 大牌明星闪亮登场深情演唱... std::endl;}};// 虚拟代理 (Virtual Proxy - 替身经纪人)classStarAgent:publicStar{private:mutablestd::unique_ptrSuperstarrealStar;// 真明星需要时才请public:voidperform()constoverride{// 检查真明星来了没没来赶紧请延迟加载if(!realStar){std::cout经纪人稍等正在联系大牌明星出场费很贵哦...std::endl;realStarstd::make_uniqueSuperstar();}// 真明星到场表演开始realStar-perform();}};// 保护代理 (Protection Proxy - 保安大哥)classSecurityGuard:publicStar{private:std::unique_ptrSuperstarrealStar;std::string password;// 暗号public:explicitSecurityGuard(conststd::stringpwd):realStar(std::make_uniqueSuperstar()),password(pwd){}// 提前请好明星voidperform()constoverride{// 保安大哥先查暗号if(password天王盖地虎){std::cout保安暗号正确大佬您请进std::endl;realStar-perform();// 放行见真明星}else{std::cout保安暗号不对闲杂人等不得靠近std::endl;}}};// 用起来intmain(){std::cout 虚拟代理 (延迟加载) std::endl;StarAgent agent;// 只请了经纪人便宜agent.perform();// 第一次call经纪人现场联系明星慢agent.perform();// 第二次call明星已在场直接演快std::cout\n 保护代理 (访问控制) std::endl;SecurityGuardguardWithRightPwd(天王盖地虎);// 保安知道正确暗号guardWithRightPwd.perform();// 放行明星表演SecurityGuardguardWithWrongPwd(小鸡炖蘑菇);// 保安碰到错误暗号guardWithWrongPwd.perform();// 拦截不让见return0;}猫哥点评优点控制访问安全延迟加载省资源加功能记录日志啥的。缺点多了一层可能拖慢速度。类变多。3. 拉关系派行为型3.1 策略模式Strategy算法七十二变干啥用一堆算法想运行时灵活切换策略模式把每个算法封装成独立对象策略客户端想用哪个就换哪个跟换衣服似的。告别长长的if-else/switch-case猫哥上代码排序算法大比拼#includeiostream#includememory#includevector// 排序策略接口classSortStrategy{public:virtual~SortStrategy()default;virtualvoidsort(std::vectorintdata)const0;// 必须会排序};// 冒泡排序策略classBubbleSort:publicSortStrategy{public:voidsort(std::vectorintdata)constoverride{std::cout 启动冒泡排序朴实无华...std::endl;// ... 冒泡排序实现略猫哥相信你}};// 快速排序策略classQuickSort:publicSortStrategy{public:voidsort(std::vectorintdata)constoverride{std::cout 启动快速排序速度与激情...std::endl;// ... 快速排序实现略}};// 堆排序策略classHeapSort:publicSortStrategy{public:voidsort(std::vectorintdata)constoverride{std::cout 启动堆排序稳如老狗...std::endl;// ... 堆排序实现略}};// 排序上下文 (Context - 它持有一个策略)classSorter{private:std::unique_ptrSortStrategystrategy;// 当前用的策略public:explicitSorter(std::unique_ptrSortStrategys):strategy(std::move(s)){}// 换个策略耍耍voidsetStrategy(std::unique_ptrSortStrategys){strategystd::move(s);}// 执行排序干活的是当前策略voidexecuteSort(std::vectorintdata)const{strategy-sort(data);}};// 用起来intmain(){std::vectorintnumbers{5,1,4,2,8};Sortersorter(std::make_uniqueBubbleSort());// 初始用冒泡sorter.executeSort(numbers);// 冒泡排序// 换个策略快排sorter.setStrategy(std::make_uniqueQuickSort());sorter.executeSort(numbers);// 快速排序// 再换个策略堆排sorter.setStrategy(std::make_uniqueHeapSort());sorter.executeSort(numbers);// 堆排序return0;}猫哥点评优点运行时切换算法爽干掉复杂条件判断爽加新算法容易开闭原则。缺点客户端得知道所有策略选哪个。策略对象多了点。3.2 观察者模式Observer一个咳嗽全群感冒干啥用一个对象主题/Subject状态变了想通知一群依赖它的小弟观察者/Observer观察者模式走起主题只管“吼一声”通知观察者们自己“对号入座”更新自己。应用广GUI事件、消息队列、发布-订阅。猫哥上代码股票价格变动通知股民#includeiostream#includememory#includevector#includestring#includemutex// 股民接口 (Observer - 订阅者)classInvestor{public:virtual~Investor()default;virtualvoidupdate(conststd::stringstockName,doubleprice)0;// 必须会接收通知};// 股市大屏 (Subject - 发布者)classStockMarket{private:std::vectorstd::weak_ptrInvestorinvestors;// 股民列表用weak_ptr防主子被小弟拖住mutablestd::mutex mutex;// 多线程安全防通知时乱套std::string stockName;doublecurrentPrice;public:StockMarket(std::string name,doubleprice):stockName(std::move(name)),currentPrice(price){}// 股民订阅登记voidsubscribe(std::shared_ptrInvestorinvestor){std::lock_guardstd::mutexlock(mutex);investors.push_back(investor);std::coutinvestor.get() 订阅了 stockName 行情std::endl;}// 股民取消订阅除名voidunsubscribe(std::shared_ptrInvestorinvestor){std::lock_guardstd::mutexlock(mutex);// 找到并移除这个股民顺带清理僵尸investors.erase(std::remove_if(investors.begin(),investors.end(),[investor](conststd::weak_ptrInvestorw){autosw.lock();return!s||s.get()investor.get();// 没订阅了或就是这个股民}),investors.end());std::coutinvestor.get() 取消订阅 stockNamestd::endl;}// 发布价格变动通知voidnotify(doublenewPrice){std::lock_guardstd::mutexlock(mutex);currentPricenewPrice;// 更新价格std::string messagestockName 最新股价: std::to_string(newPrice);// 遍历所有股民同时清理失效的investors.erase(std::remove_if(investors.begin(),investors.end(),[message](conststd::weak_ptrInvestorw){autosw.lock();if(s){s-update(message);// 通知有效股民returnfalse;// 保留}returntrue;// 标记僵尸股民待清理}),investors.end());}};// 具体股民张三classZhangSan:publicInvestor,publicstd::enable_shared_from_thisZhangSan{public:voidupdate(conststd::stringstockName,doubleprice)override{std::cout张三收到: stockName - price(price100? (发财了): (再等等...))std::endl;}};// 具体股民李四classLiSi:publicInvestor,publicstd::enable_shared_from_thisLiSi{public:voidupdate(conststd::stringstockName,doubleprice)override{std::cout李四收到: stockName - price(price50? (抄底): (有点贵...))std::endl;}};// 用起来股市风云intmain(){// 创建一只股票猫哥科技 (代码: MGKJ)StockMarketmgkj(猫哥科技(MGKJ),90.0);// 创建两位股民autozhangsanstd::make_sharedZhangSan();autolisistd::make_sharedLiSi();// 股民订阅行情mgkj.subscribe(zhangsan);mgkj.subscribe(lisi);// 股价变动触发通知mgkj.notify(95.5);// 涨了mgkj.notify(102.3);// 破百了// 李四受不了了割肉离场取消订阅mgkj.unsubscribe(lisi);// 股价暴跌只通知张三了mgkj.notify(45.8);return0;}猫哥点评优点主体和小弟解耦爽广播通知爽动态增删小弟爽遵循开闭原则。缺点小弟太多通知一遍慢死性能瓶颈。注意循环引用weak_ptr来救场。通知顺序看缘分不确定。3.3 状态模式State看我七十二变状态干啥用一个对象的行为取决于它的内部状态并且状态一改行为全变状态模式把每个状态封装成一个类状态变了就换类对象。告别超长的状态判断if-else。猫哥上代码自动贩卖机状态流转#includeiostream#includememory#includestring// 状态接口 (State)classVendingMachineState{public:virtual~VendingMachineState()default;virtualvoidinsertMoney(intamount)0;// 投币virtualvoidselectItem(conststd::stringitem)0;// 选货virtualvoiddispenseItem()0;// 出货virtualvoidcancel()0;// 取消};// 具体状态待机状态 (等待投币)classIdleState:publicVendingMachineState{private:std::string context;// 状态机上下文引用 (模拟)public:explicitIdleState(std::stringctx):context(ctx){}voidinsertMoney(intamount)override{std::cout投币成功amount等待选择商品。std::endl;contextHasMoney;// 状态流转 - 有钱状态}voidselectItem(conststd::string)override{std::cout【待机】请先投币std::endl;}voiddispenseItem()override{std::cout【待机】请先投币并选择商品std::endl;}voidcancel()override{std::cout【待机】无交易可取消。std::endl;}};// 具体状态有钱状态 (已投币等待选择)classHasMoneyState:publicVendingMachineState{private:std::string context;intmoneyInserted0;public:explicitHasMoneyState(std::stringctx):context(ctx){}voidinsertMoney(intamount)override{moneyInsertedamount;std::cout追加投币amount总计moneyInsertedstd::endl;}voidselectItem(conststd::stringitem)override{std::cout已选择商品: item准备出货...std::endl;contextItemSelected;// 状态流转 - 已选状态}voiddispenseItem()override{std::cout【有钱】请先选择商品std::endl;}voidcancel()override{std::cout交易取消退还moneyInsertedstd::endl;moneyInserted0;contextIdle;// 状态流转 - 待机状态}};// 具体状态已选状态 (已选商品等待出货/取消)classItemSelectedState:publicVendingMachineState{private:std::string context;std::string selectedItem;public:explicitItemSelectedState(std::stringctx,conststd::stringitem):context(ctx),selectedItem(item){}voidinsertMoney(int)override{std::cout【已选】请先出货或取消当前商品std::endl;}voidselectItem(conststd::string)override{std::cout【已选】您已选择了 selectedItem std::endl;}voiddispenseItem()override{std::cout出货: selectedItem 交易完成std::endl;contextIdle;// 状态流转 - 待机状态}voidcancel()override{std::cout取消商品: selectedItem 退还金额。std::endl;contextIdle;// 状态流转 - 待机状态}};// 贩卖机上下文 (Context - 持有一个状态对象)classVendingMachine{private:std::unique_ptrVendingMachineStatecurrentState;std::string stateNameIdle;// 简单表示当前状态名std::string selectedItem;// 选中的商品public:VendingMachine(){currentStatestd::make_uniqueIdleState(stateName);// 初始状态待机}// 状态机核心根据stateName切换状态对象voidsetState(){if(stateNameIdle){currentStatestd::make_uniqueIdleState(stateName);}elseif(stateNameHasMoney){currentStatestd::make_uniqueHasMoneyState(stateName);}elseif(stateNameItemSelected){currentStatestd::make_uniqueItemSelectedState(stateName,selectedItem);}}// 投币voidinsertMoney(intamount){currentState-insertMoney(amount);setState();// 投币可能导致状态变检查并更新状态对象}// 选择商品voidselectItem(conststd::stringitem){selectedItemitem;currentState-selectItem(item);setState();// 选择商品可能导致状态变检查并更新状态对象}// 出货voiddispenseItem(){currentState-dispenseItem();setState();// 出货可能导致状态变检查并更新状态对象}// 取消交易voidcancel(){currentState-cancel();setState();// 取消可能导致状态变检查并更新状态对象}};// 用起来买瓶快乐水intmain(){VendingMachine vm;vm.selectItem(快乐水);// 待机状态不让选vm.insertMoney(5);// 投币5块 - 进入有钱状态vm.selectItem(快乐水);// 选择商品 - 进入已选状态vm.dispenseItem();// 出货 - 完成交易回到待机std::cout\n再来一次中途取消std::endl;vm.insertMoney(10);// 投币10块 - 有钱状态vm.insertMoney(5);// 再投5块 - 还是有钱状态累计15vm.cancel();// 取消交易 - 退钱回到待机return0;}猫哥点评优点状态行为封装好代码清晰干掉状态判断if-else爽加新状态容易开闭原则。缺点状态类多点。状态转换逻辑散在各状态类里有时有点绕。猫哥总结设计模式是调味料不是大米饭看完这8大设计模式是不是感觉C代码瞬间有“设计感”了总结一下造人派 (创建型)Singleton一个皇帝坐江山。Factory系列量产对象换货方便简单、方法、抽象工厂。搭积木派 (结构型)Adapter万能转接头接口不兼容不存在的Decorator给对象动态穿马甲加功能一层套一层。Proxy找个替身挡子弹控制访问、延迟加载。拉关系派 (行为型)Strategy算法随便换跟换衣服似的。Observer一个大哥吼一群小弟动发布-订阅。State状态一变行为全变告别状态判断噩梦。最后猫哥叨叨几句别硬套设计模式是**好用的但别应套啊。就像穿鞋一样每个人的脚是不一样的适合自己的就是最好的。多实践别停留在纸上谈兵。不能为了用而用为了所谓的高打上而用。而是解决实际的问题而用。看菜下饭小项目用单例/工厂这种油盐酱醋就够了别学五星大厨摆分子料理的谱——碗泡面非要雕萝卜花纯粹闲得慌活学活用别把模式当祖宗牌位供着。比如观察者模式如果用消息队列更香就换别抱着锤子看啥都是钉子。警惕性能刺客代理层层包装、观察者万人通知这些花活看着炫遇上性能瓶颈直接变代码火葬场。CPU和内存可不听你讲设计哲学。别当模式原教旨主义者状态模式非得搞十几种状态类试试查表法状态机它不香吗模式是参考答案不是高考作文评分标准。记住牛逼的代码不是用模式堆出来的是让读代码的人能笑着骂这孙子真会偷懒下次写代码卡壳了翻翻猫哥这篇咱江湖再见

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询