设计原则


前言

学习并遵守设计原则可以让我们的代码更加容易维护和扩展, 一下便是对设计原则的一些说明


提示:以下是本篇文章正文内容

一、设计原则是什么?

其实文字已经体现出来了, 更确切的说是程序设计原则, 原则即参考标准, 他不是强制的, 但在很多场景下使用该标准可以让你的代码变得更加容易维护和扩展

二、为什么要使用设计原则 ?

软件发展至今, 已由原来的个人程序到现在的大规模多人应用程序, 从这一方面来说, 程序在不断的扩大, 从原来的一个小工具变成了一整套系统, 在大型软件构建中很容易因为代码体量过大, 构架不清晰, 设计不合理从而导致软件无法继续开发下去, 最终导致软件失败

另一方面, 客户需求不总是那么确定的, 我们需要有良好的方案来应对变化

三、有哪些设计原则

  • 单一职责
  • 开闭原则
  • 依赖倒置
  • 里氏替换
  • 接口隔离
  • 迪米特法则

四、原则详解

1. 单一职责

该模式很好理解, 一个 功能/模块/类/函数 不该有过多的责任, 尽量保证职责的单一性

场景: 假设你需要 生成PDF 并对 PDF 签名

class DealPdf
{
	public function createPdfAndSinger()
	{
		$pdf = new Pdf();
		$pdf->writeText(100,100,'hello world');
		$pdf->writeText(130,100,'hello world');
		$pdf->writeText(160,100,'hello world');
		$pdf->complete('temp.pdf');
		
		$singer = new Singer();
		$singer->setLoca('');
		$singer->setTime('');
		$singer->setTitle('');
		$singer->setAuth('');
		$singer->setDesc('');
		$singer->singerPdf('temp.pdf','singer.pdf');
		
		return 'singer.pdf';
	}
}
  • 该代码既有创建职责又有签名职责, 但你想改变创建规则或者修改签名规则, 你不得不去修改源码, 此时由于 签名和创建 两个功能耦合在一起, 所以你必须一起测试
  • 假设后期需要一个相同的PDF却不带签名, 你需要重新写一次PDF 的创建过程
  • 假设后期需要直接对一个PDF签名且签名内容不变, 你也需要重新写一次签名的过程
  • 但这些问题一开始就可以规避掉, 将PDF的构建过程和签名的构建过程分离开, 使得这两个职责可以独立变化

改良后

class createPdf
{
	public function create()
	{
		$pdf = new Pdf();
		$pdf->writeText(100,100,'hello world');
		$pdf->writeText(130,100,'hello world');
		$pdf->writeText(160,100,'hello world');
		$pdf->complete('temp.pdf');
		
		return 'temp.pdf';
	}
}

class singerPdf
{
	public function singer($pdfPath)
	{
		$singer = new Singer();
		$singer->setLoca('');
		$singer->setTime('');
		$singer->setTitle('');
		$singer->setAuth('');
		$singer->setDesc('');
		$singer->singerPdf('temp.pdf','singer.pdf');
		
		return 'singer.pdf';
	}
}

class DealPdf
{
	public function createPdfAndSinger()
	{
		$singer = new singerPdf();
		$pdfBuild = new createPdf();
		
		return $singer->singer($pdfBuild->create());
	}
}

  • 改良之后, 无论是想修改签名, 还是想修改PDF的创建过程都不会影响到另一方
  • 这个原则我们在使用函数的时候就已经接触过, 通常情况下我们会将我们的复杂函数分解成一些简单的函数, 每个函数的目的性和内聚都很强
  • 当然, 该原则通常会增加代码, 分解也不应过细, 应当根据项目的实际情况出发
  • 比如在这个案例中, 当我们能确定只使用创建并签名这一个功能时, 我们大可不必将其拆分
  • 原则和模式存在于稳定与变化之中, 如果能够预料到变化可能性, 那么在设计之初就应当按原则设计以应对变化

2. 开闭原则

  • 该模式可以认定为目标, 即程序设计目标
  • 我们的程序应该尽量的达到该原则
  • 该原则表达为: 对扩展开放, 对修改封闭, 那么怎么理解呢 ?
  • 当我们的设计的功能无法满足客户需要, 我们需要调整软件的功能
  • 根据开闭原则, 需要我们写一份新的代码, 而不是直接修改源代码的方式去更新功能
  • 通常是通过调整配置配合新的代码从而完成新的功能

3. 依赖倒置

  • 该模式要求我们依赖抽象和接口
  • 其实很好理解, 就好比你去吃饭, 你只要去饭店你就能吃到饭, 而如果你非要去XX饭店吃饭, 那么如果这个饭店关门几天那么你可能会饿着
  • 同理, 我们依赖抽象和接口时, 即便我们的具体类有些问题, 我们也可以轻松的根据里氏替换原则更换其他的具体类
  • 该原则是开闭原则的基础原则, 只有遵循该原则才能在扩展功能时实现平滑替换

4. 里氏替换

  • 该模式要求, 所有引用父类的地方都能透明的使用其子类进行替换
  • 饭店有的功能, xx饭店就一定会有就是这个道理
  • 该模式同样也是开闭原则的基础原则

5. 接口隔离

  • 使用多个专门的接口比使用总的统一的接口好
  • 不要给客户端提供他们用不到的接口, 对于不同的客户端需要进行接口屏蔽

6. 迪米特法则

  • 该法则也叫最少知识法则, 一个模块一个类尽量少与陌生的模块联系

五、总结

  • 遵循原则写代码你可以写出扩展和维护上良好的代码, 但前期投入时间可能会长
  • 所以不能死记原则, 在实际开发中我们应该 因时制宜, 因地制宜
  • 结合自身情况, 比如:你想多久跳槽, 你想划多少水, 比如是否有甩锅的法子等等, 这样的写出来的代码才是最佳实践!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值