当前位置: 移动技术网 > IT编程>软件设计>面向对象 > 设计原则的简单理解

设计原则的简单理解

2019年03月28日  | 移动技术网IT编程  | 我要评论

前言

好的代码需要有高内聚、低耦合、易扩展且扩展改动小等特点。说实话,我入行很久之后,才知道这些设计原则的名字,但是我并不觉得陌生,反而有一种理所当然的感觉。这得感谢自学时网络上前辈们推荐的书籍,培养了自己的代码洁癖,还得感谢转行后的第一个东家!以下只是我的理解,如有错误,请指正。

单一职责原则

顾名思义,单一职责就是函数或类只做一件事,但是"只做一件事"肯定是针对不同抽象层次的。
举个例子,我要写一个文件,于是我定义了write()这么一个函数,它确实只做一件事。但是这个write()对于写一个文件来说是不够的,我肯定还需要open()close(),自然这两个函数也只做了一件事。
但我要真正写一个文件,希望得到的是下面的函数

int write_file()
{
    open();
    write();
    close();
}

对于write_file()的调用者来说,write_file()确实只做了一件事,它帮我写了一个文件。但对于写write_file()的程序员来说,write_file()明明做了三件事。
单一职责的职责是对外抽象后的职责,只要函数或类所做的事不超过这个抽象定义,那就不算违背单一职责。

越底层的函数越容易确定职责,甚至只需要这个函数写的足够短小,其职责一般就能保证单一。高层的函数或者类就需要考验程序员的抽象能力了。一个简单的检查该抽象是否能做到单一职责的方法,就是看看函数内是否只做了函数名要求的事,类内所有成员函数和成员变量是否只是为了做到类名要求的事。

当我们长期遵循单一职责原则时,我们会习惯于将一个任务拆分为多个最小步骤,而这通常意味着可以通过流水线,并行等方式来执行这些最小步骤,达到提升性能的目的。

里氏替换

里氏替换就是指子类可以出现在父类出现的任何地方。这是一个指导我们何时使用继承的原则。a继承b,我们说"a是一个b",既然"a是一个b",a自然能替换到b出现的任何地方。如果无法替换的话,说明a不应继承b。

依赖倒置

依赖倒置就是为了做到面向接口编程。
那为什么叫倒置呢?原本高层a直接调用底层b的接口,当高层a想用底层c时就可能需要修改大量代码,原因是c和b是没有约束的,c的接口与b可能完全不一样。为了避免替换底层需要修改大量代码的情况,高层a自己定义了抽象层d,让底层b和底层c都依赖抽象层d的接口去实现。因为抽象层d是高层定义的,而底层b和c是依赖d去实现的,所以就叫依赖倒置。在c++中,这通过定义虚基类,并继承该虚基类来实现。

依赖倒置可以使得高层切换底层实现类时,减少代码修改量,只需要修改一下实例化的代码即可,更灵活。

class d
{
public:
    virtual foo1() = 0;
    ...
    virtual foon() = 0;
}
class b : public d;
class c : public d;
void a()
{
    d* a = new b; // 切换为c时,只需要修改这一行代码。
    a->foo1();
    ...
    a->foon();
}

接口隔离原则

接口隔离是针对接口调用者做的隔离,只让调用者看到其能调用的接口,本质上是最小权限。大部分it公司都会宣讲信息安全,而为了保证信息安全的一个原则就是最小化原则。接口隔离就是为了程序安全,如果提供了超过调用者权限的接口,那可能就会引发问题。

迪米特法则

迪米特法则就是最小依赖,依赖更少的类,更少的接口,这样可以降低类之间的耦合和减少代码复杂度。如果某个类依赖了很多类,很多接口,那以后其代码就有更大的可能因为其依赖项的改动而改动,变得不稳定。

开闭原则

对扩展开放,对修改闭合。扩展可以是函数的扩展,也可以是类的扩展,这里的对修改闭合指的是对本层的修改闭合,因为对于高层来说肯定是需要修改的,比如调用新接口,使用新类的实例。之所以对修改闭合,是为了避免修改引入bug。

后话

总是遵顼这些设计原则,对自己的代码能力是有很大益处的。再者设计原则是道,设计模式是术,如果对道理解通透的话,术是可以自行推演的,可能不知不觉中你已经用了某种设计模式了,甚至创造了新的设计模式。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网