Java 设计模式(十) 单一职责原则(SRP)

单一职责原则(Single Responsibility Principle)

SRP 基本概念

单一职责原则

  • 定义:应该有且仅有一个原因引起类的变更,也就是接口或类和职责的关系是一一对应的。
  • 难点:职责的划分:
    • 在不同情景和生产环境下我们对职责的细化是不同的(职责单一的相对性)
    • 单一职责原则提出的是一个评价接口是否优良的标准,但是职责和变化原因是不可度量的,因项目而异,因环境而异(不可度量性)
  • 优势
    • 类的复杂性降低:每个类或接口都只实现单一的职责,定义明确清晰
    • 可读性提高:定义明确清晰,自然带来较高的代码可读性
    • 可维护性提高:代码可读性强,更容易理解,自然方便维护,而且职责单一所以类之间耦合度较低,所以更容易修改。
    • 拓展性更好:有新的职责需要拓展,只需要继承对应的接口实现新的实现即可。

例讲SRP

因为面向对象的编程是推崇面向接口的编程的,我们对外暴露的方法也最好是以接口的形式定义,再由具体的类进行实现,诸多的好处就不再赘述,我们下面就基于一个简单的场景进行设计,体现单一职责的好处:

场景的定义

比如Pear是一家电子产品商,它要生产pad,phone,watch等设备,但是有一些重复的功能,如果分别设计一套,很显然并不划算,那么接口定义上我们就可以根据功能划分设定单一职责的接口:

接口的定义

//可以拨打电话
interface Callable{
    void call ();
}

//可以触摸控制
interface Touchable{
    void touch();
}

//可以消息提醒
interface MessagePromptable{
    void prompt();
}

//可以接入键盘
interface KeyBoardMatchable{
    void match();
}

实现接口的类依旧单一职责

class StandardCall implements Callable{

    @Override
    public void call() {
        System.out.println("Call to somebody!");
    }
}

class StandardTouch implements Touchable{

    @Override
    public void touch() {
        System.out.println("touch to press the button!");
    }
}

class StandardPromt implements MessagePromptable{

    @Override
    public void prompt() {
        System.out.println(" someone contact to you,sir!");
    }
}

class StandardMatch implements KeyBoardMatchable{

    @Override
    public void match() {
        System.out.println("The keyBoard is ready to work!");
    }
}

产品的生产

  • 我们如果基于我们现有的技术生产一部手机,那么我们需要它能打电话触屏控制消息提醒:
//在声明这台手机时我们就明确知道了它的功能
class MyPhone implements Callable,MessagePromptable,Touchable{

    //无需重复研发已有的技术,直接装载即可
    private Callable caller = new StandardCall();
    private MessagePromptable prompter = new StandardPromt();
    private Touchable toucher = new StandardTouch();

    @Override
    public void call() {
        caller.call();
    }

    @Override
    public void prompt() {
        prompter.prompt();
    }

    @Override
    public void touch() {
        toucher.touch();
    }
}

public class SRPTest {
    public static void main ( String [] args ){
        MyPhone phone = new MyPhone();
        phone.call();
        phone.prompt();
        phone.touch();
    }
}
  • 假如我们需要出一款新的手机,但是我们只是拥有了新的呼叫技术,那么只需要在实现这项技术时继承Callable接口,然后在之前手机的Callable的具体是凶案类换成新的技术即可,只需要修改一行代码,是不是感觉棒棒的。职责的单一,对于我们对于现有类的修改造成的影响有了约束
  • 那么如果我想生产一个Pad呢,同理啊,只需要在已有技术上装载即可啊,Pad类依旧只是单一的整合技术形成产品的职责,整合成产品研发出技术的职责分离,为我们的类的拓展带来了方便
class MyPad implements Touchable,KeyBoardMatchable{

    Touchable toucher = new StandardTouch();
    KeyBoardMatchable matcher = new StandardMatch();

    @Override
    public void match() {
        toucher.touch();
    }

    @Override
    public void touch() {
        matcher.match();
    }
}

总结

通过上面额例子,可以有一个更清晰的理解,其实如果单个接口都提供一个实现类会导致类额数量很庞大,使用起来很不方便,所以我们可以整合一些功能。简而言之:

对于单一职责原则,接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化

  • 下面一个例子,我们的接口依旧单一职责,但是接听和拨打电话的功能往往是不可分的,他们会同时发生变化,所以我们可以提供一个同时继承两个接口的实现类。
class CallAndPrompt implements Callable,MessagePromptable{

    @Override
    public void call() {
        System.out.println("Hello, I have some thing to tell you!");
    }

    @Override
    public void prompt() {
        System.out.println("Hello,what do you want to tell me!");
    }
}

//在声明这台手机时我们就明确知道了它的功能
class MyPhone implements Callable,MessagePromptable,Touchable{

    //无需重复研发已有的技术,直接装载即可
    private Callable caller = new CallAndPrompt();
    //不同的接口调用同一个实现类的不同功能
    private MessagePromptable prompter = (MessagePromptable)caller;
    private Touchable toucher = new StandardTouch();

    @Override
    public void call() {
        caller.call();
    }

    @Override
    public void prompt() {
        prompter.prompt();
    }

    @Override
    public void touch() {
        toucher.touch();
    }
}

从上面的例子,可能你会更理解我的总结。但是原则这个东西要遵守,但是没必要死守。在实际的设计中还是要学会变通。毕竟经典的设计模式也不总是遵守这些设计原则,但他们依旧被广泛地应用到实际当中,而且表现还不错

时间: 2024-10-10 23:13:03

Java 设计模式(十) 单一职责原则(SRP)的相关文章

[OOD] 为什么单一职责原则(SRP)是最难运用的

单一职责原则(SRP)已经几乎是每一个程序员都知道的设计原则.最早由Robert C. Martin在<<敏捷软件开发 - 原则.模式与实践>>中正式提出.书中作者在结论中提到:  SRP是所有设计原则最简单的,但也是最难运用的.(中文翻译有之一,略去了) 现实工作中,关于一个类是否符合SRP,或者是否有必要符合SRP的讨论是经常发生的.争论的关键在于职责的定义,但我理解SRP真正的核心是关注于变化.这并不是我的新见解,全是来自Martin大叔的解释: 首先职责的定义是: 引起变化

设计模式(3)-----单一职责原则

单一职责原则(SRP) 定义 就一个类而言,应该仅有一个引起它变化的原因.一个类,只有一个引起它变化的原因.应该只有一个职责.每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其它的职责.另外,多个职责耦合在一起,会影响复用性.例如:要实现逻辑和界面的分离. 例子 例如在做一个根据参数对用户表进行查询再显示出来的功能,把这些东西写在一个类里面是非常不好的.如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个

《大话设计模式》——单一职责原则

单一职责原则(SRP):就一个类而言,应该仅有一个能引起它变化的原因. 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或抑制这个类完成其他职责的能力.这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏. 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离. 如果能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.就应该考虑类的职责分离.

学习大话设计模式03_单一职责原则

单一职责原则:一个类,应仅有一个引起它变化的原因 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力.这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏. 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分享.如果你能够想到多于一个的动机去改变一个类,那么这个类就是具有多于一个的职责 学习大话设计模式03_单一职责原则

设计模式之单一职责原则(SRP)

自己之前写过一些关于设计模式的博客,但是大部分都写得比较匆忙.现在正好趁年前有时间,笔者打算好好地整理一下自己这块知识结构.开篇的第一个原则就是设计原则里面最简单的一个原则--单一职责原则. 想必大家都听过并且常用这个原则进行一些项目的重构,因为这个原则太简单了,一句话概括就是:应该有且仅有一个原因引起类的变更.但是我们在实际的项目里面不能够生搬硬套,因为单一职责原则有个缺点就是可能会造成类对象的剧增,导致我们在用的时候就需要人为的组合对象.大家应该知道组合操作就会造成冗余.耦合,所以可以视具体

架构师之路——单一职责原则SRP (我单纯,我快乐)

定义: 不要存在多于一个导致类变更的原因.通俗地讲,一个类只做一件事情. 单一职责原则的好处: 1.类的复杂性降低,实现什么职责都有清晰明确的定义: 2.可读性提高,复杂性降低,那当然可读性提高了: 3.可维护性提高,可读性提高,那当然更容易维护了: 4.变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性.维护性都有非常大的帮助. 建议: 接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化 SRP好处

大话设计模式笔记 单一职责原则 开放-封闭原则

单一职责原则(SRP),就一个类而言,应该仅有一个引起它的变化原因. 个人认为这个原则过于理想化,仅有一个并不是绝对的,合理就好. 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离[ASD] 如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责. MVC,可以说良好运用了这个原则,但有时候一些小项目,可直接在service执行SQL语句,也是可以的. 开放-封闭原则,说是软件实体(类.模块.函数等等)应该可以扩张,但是不可修改. 对于扩张是开放的(Open for

敏捷开发:原则,模式与实践——第8章 单一职责原则SRP

鲍勃大叔说: 单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因. 我最开始理解成只能有一个原因去改变,跟我以前的认知有问题,从我开始学OOP以来,我觉得一个类就是一个事物的抽象,比如书,BOOK类,如果按照我理解的意思,book类就有很多可以改变它的原因,例如翻书或者买书,我感觉SRP说的是函数的职责,不是类的职责,于是我就去找了一个同学讨论,然后我们讨论了一会,得出的结论是这样的(以保龄球为例): SRP指的是只改变保龄球相关的内容算一件事,如果我用一个比赛类去代替保龄球的话

2单一职责原则SRP

一.什么是单一职责原则 单一职责原则(Single Responsibility Principle ): 就一个类而言,应该仅有一个引起它变化的 原因. 二.多功能的山寨手机 山寨手机的功能: 拍照.摄像.手机游戏.网络摄像头.GPS.炒股 等等. 功能多.但是每一个功能都不强. 拍摄功能 ------>专业摄像机或照相机 手机游戏 ------>PSP 网络摄像头---->专业摄像头 GPS功能------>专业GPS导航系统 三.烦人的山寨手机 每一个职责都是一个变化的轴线,