自贡 网站建设,做网站关键词软件,dede网站 设置404 错误页面,个人网页设计排版写代码像闯江湖#xff1f;总遇到些似曾相识的难题#xff1a;对象怎么造省心#xff1f;功能怎么加优雅#xff1f;模块怎么搭结实#xff1f;设计模式就是前辈们踩坑总结的“武功套路”#xff0c;专治各种代码花式作死。今天猫哥继续带你逛遍设计模式大观园#xff0…写代码像闯江湖总遇到些似曾相识的难题对象怎么造省心功能怎么加优雅模块怎么搭结实设计模式就是前辈们踩坑总结的“武功套路”专治各种代码花式作死。今天猫哥继续带你逛遍设计模式大观园分造人派创建型、搭积木派结构型、搞关系派行为型三大片区20个门派各显神通走起一、造人派创建型专治“对象难产”1. 单例模式 (Singleton) - “孤寡老人”核心奥义整个江湖就允许一个实例想new没门适用场景日志总管、配置大管家、数据库连接池多了会撑死猫哥吐槽用不好就是“全局垃圾场”测试时想换对象做梦classLogManager{public:staticLogManagergetInstance(){staticLogManager instance;// C11魔法线程安全又省心returninstance;}voidlog(conststd::stringmsg){std::cout[LOG] msgstd::endl;}private:LogManager()default;// 关门不准外面造// 防克隆防篡位三连LogManager(constLogManager)delete;LogManageroperator(constLogManager)delete;};// 用法整个程序就这一个日志老大LogManager::getInstance().log(猫哥来也);2. 工厂方法 (Factory Method) - “专业分店”核心奥义想要啥产品找对应分店子类决定造啥。适用场景不同武器店造不同武器刀店造刀枪店造枪猫哥吐槽开分店上瘾小心“类爆炸”// 武器基类classWeapon{public:virtualvoidattack()0;};// 具体产品屠龙刀classDragonSword:publicWeapon{public:voidattack()override{std::cout刀光一闪std::endl;}};// 武器工厂总店规矩classWeaponFactory{public:virtualstd::unique_ptrWeaponcreate()0;};// 屠龙刀专卖店分店classSwordFactory:publicWeaponFactory{public:std::unique_ptrWeaponcreate()override{returnstd::make_uniqueDragonSword();}};// 用法找分店买刀autofactorystd::make_uniqueSwordFactory();automySwordfactory-create();mySword-attack();// 刀光一闪3. 抽象工厂 (Abstract Factory) - “集团大厂”核心奥义搞套装Windows风按钮窗口Mac风按钮窗口整包发货适用场景跨平台UI套件、游戏皮肤包猫哥吐槽加个新配件所有分厂都得加班// 抽象UI套件classButton{public:virtualvoiddraw()0;};classWindow{public:virtualvoidshow()0;};// Windows全家桶classWinButton:publicButton{voiddraw()override{std::cout画了个Windows按钮std::endl;}};classWinWindow:publicWindow{voidshow()override{std::cout弹了个Windows窗口std::endl;}};// 抽象大厂classUIFactory{public:virtualstd::unique_ptrButtoncreateButton()0;virtualstd::unique_ptrWindowcreateWindow()0;};// Windows大厂classWinFactory:publicUIFactory{std::unique_ptrButtoncreateButton()override{returnstd::make_uniqueWinButton();}std::unique_ptrWindowcreateWindow()override{returnstd::make_uniqueWinWindow();}};// 用法找Windows大厂下单autowinFactorystd::make_uniqueWinFactory();autobtnwinFactory-createButton();autowindowwinFactory-createWindow();btn-draw();// 画了个Windows按钮window-show();// 弹了个Windows窗口4. 建造者 (Builder) - “乐高大师”核心奥义分步造复杂对象避免构造函数参数炸了适用场景配豪华电脑选CPU、加内存、装显卡猫哥吐槽配台电脑要写10个类杀鸡用牛刀classComputer{public:voidsetCPU(conststd::stringcpu){cpu_cpu;}voidsetRAM(conststd::stringram){ram_ram;}voidshow()const{std::cout电脑配置: CPUcpu_ RAMram_std::endl;}private:std::string cpu_;std::string ram_;};// 装机师傅建造者classComputerBuilder{public:virtualvoidbuildCPU()0;virtualvoidbuildRAM()0;virtualComputergetResult()0;};// 游戏电脑装机师傅classGamingBuilder:publicComputerBuilder{public:voidbuildCPU()override{computer_.setCPU(i9-13900K);}voidbuildRAM()override{computer_.setRAM(32GB DDR5);}ComputergetResult()override{returncomputer_;}private:Computer computer_;};// 用法指挥装机GamingBuilder builder;builder.buildCPU();builder.buildRAM();Computer myPCbuilder.getResult();myPC.show();// 电脑配置: CPUi9-13900K RAM32GB DDR55. 原型模式 (Prototype) - “克隆大法”核心奥义复制比new快尤其当对象构造像“等外卖”一样慢时。适用场景游戏里复制100个小兵、复杂配置对象复制猫哥吐槽深拷贝浅拷贝搞不清等着内存泄漏吧classMonster{public:virtualstd::unique_ptrMonsterclone()const0;virtualvoidroar()const0;};classGoblin:publicMonster{public:std::unique_ptrMonsterclone()constoverride{returnstd::make_uniqueGoblin(*this);// 深拷贝}voidroar()constoverride{std::cout嘎呜std::endl;}};// 用法克隆10只哥布林Goblin prototype;std::vectorstd::unique_ptrMonsterarmy;for(inti0;i10;i){army.push_back(prototype.clone());}army[0]-roar();// 嘎呜二、搭积木派结构型专治“对象不合”6. 适配器 (Adapter) - “万能转接头”核心奥义让老插头插新插座旧类换身马甲继续用。适用场景整合老代码、第三方库接口改造猫哥吐槽适配器叠三层代码变千层饼// 新插座标准 (Target)classUSBSocket{public:virtualvoidcharge()0;};// 老式TypeC插头 (Adaptee)classTypeCPlug{public:voidtypeCCharge(){std::coutTypeC充电中...std::endl;}};// 转接头 (Adapter)classTypeCToUSBAdapter:publicUSBSocket{public:TypeCToUSBAdapter(TypeCPlug*plug):plug_(plug){}voidcharge()override{plug_-typeCCharge();}// 偷偷转换private:TypeCPlug*plug_;};// 用法老插头插新插座TypeCPlug oldPlug;TypeCToUSBAdapteradapter(oldPlug);adapter.charge();// TypeC充电中...7. 装饰器 (Decorator) - “俄罗斯套娃”核心奥义给对象动态穿马甲加日志加权限套就完事适用场景功能增强咖啡加奶加糖、中间件猫哥吐槽套娃十层调试时想找本尊得拆到哭classCoffee{public:virtualvoidbrew()const0;};classBlackCoffee:publicCoffee{voidbrew()constoverride{std::cout冲一杯黑咖啡std::endl;}};// 装饰器基类套娃核心classCoffeeDecorator:publicCoffee{public:explicitCoffeeDecorator(std::unique_ptrCoffeec):coffee_(std::move(c)){}voidbrew()constoverride{coffee_-brew();}protected:std::unique_ptrCoffeecoffee_;};// 加奶装饰器classMilkDecorator:publicCoffeeDecorator{public:usingCoffeeDecorator::CoffeeDecorator;voidbrew()constoverride{coffee_-brew();std::cout加一勺鲜奶std::endl;}};// 用法黑咖啡 - 加奶 - 加糖automyCoffeestd::make_uniqueMilkDecorator(std::make_uniqueBlackCoffee());myCoffee-brew();// 输出// 冲一杯黑咖啡// 加一勺鲜奶8. 代理 (Proxy) - “明星经纪人”核心奥义想见明星先过经纪人这关控制访问延迟加载。适用场景远程调用、权限控制、图片懒加载猫哥吐槽经纪人太忙访问速度慢成蜗牛classStar{public:virtualvoidperform()0;};classRealStar:publicStar{voidperform()override{std::cout周董开唱哎哟不错哦std::endl;}};// 经纪人代理classStarAgent:publicStar{public:voidperform()override{if(!realStar_){// 还没请赶紧的std::cout经纪人联系周董中...收出场费std::endl;realStar_std::make_uniqueRealStar();}realStar_-perform();}private:std::unique_ptrRealStarrealStar_;};// 用法找经纪人StarAgent agent;agent.perform();// 第一次经纪人联系明星agent.perform();// 第二次直接表演9. 桥接 (Bridge) - “跨平台大佬”核心奥义抽象和实现分手让它们各自找新欢。适用场景跨平台绘图库Windows/Mac画圆画方猫哥吐槽抽象和实现总吵架桥接劝分不劝和// 实现部分渲染引擎classRenderer{public:virtualvoidrenderCircle(floatr)0;};classOpenGLRenderer:publicRenderer{voidrenderCircle(floatr)override{std::coutOpenGL画圆半径rstd::endl;}};// 抽象部分形状classShape{public:Shape(Renderer*r):renderer_(r){}virtualvoiddraw()0;protected:Renderer*renderer_;};classCircle:publicShape{public:Circle(Renderer*r,floatrad):Shape(r),radius_(rad){}voiddraw()override{renderer_-renderCircle(radius_);}private:floatradius_;};// 用法OpenGL画个圆OpenGLRenderer gl;Circlecircle(gl,5.0f);circle.draw();// OpenGL画圆半径510. 组合 (Composite) - “套娃高手”核心奥义文件夹套文件夹套文件统一当“节点”处理适用场景UI组件树、文件系统、组织架构猫哥吐槽叶子节点非要加子节点等着程序崩吧classFileComponent{public:virtualvoidlist(intdepth0)const0;};// 文件叶子节点classFile:publicFileComponent{public:File(std::string name):name_(std::move(name)){}voidlist(intdepth)constoverride{std::coutstd::string(depth,-)文件: name_std::endl;}private:std::string name_;};// 文件夹复合节点classFolder:publicFileComponent{public:voidadd(std::unique_ptrFileComponentcomp){children_.push_back(std::move(comp));}voidlist(intdepth)constoverride{std::coutstd::string(depth,-)文件夹std::endl;for(constautochild:children_){child-list(depth2);}}private:std::vectorstd::unique_ptrFileComponentchildren_;};// 用法构建文件夹结构autorootstd::make_uniqueFolder();root-add(std::make_uniqueFile(猫哥的简历.pdf));autosubFolderstd::make_uniqueFolder();subFolder-add(std::make_uniqueFile(黑历史.txt));root-add(std::move(subFolder));root-list();// 输出// 文件夹// --文件: 猫哥的简历.pdf// --文件夹// ----文件: 黑历史.txt11. 享元 (Flyweight) - “内存抠门鬼”核心奥义共享相同部分省内存尤其当你有10万颗同款树时。适用场景文字编辑器字符池、游戏粒子系统猫哥吐槽共享状态线程不安全多线程下等着哭吧// 享元对象树的类型内在状态classTreeType{public:TreeType(std::string name,std::string color):name_(std::move(name)),color_(std::move(color)){}voiddraw(intx,inty)const{std::cout在(x,y)画一棵color_的name_std::endl;}private:std::string name_;std::string color_;};// 享元工厂管理池子classTreeFactory{public:constTreeType*getTreeType(conststd::stringname,conststd::stringcolor){autokeyname_color;if(autoitpool_.find(key);it!pool_.end()){return(it-second);}auto[newIt,_]pool_.emplace(key,TreeType(name,color));return(newIt-second);}private:std::unordered_mapstd::string,TreeTypepool_;};// 用法画1000棵松树只存1个类型TreeFactory factory;constTreeType*pineTypefactory.getTreeType(松树,绿色);for(inti0;i1000;i){pineType-draw(rand()%100,rand()%100);// 复用同一个TreeType对象}12. 外观 (Facade) - “万能接线员”核心奥义复杂系统太闹心一个接口全搞定适用场景系统启动流程、复杂库封装猫哥吐槽滥用外观小心变成“上帝类”背锅侠// 复杂子系统CPUclassCPU{public:voidstart(){std::coutCPU启动std::endl;}};// 复杂子系统内存classMemory{public:voidinit(){std::cout内存初始化std::endl;}};// 复杂子系统硬盘classHardDrive{public:voidread(){std::cout硬盘读取引导区std::endl;}};// 外观电脑启动按钮classComputerFacade{public:voidpowerOn(){cpu_.start();memory_.init();hd_.read();std::cout欢迎使用std::endl;}private:CPU cpu_;Memory memory_;HardDrive hd_;};// 用法一键开机ComputerFacade myPC;myPC.powerOn();// 输出// CPU启动// 内存初始化// 硬盘读取引导区// 欢迎使用三、搞关系派行为型专治“对象社恐”13. 策略 (Strategy) - “算法七十二变”核心奥义算法随便换告别if-else地狱适用场景支付方式切换、排序算法动态选择猫哥吐槽策略太多选择困难症患者慎入classPaymentStrategy{public:virtualvoidpay(intamount)0;};classAlipay:publicPaymentStrategy{voidpay(intamount)override{std::cout支付宝支付amount元std::endl;}};classWechatPay:publicPaymentStrategy{voidpay(intamount)override{std::cout微信支付amount元std::endl;}};// 支付上下文收银台classPaymentContext{public:voidsetStrategy(std::unique_ptrPaymentStrategys){strategy_std::move(s);}voidexecutePay(intamount){strategy_-pay(amount);}private:std::unique_ptrPaymentStrategystrategy_;};// 用法随时切换支付方式PaymentContext ctx;ctx.setStrategy(std::make_uniqueAlipay());ctx.executePay(100);// 支付宝支付100元ctx.setStrategy(std::make_uniqueWechatPay());ctx.executePay(50);// 微信支付50元14. 观察者 (Observer) - “八卦传播链”核心奥义一个对象咳嗽所有依赖它的对象都感冒适用场景事件通知、数据监控、MVC架构猫哥吐槽观察者太多通知一圈能泡三杯咖啡// 主题八卦中心classSubject{public:virtualvoidattach(Observer*o)0;virtualvoidnotify(conststd::stringnews)0;};// 观察者吃瓜群众classObserver{public:virtualvoidupdate(conststd::stringnews)0;};// 具体主题微博大VclassWeiboStar:publicSubject{public:voidattach(Observer*o)override{fans_.push_back(o);}voidnotify(conststd::stringnews)override{for(autofan:fans_)fan-update(news);}private:std::vectorObserver*fans_;};// 具体观察者猫哥classCatBro:publicObserver{voidupdate(conststd::stringnews)override{std::cout猫哥收到八卦news (咔嚓截图)std::endl;}};// 用法大V发动态粉丝全收到WeiboStar star;CatBro cat;star.attach(cat);star.notify(某顶流明星塌房了);15. 状态 (State) - “变脸大师”核心奥义状态一变行为全变告别if-else状态机。适用场景订单流程、游戏角色状态、工单审批流猫哥吐槽状态太多类数量爆炸警告classVendingMachineState{public:virtualvoidinsertCoin()0;virtualvoiddispense()0;};// 待投币状态classIdleState:publicVendingMachineState{public:voidinsertCoin()override{std::cout投币成功请选择商品std::endl;}voiddispense()override{std::cout请先投币std::endl;}};// 已投币状态classHasCoinState:publicVendingMachineState{public:voidinsertCoin()override{std::cout您已投币别再投了std::endl;}voiddispense()override{std::cout出货中...请取走快乐水std::endl;}};// 自动贩卖机classVendingMachine{public:VendingMachine():state_(std::make_uniqueIdleState()){}voidinsertCoin(){state_-insertCoin();}voiddispense(){state_-dispense();}voidchangeState(std::unique_ptrVendingMachineStatenewState){state_std::move(newState);}private:std::unique_ptrVendingMachineStatestate_;};// 用法根据状态切换行为VendingMachine vm;vm.insertCoin();// 投币成功请选择商品vm.dispense();// 出货中...请取走快乐水16. 命令 (Command) - “任务派遣单”核心奥义把请求打包成对象支持撤销/重做/排队适用场景操作历史记录、遥控器按钮、任务队列猫哥吐槽简单操作搞命令杀鸡用火箭筒// 命令接口classCommand{public:virtualvoidexecute()0;virtualvoidundo()0;};// 具体命令开灯classLightOnCommand:publicCommand{public:explicitLightOnCommand(Light*l):light_(l){}voidexecute()override{light_-on();}voidundo()override{light_-off();}private:Light*light_;};// 灯接收者classLight{public:voidon(){std::cout灯亮了std::endl;}voidoff(){std::cout灯灭了std::endl;}};// 遥控器按钮调用者classRemoteButton{public:voidsetCommand(std::unique_ptrCommandcmd){command_std::move(cmd);}voidpress(){command_-execute();}voidundoPress(){command_-undo();}private:std::unique_ptrCommandcommand_;};// 用法开灯 - 撤销Light myLight;autobuttonstd::make_uniqueRemoteButton();button-setCommand(std::make_uniqueLightOnCommand(myLight));button-press();// 灯亮了button-undoPress();// 灯灭了17. 模板方法 (Template Method) - “标准化流水线”核心奥义固定流程框架子类填空细节防止跑偏。适用场景游戏主循环、业务流程框架猫哥吐槽步骤太多子类实现要疯// 游戏骨架模板classGame{public:// 固定流程子类不能改voidplay(){initialize();startPlay();endPlay();}virtual~Game()default;protected:// 留给子类填空virtualvoidinitialize()0;virtualvoidstartPlay()0;virtualvoidendPlay()0;};// 具体游戏象棋classChess:publicGame{protected:voidinitialize()override{std::cout摆棋盘棋子...std::endl;}voidstartPlay()override{std::cout当头炮std::endl;}voidendPlay()override{std::cout将军赢了顿烧烤std::endl;}};// 用法按标准流程玩Chess game;game.play();// 输出// 摆棋盘棋子...// 当头炮// 将军赢了顿烧烤18. 迭代器 (Iterator) - “容器导游”核心奥义不管容器是数组还是链表遍历用同一套姿势适用场景自定义容器遍历、封装集合内部结构猫哥吐槽C有STL迭代器还手写除非吃饱了撑的templatetypenameTclassMyList{public:classIterator{public:Iterator(T*ptr):ptr_(ptr){}Toperator*()const{return*ptr_;}Iteratoroperator(){ptr_;return*this;}booloperator!(constIteratorother)const{returnptr_!other.ptr_;}private:T*ptr_;};voidadd(constTitem){data_.push_back(item);}Iteratorbegin(){returnIterator(data_[0]);}Iteratorend(){returnIterator(data_[0]data_.size());}private:std::vectorTdata_;};// 用法像STL一样遍历MyListstd::stringplaylist;playlist.add(七里香);playlist.add(双截棍);for(autosong:playlist){std::cout播放: songstd::endl;}19. 备忘录 (Memento) - “时光机”核心奥义随时存档读档对象状态想改就改想回滚就回滚。适用场景撤销操作、游戏存档猫哥吐槽存档太频繁内存分分钟爆炸// 游戏角色需存档的对象classGameCharacter{public:structMemento{inthealth;intlevel;};// 存档数据Mementosave()const{return{health_,level_};}voidrestore(constMementom){health_m.health;level_m.level;}voidtakeDamage(intdmg){health_-dmg;}voidshow()const{std::cout血量:health_ 等级:level_std::endl;}private:inthealth_100;intlevel_1;};// 存档管理器classSaveManager{public:voidsave(conststd::stringkey,constGameCharacter::Mementom){saves_[key]m;}GameCharacter::Mementoload(conststd::stringkey){returnsaves_.at(key);}private:std::unordered_mapstd::string,GameCharacter::Mementosaves_;};// 用法存档 - 受伤 - 读档GameCharacter hero;SaveManager saves;saves.save(slot1,hero.save());// 存档hero.takeDamage(50);// 受伤hero.show();// 血量:50 等级:1hero.restore(saves.load(slot1));// 读档hero.show();// 血量:100 等级:1 (满血复活!)20. 中介者 (Mediator) - “婚介所红娘”核心奥义对象别直接聊天找中介传话降低耦合。适用场景聊天室、飞机调度系统猫哥吐槽中介累成狗可能成性能瓶颈// 中介接口classChatMediator{public:virtualvoidsendMsg(conststd::stringmsg,classUser*sender)0;virtualvoidaddUser(User*user)0;};// 具体中介聊天室classChatRoom:publicChatMediator{public:voidaddUser(User*user)override{users_.push_back(user);}voidsendMsg(conststd::stringmsg,User*sender)override{for(autouser:users_){if(user!sender)// 不发给发送者user-receive(msg);}}private:std::vectorUser*users_;};// 用户classUser{public:User(conststd::stringname,ChatMediator*med):name_(name),mediator_(med){}voidsend(conststd::stringmsg){std::coutname_发送: msgstd::endl;mediator_-sendMsg(msg,this);}voidreceive(conststd::stringmsg){std::coutname_收到: msgstd::endl;}private:std::string name_;ChatMediator*mediator_;};// 用法聊天不用加好友找中介ChatRoom room;Useruser1(猫哥,room);Useruser2(狗弟,room);room.addUser(user1);room.addUser(user2);user1.send(今晚吃鸡);// 输出// 猫哥发送: 今晚吃鸡// 狗弟收到: 今晚吃鸡猫哥结语设计模式是调料包不是主食一口气逛完20大设计模式是不是感觉代码世界豁然开朗最后叮嘱几句别走火入魔不是所有代码都要套模式KISS原则Keep It Simple, Stupid永不过时。看懂再用半懂不懂硬套恭喜喜提“屎山代码”一座C特色善用RAII管理资源智能指针防内存泄漏模板元编程玩出花。记住好代码不是模式堆出来的是让读的人拍大腿喊“妙啊”下次写代码卡壳翻出猫哥这篇保证药到病除