当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 设计模式的七大原则(1) --单一职责原则

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

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

前言

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

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

我们踩过的坑,历代前辈们也踩过。可想而知,通他们多年的踩坑填坑经验后,所总结出来的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应该尽量的少用,要不耦合会非常严重,去看看优秀源码也是如此。可以思考思考使用单一职责原则,用类来划分多分支。

总结

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

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

相关文章:

验证码:
移动技术网