软件设计的“七宗罪”及设计模式的七大原则

编写软件过程中,面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序,具有更好的代码重用性、可读性、可扩展性、可靠性,使程序呈现高内聚低耦合的特性。

软件设计的“七宗罪”:

  1. 僵化性
  2. 脆弱性
  3. 牢固性
  4. 粘滞性
  5. 不必要的重复
  6. 不必要的复杂性
  7. 晦涩性

1. 僵化性

僵化性是指难以对软件进行改动,即使是简单的改动。如果单一的改动会导致有依赖关系的模块中的连锁改动,那么设计就是僵化的。必须要改动的模块越多,设计就越僵化。

2. 脆弱性

脆弱性是指在进行一个改动时,程序的许多地方就可能出现问题,即设计易于遭破坏。并且,往往是出现新问题的地方与改动的地方并没有概念上的关联。

3. 牢固性

牢固性是指设计中包含了对其他系统有用的部分,但要想把这些部分分离出来所需要的努力和风险是巨大的,即设计难以复用。

4. 粘滞性

有的时候,一个改动可以以保持原有的设计意图和原有的设计框架的方式进行,也可以以破坏原始的意图和框架的方式进行。第一种办法无疑会对系统的未来有利,第二种办法是去权宜之计,可以解决短期问题,但是会牺牲长期利益。如果第二种办法比第一种办法容易得多的话,程序员就有可能牺牲长期利益,采取权宜之计,在一个通用的逻辑中建立一种特例,以便解决眼前的问题。一个系统的设计,如果总是使得第二种办法比第一种办法来得容易,说明粘滞性过高。一个粘滞性过高的系统会诱使维护它的程序员采取错误的维护方案。

5. 不必要的重复

大量的重复代码往往是由于开发人员忽略了抽象,从而使系统不易理解,而且,软件中的重复代码,也会使系统的改动变得困难,不易于系统的维护。

6. 不必要的复杂性

不必要的复杂性是指设计中包含了当前没有用的部分,即过分设计。例如,对于逻辑复杂、技术先进的过度追求,导致了技术框架虽看似华丽却复杂难用。再例如,在设计产品功能或界面交互时,过度追求体验完美、需求满足却导致实际体验下降、功能没人用。所以,软件设计应“有所为有所不为”。

7. 晦涩性

晦涩性是指模块难于理解。代码随时间而不断演化,往往会变得越来越晦涩、可读性差。代码晦涩难懂常体现在如下几点:

  1. 代码不良
  2. 代码的格式不正确或不一致
  3. 代码中包含冗余代码
  4. 代码中包含未备注的低层次优化
  5. 代码逻辑过于复杂

设计模式七大原则有:

  1. 单一职责原则
  2. 接口隔离原则
  3. 依赖倒置原则
  4. 里氏替换原则
  5. 开闭原则
  6. 迪米特法则
  7. 合成复用原则

1. 单一职责原则

单一职责原则SRP(The Single Responsibility Principle)指的就是一个类应该仅有一个引起它变化的原因。这是最简单、最容易理解却最不容易做到的一个设计原则。

对类来说的,即一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。

单一职责原则注意事项和细节:

  1. 降低类的复杂度,一个类只负责一项职责。
  2. 提高类的可读性,可维护性
  3. 降低变更引起的风险

2. 接口隔离原则

接口隔离原则ISP(The Interface Segregation Principle)指的是“客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上”。就是说,“不应该强迫客户依赖于它们不用的方法”。再通俗点说,不要强迫客户使用它们不用的方法,如果强迫客户使用它们不需要的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

下面是一个违反了接口隔离原则的例子:

上述例子中,有普通和高级两种工作者,他们都需要工作和吃饭。但是,现在来了一批机器人,机器人作为公司的工作者,一方面需要工作,需要实现IWorker接口;另一方面机器人不需要吃饭,又不需要实现IWorker接口。这种情况下,IWorker就被认为是一个被污染了的接口。

如果我们保持上面那样的设计,那么Robot类就将被迫实现eat()方法,当然我们可以写一个哑类让它什么也不做,但是这会对程序造成不可预料的结果,例如管理者看到报表中显示被带走的午餐多于实际的人数。

通过接口隔离原则,我们应该把IWorker分离成两个接口,如果Robot类需要添加特有而工人没有的方法,例如充电功能,我们可以再创建一个新的IRechargeable接口,其中包含一个重新充电的方法recharge。

更改后的代码如下:

总之,接口隔离原则是对接口进行规范约束,其包含以下含义:

  1. 接口尽量要小,这是接口隔离原则的核心定义,不要出现臃肿的接口
  2. 接口要高内聚
  3. 定制服务,只提供访问者需要的方法
  4. 接口设计是有限度的

3. 依赖倒置原则

依赖倒置原则DIP(The Dependency Inversion Principle)指的是“高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象”。

好抽象的定义,我们直接上代码,先看一个不符合DIP原则的例子

软件设计的“七宗罪”及设计模式的七大原则
public interface Switchable {    void turnOn();    void turnOff();}public abstract class Light implements Switchable  {}public abstract class TV implements Switchable {}public class BulbLight extends Light {    @Override    public void turnOn() {System.out.println("BulbLight turned on...");    }    @Override    public void turnOff() {System.out.println("BulbLight turned off...");    }}public class TubeLight extends Light {    @Override    publi

来源:街头流浪的puppy

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月1日
下一篇 2021年1月1日

相关推荐