面向对象设计原则原则的目的面向对象设计原创表单一职责原则案例开闭原则案例依赖倒转原则案例

面向对象设计原则


对于面向对象软件系统的设计而言,在支持可维护性的同时,提高系统的可复用性是一个至关重要的问题,如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。在面向对象设计中,可维护性的复用是以设计原则为基础的。每一个原则都蕴含一些面向对象设计的思想,可以从不同的角度提升一个软件结构的设计水平。


面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一。


原则的目的: 高内聚,低耦合


面向对象设计原创表



1,单一职责原则:

如果将每个类的方法分离出来,就能够保证每个类的指针单一.

提高了安全性.

提高了可维护性

提高了可读性.



单一原则,示范1,

chunli@linux:~/design$catmain.cpp#include<iostream>usingnamespacestd;classclothes{public:voidworking(){cout<<"穿正式的衣服"<<endl;}voidshoping(){cout<<"穿休闲的衣服"<<endl;}};intmain(){clothesc;c.working();c.shoping();return0;}chunli@linux:~/design$g++main.cpp&&./a.out穿正式的衣服穿休闲的衣服chunli@linux:~/design$


但是这个项目,老程序员走了,新的程序员接手,要求上班穿休闲的衣服

于是代码就变成了这样的:

chunli@linux:~/design$g++main.cpp&&./a.out穿正式的衣服穿正式的衣服chunli@linux:~/design$catmain.cpp#include<iostream>usingnamespacestd;classclothes{public:voidworking(){cout<<"穿正式的衣服"<<endl;}voidshoping(){cout<<"穿正式的衣服"<<endl;}};intmain(){clothesc;c.working();c.shoping();return0;}chunli@linux:~/design$g++main.cpp&&./a.out穿正式的衣服穿正式的衣服chunli@linux:~/design$


后来又有新的程序员看着这两行的功能是一样 的,于是又改成这样的

chunli@linux:~/design$catmain.cpp#include<iostream>usingnamespacestd;classclothes{public:voidworking(){cout<<"穿正式的衣服"<<endl;}voidshoping(){cout<<"穿正式的衣服"<<endl;}};intmain(){clothesc;c.working();c.working();return0;}chunli@linux:~/design$g++main.cpp&&./a.out穿正式的衣服穿正式的衣服chunli@linux:~/design$


再来新手接这样的项目就彻底晕了.....

写成单一原则,这样就不用搞来搞去了,不要修改已经写好的代码.

chunli@linux:~/design$catmain.cpp#include<iostream>usingnamespacestd;classClothesWoring{public:voidstyle(){cout<<"穿正装"<<endl;}};classClothesShoping{public:voidstyle(){cout<<"穿休闲装"<<endl;}};intmain(){ClothesShopingcs;ClothesWoringcw;cs.style();cw.style();return0;}chunli@linux:~/design$g++main.cpp&&./a.out穿休闲装穿正装chunli@linux:~/design$


单一职责原则:

如果将每个类的方法分离出来,就能够保证每个类的指针单一.

提高了安全性.

提高了可维护性

提高了可读性.



2,开闭原则案例:

类的改动是添加代码,而不是修改源代码

原始的代码:chunli@linux:~$catmain.cpp//设计模式开闭原则//定义:类的改动是增加代码进行的,而不是修改源代码#include<iostream>usingnamespacestd;classBanker{public:voidsave(){cout<<"存款"<<endl;}voidpay(){cout<<"付款"<<endl;}voidtransfer(){cout<<"转账"<<endl;}};intmain(){BankerB;B.save();B.pay();B.transfer();return0;}chunli@linux:~$g++main.cpp&&./a.out存款付款转账chunli@linux:~$

代码优化,

chunli@linux:~$catmain.cpp//设计模式开闭原则//定义:类的改动是增加代码进行的,而不是修改源代码#include<iostream>usingnamespacestd;//////////////////////////////////////////////////////////////////classAbstractBanker//抽象类{public://AbstractBanker()=0;virtual~AbstractBanker(){};virtualvoidwork()=0;//接口};////////////////////////////////////////////classSaveBanker:publicAbstractBanker//存款,继承抽象类{public:virtualvoidwork(){cout<<"存款方法"<<endl;}};classPayBanker:publicAbstractBanker//支付,继承抽象类{public:virtualvoidwork(){cout<<"支付方法"<<endl;}};classTransferBanker:publicAbstractBanker//转账,继承抽象类{public:virtualvoidwork(){cout<<"转账方法"<<endl;}};/////////////////////////////////////////////////////////intmain(){SaveBanker*sb=newSaveBanker;sb->work();deletesb;PayBanker*pb=newPayBanker;pb->work();deletesb;TransferBanker*tb=newTransferBanker;tb->work();deletetb;return0;}chunli@linux:~$g++main.cpp-Wall&&./a.out存款方法支付方法转账方法chunli@linux:~$


新增 基金办理 需求,不再需要修改源代码

chunli@linux:~$catmain.cpp//设计模式开闭原则//定义:类的改动是增加代码进行的,而不是修改源代码#include<iostream>usingnamespacestd;//////////////////////////////////////////////////////////////////classAbstractBanker//抽象类{public://AbstractBanker()=0;virtual~AbstractBanker(){};virtualvoidwork()=0;//接口};////////////////////////////////////////////classSaveBanker:publicAbstractBanker//存款,继承抽象类{public:virtualvoidwork(){cout<<"存款方法"<<endl;}};classPayBanker:publicAbstractBanker//支付,继承抽象类{public:virtualvoidwork(){cout<<"支付方法"<<endl;}};classTransferBanker:publicAbstractBanker//转账,继承抽象类{public:virtualvoidwork(){cout<<"转账方法"<<endl;}};classFundBanker:publicAbstractBanker//新增基金,继承抽象类,不需要修改其他类的源代码{public:virtualvoidwork(){cout<<"基金办理"<<endl;}};/////////////////////////////////////////////////////////intmain(){SaveBanker*sb=newSaveBanker;sb->work();deletesb;PayBanker*pb=newPayBanker;pb->work();deletesb;TransferBanker*tb=newTransferBanker;tb->work();deletetb;FundBanker*fb=newFundBanker;fb->work();deletefb;return0;}chunli@linux:~$g++main.cpp-Wall&&./a.out存款方法支付方法转账方法基金办理chunli@linux:~$


总结:

开闭原则:安全稳定,可维护.



3,依赖倒转原则案例:

张三上班开奔驰

chunli@linux:~$catmain.cpp//设计模式:依赖倒转#include<iostream>usingnamespacestd;classBenz{public:voidrun(){cout<<"奔驰启动了"<<endl;}};classZhangsan{public:voiddriveBenz(Benz*car){cout<<"张三开车上班"<<endl;car->run();}};intmain(){Benz*benz=newBenz;Zhangsan*z3=newZhangsan;z3->driveBenz(benz);return0;}chunli@linux:~$g++main.cpp-Wall&&./a.out张三开车上班奔驰启动了chunli@linux:~$


张三还可能开宝马上班

chunli@linux:~$catmain.cpp//设计模式:依赖倒转#include<iostream>usingnamespacestd;classBenz{public:voidrun(){cout<<"奔驰启动了"<<endl;}};classBMW{public:voidrun(){cout<<"宝马启动了"<<endl;}};classZhangsan{public:voiddriveBenz(Benz*car){cout<<"张三开车上班"<<endl;car->run();}voiddriveBMW(BMW*car){cout<<"张三开车上班"<<endl;car->run();}};intmain(){Benz*benz=newBenz;Zhangsan*z3=newZhangsan;z3->driveBenz(benz);BMW*bmw=newBMW;z3->driveBMW(bmw);return0;}chunli@linux:~$g++main.cpp-Wall&&./a.out张三开车上班奔驰启动了张三开车上班宝马启动了chunli@linux:~$

-------------------------------

业务逐渐复杂,那大众呢?越来越多的的呢?

越来越乱............

------------------------------------------


将业务层和实现层 通过抽象层 隔离,解耦合

chunli@linux:~$catmain.cpp//设计模式:依赖倒转//将业务层和实现层通过抽象层隔离,解耦合#include<iostream>usingnamespacestd;//////////抽象层车人////////////////////////////classCar{public:virtualvoidrun()=0;virtual~Car(){}};classDriver{public:virtualvoiddrive(Car*car)=0;virtual~Driver(){}};////////实现层/////////////////////////classZhangSan:publicDriver{public:virtualvoiddrive(Car*car){cout<<"张三开车上班了"<<endl;car->run();}};classLiSi:publicDriver{public:virtualvoiddrive(Car*car){cout<<"李四开车上班了"<<endl;car->run();}};classBenz:publicCar{public:virtualvoidrun(){cout<<"Benz启动了"<<endl;};};classBMW:publicCar{public:virtualvoidrun(){cout<<"BMW启动了"<<endl;};};/////////////主函数////////////////////////////////////intmain(){//让张三开奔驰Car*benz=newBenz;Driver*zhangsan=newZhangSan;zhangsan->drive(benz);//让李四上班开宝马Car*bmw=newBMW;Driver*lisi=newLiSi;lisi->drive(bmw);return0;}chunli@linux:~$g++main.cpp-Wall&&./a.out张三开车上班了Benz启动了李四开车上班了BMW启动了chunli@linux:~$




依赖倒转原则,电脑组装案例:

抽象层:CPU,显卡,内存

框架层:组合CPU,显卡,内存

chunli@linux:~$catmain.cpp//设计模式:依赖倒转,电脑组装案例#include<iostream>usingnamespacestd;//抽象类classCPU{public:virtualvoidcaculate()=0;virtual~CPU(){}};classCard{public:virtualvoiddisplay()=0;virtual~Card(){}};classMemmory{public:virtualvoidstorage()=0;virtual~Memmory(){}};//架构类classComputer{public:Computer(CPU*cpu,Card*card,Memmory*mem){this->cpu=cpu;this->card=card;this->mem=mem;}virtual~Computer(){};voidwork(){cpu->caculate();card->display();mem->storage();}private:CPU*cpu;Card*card;Memmory*mem;};//////实现层//////////////////////////////////classIntelCPU:publicCPU{public:virtualvoidcaculate(){cout<<"intelCPUworking"<<endl;}};classNvidiaCard:publicCard{public:virtualvoiddisplay(){cout<<"nvidiacardworking"<<endl;}};classKingSton:publicMemmory{public:virtualvoidstorage(){cout<<"KingStonmemworking"<<endl;}};/////////主函数///////////////////intmain(){CPU*cpu=newIntelCPU;Card*card=newNvidiaCard;Memmory*mem=newKingSton;Computer*computer=newComputer(cpu,card,mem);computer->work();return0;}chunli@linux:~$g++main.cpp-Wall&&./a.outintelCPUworkingnvidiacardworkingKingStonmemworkingchunli@linux:~$


里氏代换原则:略

接口隔离原则:

合成复用原则:继承,组合,依赖

能用组合不用继承

迪米特法则: