设计模式的设计原则

关于设计模式

从Grace Hopper发明世界上第一个编译器 (Compiler)起,越来越多的人走入编程的世界,完成程序设计。然而并不是所有的事情都是一帆风顺的,无数的程序员在实践的过程中肯定也绕过不少弯路。先驱们为了让后面的人尽量不再犯同样的错误,就会对之前所经历的教训进行总结,这就有了设计模式。
**设计模式(Design Pattern)**基于面向对象设计的原则,是软件开发人员在软件开发过程中面临的常见问题的解决方案。这些解决方案极具参考性,它以某种形式展现出了优秀的程序设计人员在利用计算机解决问题时候的思路。这些经过多年实践验证有效的解决思路,即便未来不再做程序设计,认真学习一下,对于个人的思维成长也会有很大帮助。

设计原则

一、单一职责原则

单一职责原则(Single Responsibility Principle,SRP):一个类只负责一个功能领域中的相应职责,即一个类或者模块应该有且只有一个改变的原因。

使用动机

在做编程的时候,我们很容易会给类加各种各样的功能,比如我们写一个窗体应用程序,一般都会生成一个Forml这样的类,于是我们就把各种各样的代码,像某种商业运算的算法呀,像数据库访问的SQL语句呀什么的都写到这样的类当中。这就意味着,一旦有了新需求,我们都需要再来更改这个窗体类,这其实是很糟糕的,维护麻烦,灵活性很差。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。

关键点

职责的分解。在对具体的功能进行划分时,要将不同的职责分开到不同的类进行实现,尽量保证彼此之间互不影响。在这种情况下里,每一个类实现的职责有清晰明确的定义,且对其中某一个功能/目标的修改,只会对特定的类产生影响,而对其它的类不会有影响。

二、开闭原则

开放-封闭原则(Open-Closed Principle,OCP):一个软件实体如类、模块和函数应该对扩展开放的(Open for extension),对修改关闭(Closed for modification)。

使用动机

做任何系统,都不要指望系统一开始时需求确定,就再也不会变化。从中透射出一个关键的意思就是,对于软件设计者来说,当需要扩展软件的功能,可以通过添加新的代码来实现,而不需要修改原有的代码。

关键点

对程序中呈现出频繁变化的那些部分做出抽象,做到应用程序可维护、可扩展、可复用、灵活性好。实现开闭原则,需要做到:

  • 抽象:将软件实体抽象成接口或抽象类,并通过继承或实现来实现行为的扩展。(仅对程序中呈现出频繁变化的部分做出抽象。不要刻意对每个部分进行抽象,拒绝不成熟的抽象,它和抽象本身一样重要。)
  • 封装:将具体的实现细节封装起来,并进行充分的测试。

软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。

三、迪米特法则

迪米特法则(Law of Demeter,LoD):也叫最少知识原则,类应尽量降低成员的访问权限,即一个对象应该尽可能少地了解其他对象的内部细节:一个类包装好自己的private状态,不需要让别的类知道的字段或行为就不要公开。

使用动机

迪米特法则的核心观念就是类间解耦,也就降低类之间的耦合,如果两个类之间的依赖关系过于紧密,那么当一个类发生改变时,可能会导致另一个类也发生改变,这样会使得系统不稳定。
只有类处于弱耦合状态,类的复用率才会提高。

实现要点

  • 减少公开方法和变量。
  • 每个类对其他类知道的越少越好,使用中介来实现类之间的通信。
  • 类不应该知道它所操作的对象的内部细节。

客观来说,如果过度追求降低耦合,有可能产生大量的中间类或者跳转类,导致系统的复杂性提高,可维护性降低。所以也得根据情况来适当完成。

四、里氏替换原则

里氏替换原则(Liskov Substituion Principle,LSP):一个软件实体如果使用的是一个父类的话,一定适用于其子类,而且它察觉不出父类和子类的区别。

使用动机

LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对"开-闭"原则的补充。实现"开-闭"原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

关键点

在设计程序的时候先对基类进行对象的定义和引用,在运行时再决定基类的具体子类型,保证所有引用基类的地方都能透明地使用其子类的对象。

五、依赖倒置原则

依赖倒置原则(Dependency Inversion Principle,DIP):高层次的类不应依赖低层次的类,都应依赖于抽象接口。简单来说,就是要针对接口编程,不要针对实现编程。

使用动机

依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性。如果说实现开闭原则的关键事抽象化,是面向对象设计的目标的话,依赖倒置原则就是这个面向对象设计的主要机制。

关键点

抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程:

  • 每个类尽量提供接口或抽象类,或者两者都具备。
  • 变量的声明类型尽量是接口或者是抽象类。
  • 任何类都不应该从具体类派生。
  • 使用继承时尽量遵循里氏替换原则。

里氏替换原则是关于子类与父类的原则;依赖倒置原则是关于抽象与细节的原则。

参考

[1] datawhale大话设计模式教程云 - GitHub
[2] 设计模式概念和七大原则 - 腾讯云开发者社区 - 腾讯云

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值