面向对象设计原则 
原则的目的
面向对象设计原创表 

单一职责原则案例
开闭原则 案例
依赖倒转原则 案例

面向对象设计原则 


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


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


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


面向对象设计原创表 

wKioL1g9S6WgngolAAOuZbIXL0U218.png



1,单一职责原则:

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

提高了安全性.

提高了可维护性

提高了可读性.



单一原则,示范1,

chunli@linux:~/design$ cat main.cpp 
#include <iostream>
using namespace std;

class clothes
{
public:
	void working()
	{
		cout << "穿正式的衣服" <<endl;
	}
	void shoping()
	{
		cout << "穿休闲的衣服" <<endl;
	}
};

int main()
{
	clothes c ;
	c.working();
	c.shoping();
	return 0;
}
chunli@linux:~/design$ g++ main.cpp && ./a.out 
穿正式的衣服
穿休闲的衣服
chunli@linux:~/design$


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

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

chunli@linux:~/design$ g++ main.cpp && ./a.out 
穿正式的衣服
穿正式的衣服
chunli@linux:~/design$ cat main.cpp 
#include <iostream>
using namespace std;

class clothes
{
public:
	void working()
	{
		cout << "穿正式的衣服" <<endl;
	}
	void shoping()
	{
		cout << "穿正式的衣服" <<endl;
	}
};

int main()
{
	clothes c ;
	c.working();
	c.shoping();
	return 0;
}
chunli@linux:~/design$ g++ main.cpp && ./a.out 
穿正式的衣服
穿正式的衣服
chunli@linux:~/design$


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

chunli@linux:~/design$ cat main.cpp 
#include <iostream>
using namespace std;

class clothes
{
public:
	void working()
	{
		cout << "穿正式的衣服" <<endl;
	}
	void shoping()
	{
		cout << "穿正式的衣服" <<endl;
	}
};

int main()
{
	clothes c ;
	c.working();
	c.working();
	return 0;
}
chunli@linux:~/design$ g++ main.cpp && ./a.out 
穿正式的衣服
穿正式的衣服
chunli@linux:~/design$


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

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

chunli@linux:~/design$ cat main.cpp 
#include <iostream>
using namespace std;

class ClothesWoring
{
public:
	void style()
	{
		cout << "穿正装" << endl;
	}
};
class ClothesShoping
{
public:
	void style()
	{
		cout << "穿休闲装" << endl;
	}
};
int main()
{
	ClothesShoping cs;
	ClothesWoring cw;
	cs.style();
	cw.style();

	return 0;
}
chunli@linux:~/design$ g++ main.cpp && ./a.out 
穿休闲装
穿正装
chunli@linux:~/design$


单一职责原则:

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

提高了安全性.

提高了可维护性

提高了可读性.



2,开闭原则案例:

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

原始的代码:
chunli@linux:~$ cat main.cpp 
//设计模式 开闭原则
//定义:类的改动是增加代码进行的,而不是修改源代码


#include<iostream>
using namespace std;
class Banker
{
public:
	void save()
	{
		cout << "存款" << endl;
	}
	void pay()
	{
		cout <<"付款" << endl;
	}
	void transfer()
	{
		cout << "转账 " <<endl;
	}
};

int main()
{
	Banker B;
	B.save();
	B.pay();
	B.transfer();
	return 0;
}
chunli@linux:~$ g++ main.cpp && ./a.out 
存款
付款
转账 
chunli@linux:~$

代码优化,

chunli@linux:~$ cat main.cpp 
//设计模式 开闭原则
//定义:类的改动是增加代码进行的,而不是修改源代码


#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////
class AbstractBanker //抽象类
{
public:
	//AbstractBanker() = 0;
	virtual ~AbstractBanker(){};
	virtual void work() = 0;//接口
};
// // // // // // // // // // // // // // // // // // // // // //

class SaveBanker:public AbstractBanker //存款,继承抽象类
{
public:
	virtual void work()
	{
		cout << "存款方法" << endl;
	}
};

class PayBanker:public AbstractBanker //支付,继承抽象类
{
public:
	virtual void work()
	{
		cout << "支付方法" << endl;
	}
};

class TransferBanker:public AbstractBanker //转账,继承抽象类
{
public:
	virtual void work()
	{
		cout << "转账方法" << endl;
	}
};
/////////////////////////////////////////////////////////

int main()
{
	SaveBanker* sb = new SaveBanker;
	sb->work();
	delete sb;

	PayBanker  *pb = new PayBanker;
	pb->work();
	delete sb;

	TransferBanker *tb = new TransferBanker;
	tb->work();
	delete tb;

	return 0;
}
chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
存款方法
支付方法
转账方法
chunli@linux:~$


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

chunli@linux:~$ cat main.cpp 
//设计模式 开闭原则
//定义:类的改动是增加代码进行的,而不是修改源代码


#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////
class AbstractBanker //抽象类
{
public:
	//AbstractBanker() = 0;
	virtual ~AbstractBanker(){};
	virtual void work() = 0;//接口
};
// // // // // // // // // // // // // // // // // // // // // //

class SaveBanker:public AbstractBanker //存款,继承抽象类
{
public:
	virtual void work()
	{
		cout << "存款方法" << endl;
	}
};

class PayBanker:public AbstractBanker //支付,继承抽象类
{
public:
	virtual void work()
	{
		cout << "支付方法" << endl;
	}
};

class TransferBanker:public AbstractBanker //转账,继承抽象类
{
public:
	virtual void work()
	{
		cout << "转账方法" << endl;
	}
};

class FundBanker:public AbstractBanker //新增基金,继承抽象类,不需要修改其他类的源代码
{
public:
	virtual void work()
	{
		cout << "基金办理" << endl;
	}
};
/////////////////////////////////////////////////////////

int main()
{
	SaveBanker* sb = new SaveBanker;
	sb->work();
	delete sb;

	PayBanker  *pb = new PayBanker;
	pb->work();
	delete sb;

	TransferBanker *tb = new TransferBanker;
	tb->work();
	delete tb;
	FundBanker *fb = new FundBanker;
	fb->work();
	delete fb;

	return 0;
}
chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
存款方法
支付方法
转账方法
基金办理
chunli@linux:~$


总结:

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



3,依赖倒转原则案例:

张三上班开奔驰

chunli@linux:~$ cat main.cpp 
//设计模式:依赖倒转

#include<iostream>
using namespace std;

class Benz
{
public:
	void run()
	{
		cout << "奔驰启动了" << endl;
	}
};

class Zhangsan
{
public:
	void driveBenz(Benz *car)
	{
		cout << "张三 开车上班"<< endl;
		car->run();
	}
};

int main()
{
	Benz *benz = new Benz;
	Zhangsan *z3 = new Zhangsan;
	z3->driveBenz(benz);
	
	return 0;
}
chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
张三 开车上班
奔驰启动了
chunli@linux:~$


张三还可能开宝马上班

chunli@linux:~$ cat main.cpp 
//设计模式:依赖倒转

#include<iostream>
using namespace std;

class Benz
{
public:
	void run()
	{
		cout << "奔驰启动了" << endl;
	}
};

class BMW
{
public:
	void run()
	{
		cout << "宝马启动了" << endl;
	}
};

class Zhangsan
{
public:
	void driveBenz(Benz *car)
	{
		cout << "张三 开车上班"<< endl;
		car->run();
	}
	void driveBMW(BMW *car)
	{
		cout << "张三 开车上班"<< endl;
		car->run();
	}
};

int main()
{
	Benz *benz = new Benz;
	Zhangsan *z3 = new Zhangsan;
	z3->driveBenz(benz);


	BMW *bmw = new BMW;
	z3->driveBMW(bmw);
	
	return 0;
}
chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
张三 开车上班
奔驰启动了
张三 开车上班
宝马启动了
chunli@linux:~$

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

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

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

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


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

chunli@linux:~$ cat main.cpp 
//设计模式:依赖倒转
//将业务层和实现层 通过抽象层 隔离,解耦合 

#include<iostream>
using namespace std;
//////////抽象层 车  人 ////////////////////////////
class Car
{
public:
	virtual void run() = 0;
	virtual ~Car(){}
};

class Driver
{
public:
	virtual void drive(Car *car) = 0;
	virtual ~Driver(){}
};

////////    实现层        /////////////////////////
class ZhangSan:public Driver
{
public:
	virtual void drive(Car *car)
	{
		cout << "张三开车上班了" << endl;
		car->run();
	}
};
class LiSi:public Driver
{
public:
	virtual void drive(Car *car)
	{
		cout << "李四 开车上班了" << endl;
		car->run();
	}
};


class Benz:public Car
{
public:
	virtual void run()
	{
		cout << "Benz 启动了" << endl;
	};
};

class BMW:public Car
{
public:
	virtual void run()
	{
		cout << "BMW 启动了" << endl;
	};
};
///////////// 主函数 ////////////////////////////////////
int main()
{
	//让张三开奔驰
	Car * benz = new Benz;
	Driver *zhangsan = new ZhangSan;
	zhangsan->drive(benz);

	//让李四上班 开宝马
	Car *bmw = new BMW;
	Driver *lisi = new LiSi;
	lisi->drive(bmw);  


	return 0;
}
chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
张三开车上班了
Benz 启动了
李四 开车上班了
BMW 启动了
chunli@linux:~$




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

抽象层:CPU,显卡,内存

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

chunli@linux:~$ cat main.cpp 
//设计模式:依赖倒转,电脑组装案例
#include<iostream>
using namespace std;

//抽象类
class CPU
{
public:
	virtual void caculate() = 0;
	virtual ~CPU(){}
};

class Card
{
public:
        virtual void display() = 0;
	virtual ~Card(){}
};

class Memmory
{
public:
	virtual void storage() = 0;
	virtual ~Memmory(){}
};

//架构类
class Computer
{
public:
	Computer(CPU* cpu,Card* card,Memmory* mem)
	{
		this->cpu = cpu;
		this->card = card;
		this->mem = mem;
	}
	virtual ~Computer() {};
	void work()
	{
		cpu->caculate();
		card->display();
		mem->storage();
	}
private:
	CPU *cpu;
	Card *card;
	Memmory* mem;
};
//////实现层//////////////////////////////////
class IntelCPU:public CPU
{
public:
	virtual void caculate()
	{
		cout << "intel CPU working" << endl;
	}
};

class NvidiaCard:public Card
{
public:
	virtual void display()
	{
		cout << "nvidia card  working" << endl;
	}
};
class KingSton:public Memmory
{
public:
	virtual void storage()
	{
		cout << "KingSton mem  working" << endl;
	}
};
/////////  主函数 ///////////////////
int main()
{

	CPU* cpu 	= new IntelCPU;
	Card* card 	= new NvidiaCard;
	Memmory* mem	= new KingSton;

	Computer* computer = new Computer(cpu,card,mem);
	computer->work();
	return 0;
}





chunli@linux:~$ g++ main.cpp -Wall && ./a.out 
intel CPU working
nvidia card  working
KingSton mem  working
chunli@linux:~$


里氏代换原则:略

接口隔离原则:

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

能用组合不用继承

迪米特法则: