软件设计模式-面向对象设计原则及案例分析

软件设计模式-面向对象设计原则

一、面向对象设计原则

  1. 如何同时提高一个软件系统的可维护性和可复用性是面向对象设计需要解决的核心问题之一。
  2. 面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计 模式中,它们是从许多设计方案中总结出的指导性原则。
  3. 原则的目的:高内聚,低耦合。

二、七大原则

名称定义
单一职责原则 类的职责单一,对外只提供一种功能,而引起类变 化的原因都应该只有一个。
开闭原则 类的改动通过增加代码实现,而不修改源码。
里氏代换原则 也就是虚拟机制:任何抽象类出现的地方,都可以用他的实现类进行替换。
依赖倒转原则也就是针对接口编程:依赖于抽象,而不依赖于具体的实现
接口隔离原则不强迫用户依赖他们不需要的接口方法。即:一个接口只实现一种功能
合成复用原则对于继承和组合,优先使用组合。因为使用继承,父类的任何变化都可能影响到子类的行为
迪米特法则一个对象对其它对象应尽可能少的了解,从而降低对象之间的耦合。例如:提供一个统一的接口,来实现模块之间的调用。

三、开闭原则案例

类的改动通过增加代码实现,而不修改源码。
以银行业务员为例,通过多态可实现开闭原则。
在这里插入图片描述

#include <iostream>
using namespace std;

//繁忙的银行业务员
class BankWorker
{
public:
	//存钱
	void save() { cout << "存钱" << endl; }

	//转账
	void transfer() { cout << "转账" << endl; }

	//...

	//随着业务的增加,类会越来越臃肿

};

//轻松的银行业务员
class RBankWorker
{
public:
	virtual void doBusiness() = 0;
};

class saveBankWorker : public RBankWorker
{
public:
	virtual void doBusiness(){ 
		cout << "存钱" << endl; 
	}
};

class transferBankWorker : public RBankWorker
{
public:
	virtual void doBusiness() {
		cout << "转账" << endl;
	}
};

//...
//例如,我们现在需要添加基金办理业务
class fundBankWorker : public RBankWorker
{
public:
	virtual void doBusiness() {
		cout << "基金办理" << endl;
	}
};

int main(void)
{
	RBankWorker* rw = NULL;
	rw = new saveBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;//务必添加,因为指针变量和指针指向的内存空间是两码事

	rw = new transferBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;

	rw = new fundBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;

	return 0;
}

四、依赖倒转原则案例

针对接口编程:依赖于抽象,而不依赖于具体的实现
在这里插入图片描述
传统】的过程式设计倾向于高层次依赖于低层次,抽象层依赖于具体实现层。
例如:仍以银行业务员为例

#include <iostream>
using namespace std;

//繁忙的银行业务员
class BankWorker
{
public:
	//存钱
	void save() { cout << "存钱" << endl; }

	//转账
	void transfer() { cout << "转账" << endl; }

	//...

	//随着业务的增加,类会越来越臃肿

};

//轻松的银行业务员
class RBankWorker
{
public:
	virtual void doBusiness() = 0;
};

class saveBankWorker : public RBankWorker
{
public:
	virtual void doBusiness(){ 
		cout << "存钱" << endl; 
	}
};

class transferBankWorker : public RBankWorker
{
public:
	virtual void doBusiness() {
		cout << "转账" << endl;
	}
};

//...
//例如,我们现在需要添加基金办理业务
class fundBankWorker : public RBankWorker
{
public:
	virtual void doBusiness() {
		cout << "基金办理" << endl;
	}
};

void doBusiness(RBankWorker* rw)
{
	rw->doBusiness();
}

void printAllWorker(RBankWorker* rw)
{
	rw = new saveBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;

	rw = new transferBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;

	rw = new fundBankWorker;
	rw->doBusiness();
	delete rw;
	rw = NULL;
}

int main(void)
{
	RBankWorker* rw = NULL;
	rw = new saveBankWorker;
	doBusiness(rw);
	delete rw;
	rw = NULL;

	printAllWorker(rw);

	return 0;
}

这样自顶向下逐级依赖,底层模块、中间层模块和高层模块耦合度极高。一旦修改其中一个,很可能导致全面修改,非常麻烦。
而依赖倒转原则利用多态的特性,对中间层进行抽象依赖,这样底层和高层就解耦合了。
在这里插入图片描述
案例:组装电脑。电脑的硬盘,CPU,内存第三厂商均可以进行对接,但是电脑生产公司只是对外提供抽象中间层接口,第三方厂商想要加入只需要面向这个抽象类实现各自的实例就可以了。

#include <iostream>
using namespace std;

/* 中间层,抽象层 */
//硬盘
class HardDisk
{
public:
	virtual void doWork() = 0;
};

//内存
class Memory
{
public:
	virtual void doWork() = 0;
};

//CPU
class Cpu
{
public:
	virtual void doWork() = 0;
};

/*
让Computer框架和具体的厂商解耦合
*/

/*高级架构层*/
class Computer
{
public:
	Computer(HardDisk* hd, Memory* mem, Cpu* Cpu)
	{
		this->hd = hd;
		this->mem = mem;
		this->Cpu = Cpu;
	}

	//架构层并不关心是哪个厂商,只关心抽象层的业务
	void doWork()
	{
		hd->doWork();
		mem->doWork();
		Cpu->doWork();
	}
private:
	HardDisk* hd;
	Memory* mem;
	Cpu* Cpu;
};

/*
实现层,具体的厂商
*/

//西数硬盘
class XiShuHardDisk : public HardDisk
{
public:
	virtual void doWork()
	{
		cout << "西数硬盘正在运行中..." << endl;
	}
};

//金士顿内存
class KingstonMemory : public Memory
{
public:
	virtual void doWork()
	{
		cout << "金士顿内存正在运行中..." << endl;
	}
};

//AMD CPU
class AmdCpu : public Cpu
{
public:
	virtual void doWork()
	{
		cout << "AMD CPU正在运行中..." << endl;
	}
};

int main()
{
	XiShuHardDisk* xs = new XiShuHardDisk;
	KingstonMemory* kingston = new KingstonMemory;
	AmdCpu* amd = new AmdCpu;

	Computer* myComputer = new Computer(xs, kingston, amd);
	myComputer->doWork();

	delete xs;
	delete kingston;
	delete amd;
	delete myComputer;

	return 0;
}

五、迪米特法则

不符合迪米特法则的方式
在这里插入图片描述
符合迪米特法则,不和陌生人说话
在这里插入图片描述
迪米特法则结合依赖倒转原则
在这里插入图片描述

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

banjitino

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值