设计模式的七大原则(1) --单一职责原则

前言

最近工作中备受打击,之前设计的很多程序都被老大否决,需要重构,让我好好看看设计模式。之前对这一块内容的确不怎么重视,感觉枯燥无聊又派不上用场。后来沉下心来研究了一番...

我靠,原来如此,之前写代码的时候怎么这么傻逼,很多问题其实在一开始设计的时候就能避免。之前写的都是些什么鬼。

我们踩过的坑,历代前辈们也踩过。可想而知,通他们多年的踩坑填坑经验后,所总结出来的23种设计模式是多么的宝贵,就是我们的“ONE PIECE” 啊。如果掌握了这个内容,对今后无论是工作中还是面试都非常重要。因此下定决心,一定要熟练掌握这块内容。记录学习过程,供自己复习也供大家一起学习。

为什么要学习设计模式的目的

在前言中我们已经大致说明,我们总结一下,一个良好的程序应该满足一下六点要求:

1. 可复用性:尽量能重用方法,比如说提取某种工具类。
2. 可读性:编程具备规范性,阅读起来不困难。
3. 可扩展性:当你写好的程序需要添加一个新功能的时候,不能说:不行!非要添加的话我要重构代码。
4. 稳定性:尽可能少的bug。
5. 高内聚:每个模块尽可能独立完成自己的功能,不依赖于模块外部的代码。
6. 低耦合:并且模块之间联系越复杂耦合度越低,就不会牵一发而动全身。否则模块A的bug甚至会导致模块B无法运行

这是多代前辈们总结出来的编程经验,如果我们的程序没有以上特点,就会出现很多BUG。我们要站在巨人的肩膀上。尽量多学习多总结,避免犯“古人”们常犯的错误。

设计模式的作用就出来了,设计模式的目的就是为了让我们的程序具备以上六点特性。

设计模式常用的七大原则

在学习设计模式之前,为了不让设计模式显得很模式,我们还必须了解一个东西,那就是程序设计七大原则(很多地方说的是六大原则,但还有一个合成复用原则也值得提出来)。

这些原则是指导模式的规则,我会给一些原则附上一个例子,来说明这个原则所要表达的意思,注意,原则是死的,人是活的,所以并不是要你完完全全遵守这些规则,否则为何数据库会有逆范式,只是在可能的情况下,请尽量遵守。

七大原则分别是:

1. 单一职责原则(Single Responsibility Principle)
2. 接口隔离原则(Interface Segregation Principle)
3. 依赖倒置原则(Dependence Inversion Principle)
4. 里氏替换原则(Liskov Substitution Principle)
5. 开闭原则(Open Close Principle)
6. 迪米特法则(Law Of Demeter)
7. 合成复用原则(Composite/Aggregate Reuse Principle CARP)

单一职责原则

看名字就能知道,我们设计的类要尽可能的只负责一项职责。比说说A类只负责A功能,B类只负责B功能,不要A类既负责A功能又负责B功能。

为什么要这样设计?

当A功能需要更新,那么就得去修改A类。如果此时A还负责B功能,就很有可能修出BUG后导致B功能的正常使用。或者说,想实现B功能却调用的A功能的接口,这样会导致程序运行混乱。总结以下几点:

1. 降低类的复杂度,一个类只负责一项职责。
2. 提高类的可读性,可维护性。
3. 降低变更引起的风险。
4. 通常情况下,我们应当遵守单一职责原则,只要逻辑足够简单,才可以在代码级别违反单一职责原则:也就是说类中的方法数量足够少,可以在方法级别保持单一职责原则。下述代码将会说明。

例如以下代码:

public class SingleResponsibility1 {
    public static void main(String args[]) throws IOException {
        Computer computer = new Computer();
        computer.add();
    }

}
//读取配置文件和计算
class Computer{
    public int add() throws NumberFormatException, IOException {
        File file = new File("D:/data.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));
        int a = Integer.valueOf(br.readLine());
        int b = Integer.valueOf(br.readLine());
        return a+b;
    }
}

在这个Computer类中有一个add方法,负责读取配置文件数字,然后再进行相加。

这个类很明显违反了单一职责原则,一个类既负责了读取文件,又负责算数。大家考虑一下这样设计有没有什么问题?

问题诸多,提高代码可维护性,报错不好定位,功能耦合。。。

来看看更新后的代码是什么样子的:

public class SingleResponsibility2 {
    public static void main(String args[]) throws IOException {
        readFile readFile = new readFile();
        readFile.read("D:/data.txt");
        Computer2 computer = new Computer2();
        computer.add(readFile.getA(),readFile.getB());
    }

}
//计算
class Computer2 {
    public int add(int a, int b){
        return a + b;
    }
}
//读取配置文件
class readFile {
    private int a;
    private int b;

    public void read(String path) throws IOException {
        File file = new File(path);
        BufferedReader br = new BufferedReader(new FileReader(file));
        a = Integer.valueOf(br.readLine());
        b = Integer.valueOf(br.readLine());
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}

通过这样修改代码,我们实现了单一职责原则。

这样就万无一失了吗?

当然有时候也不见得,因为如果我们的代码足够简单,这样设计会提供编写代码的成本。并且同时还要修改客户端代码。

我们再来看看下面的代码:

public class SingleResponsibility3 {
    public static void main(String args[]) throws IOException {
        Computer3 computer = new Computer3();
        computer.read("D:/data.txt");
        computer.add(computer.getA(),computer.getB());
    }

}
//负责读取配置文件,并且负责计算
class Computer3 {
    private int a;
    private int b;

    public void read(String path) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(path));
        a = Integer.valueOf(br.readLine());
        b = Integer.valueOf(br.readLine());
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    public int add(int a, int b){
        return a + b;
    }
}

当然这个只是示例代码,在真正的开发环境也不可能这样用。我举这个例子只是想说明如果一个类的方法很少功能逻辑比较简单。如我们写的Computer类,只负责读取两个数,然后相加。

这样简单的类其实就可以在代码级别违反单一职责原则:也就是说类中的方法数量足够少,可以在方法级别保持单一职责原则。

还是那句话:人是活的,原则是死的。

一个优秀的代码if else应该尽量的少用,要不耦合会非常严重,去看看优秀源码也是如此。可以思考思考使用单一职责原则,用类来划分多分支。

总结

今天就到这里,一个一个慢慢吃透,一天进步一点。下一篇我们来看接口隔离原则。

(0)

相关推荐

  • 设计模式(Design Patterns)的简单讲解

    模式的诞生与定义 模式(Pattern)起源于建筑业而非软件业(小本本记下来--) 模式之父--美国加利佛尼亚大学环境结构中心研究所所长Christopher Alexander博士; 模式 : -C ...

  • "设计模式我学过呀,就是没用过"

    回复"000"获取大量电子书 写在前面 在开发中,不使用设计模式也不是不可以,但是用好设计模式能帮忙我们更好的去解决实际问题. 其实,我们天天都在和设计模式打交道,很多人却完全不知 ...

  • 重温设计模式系列(三)面向对象设计原则

    背景 面向对象基础知识,只是给了我们一个概念,如何更好的设计出良好的面向对象代码,需要有设计原则作为支持.设计原则是核心指导思想,在这些原则的基础上,经过不断的实践,抽象,提炼逐步产生了针对特定问题的 ...

  • 23种设计模式入门 - 设计模式概述及七大原则

    设计模式的目的 使程序拥有更好的的 代码复用性(一次编译,处处运行[手动狗头]) 可读性(不可替代性堪忧呀) 可扩展性(新增功能时方便) 可靠性(新增功能后对旧功能没有影响) 高内聚,低耦合 设计模式 ...

  • [书籍精读]《JavaScript设计模式与开发实践》精读笔记分享

    写在前面 书籍介绍:本书在尊重<设计模式>原意的同时,针对JavaScript语言特性全面介绍了更适合JavaScript程序员的了16个常用的设计模式,讲解了JavaScript面向对象 ...

  • 设计模式——六大设计原则

    文章目录 一.单一职责原则 二.里式替换原则 三.依赖倒置原则 四.接口隔离原则 五.迪米特法则 六.开闭原则 一.单一职责原则 单一职责原则简称 SRP,他想表达的就是字面意思,一个类只承担一个职责 ...

  • 设计模式的七大原则(5) --开闭原则

    前言 我们已经学习了单一职责原则,依赖倒置原则,接口隔离原则,李氏替换原则.可以说前面几个原则都是为了开闭原则奠定基础. 我们写的程序由于实际的情况可以一定程度上违背各种设计原则.但是,开闭原则我认为 ...

  • 设计模式六大原则:单一职责原则

    目录: 设计模式六大原则:单一职责原则 设计模式六大原则:接口隔离原则 设计模式六大原则:依赖倒置原则 设计模式六大原则:里氏替换原则 设计模式六大原则:迪米特法则 设计模式六大原则:开闭原则 单一职 ...

  • 面向对象的六大原则之 单一职责原则——SRP

    SRP = Single Responsibility Principle   定义:就一个类而言,应该只有一个能引起他变化的原因.通俗的说,即一个类只负责一项职责.   作用: 1.减少了类之间的耦 ...

  • 六大设计原则(一)SRP单一职责原则

    单一职责原则SRP(Single reponsibility principle) BO(Business Object):业务对象 Biz(Business Logic):业务逻辑 SRP最简单的例 ...

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

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

  • 设计模式的七大原则(6) --迪米特法则

    前言 迪米特法则,听名字有点奇怪,但是这个法则真的非常非常有意思,在我看来,这个法则其实描述的就是一个矜持的小姑娘,害羞的惹人怜爱.但是啊,姑娘虽好,切不可"贪杯"哦~ 基本介绍 ...

  • 设计模式的七大原则(4) --里氏替换原则

    前言 上一节中我们介绍了,依赖倒置,依赖倒置利用抽象的稳定性来架构我们的系统,是我们经常能遇到的一种原则,比如说面向接口编程. 这一节中,我们来说说里氏替换原则,这个原则其实非常非常的简单,其实与依赖 ...

  • 设计模式的七大原则(3) --依赖倒置原则

    前言 上一节我们说了接口隔离原则,就是让接口的职责最小化.这样对维护代码简单,调用方法也清晰. 这节我们来研究依赖倒置原则.这个原则我认为是特别特别重要的.在很多地方我们能看到.比如Dubbo中使用到 ...

  • 张际才:构图的七大原则,不要违背原则去创作

    张际才:构图的七大原则,不要违背原则去创作