Java设计模式中单一职责原则(SRP)介绍

原文地址:http://blog.csdn.net/qq_24451605/article/details/51346786

单一职责原则(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();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
实现接口的类依旧单一职责
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!");
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
产品的生产
  • 我们如果基于我们现有的技术生产一部手机,那么我们需要它能打电话触屏控制消息提醒:
//在声明这台手机时我们就明确知道了它的功能
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();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 假如我们需要出一款新的手机,但是我们只是拥有了新的呼叫技术,那么只需要在实现这项技术时继承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();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

总结

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

对于单一职责原则,接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化
  • 下面一个例子,我们的接口依旧单一职责,但是接听和拨打电话的功能往往是不可分的,他们会同时发生变化,所以我们可以提供一个同时继承两个接口的实现类。
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();
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单一职责原则(Single Responsibility Principle,SRP)是面向对象设计的一个重要原则。它要求一个类或模块应该只负责完成一个职责或功能。换句话说,一个类应该只有一个引起它变化的原因。 在Java,我们可以通过以下几种方式来遵循单一职责原则: 1. 将不同的职责分离到不同的类:将一个类的多个职责拆分成多个类,每个类只负责一个职责。这样可以提高代码的可维护性和可扩展性。 2. 使用接口进行解耦:通过定义接口,将不同的职责分离开来,使得类之间的依赖关系更加松散。这样可以降低类之间的耦合度,提高代码的灵活性。 3. 使用设计模式设计模式是一种经过验证的解决特定问题的方案。在遵循单一职责原则时,可以使用一些设计模式,如策略模式、观察者模式等,来将不同的职责分离开来,使得代码更加清晰和可维护。 下面是一个示例代码,演示了如何在Java遵循单一职责原则: ```java // 负责处理用户信息的类 class UserInfoHandler { public void saveUserInfo(UserInfo userInfo) { // 保存用户信息的逻辑 } } // 负责发送邮件的类 class EmailSender { public void sendEmail(String email, String message) { // 发送邮件的逻辑 } } // 负责生成报表的类 class ReportGenerator { public void generateReport(List<Data> dataList) { // 生成报表的逻辑 } } ``` 在上面的示例,我们将处理用户信息、发送邮件和生成报表这三个不同的职责分别放在了不同的类,每个类只负责完成一个职责。这样可以使得代码更加清晰和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值