单一职责原则是说一个类只有一个发生变更的原因,这个是在类层之上的,那在接口层次,方法层次,也要遵循单一原则,那我们现在结合一些例子来说明一下,那单一职责的好处呢,首先降低类的复杂性,提高可读性,提高维护性,最重要的是变更的时候风险率降低,那我们现在结合例子一起来体会一下,单一职责原则,首先呢我们现在有一个类

这个类图还是非常非常简单的,其实是由Test创建这两个类,这个Bird类现在已经不用了,那职责在类的层次上,还是比较清晰的,那刚刚说的是类的职责上,那我们再看一下在接口级别上,还是用我们的课程举例,ICourse是一个接口

package com.learn.design.principle.singleresponsibility;/*** 鸟主要的移动方式我们来学一下* * @author Leon.Sun**/
public class Bird {/*** 主要是用翅膀飞* 这里面我们增加一个birdName* 鸟的名称* * * @param birdName*/public void mainMoveMode(String birdName){/*** 这里要做一个判断* 这个就非常符合我们的日常开发* 一个需求来说* 我们在这里做一个修改* 其实是最快的方式* 我们在实际开发中还要考虑开发的成本* 时间,进度* 完全遵守单一原则* 有的时候还是要看实际情况的* 但是我们有一颗按照原则写代码的心* 条件允许的情况下* 还是要大家来遵守这些设计原则* 那需求现在增加了鸵鸟* 那我们在原有的类加一个判断* * */if("鸵鸟".equals(birdName)){/*** 如果是鸵鸟的话* 用脚走* 鸵鸟用脚走* * 这里面有bug了* System.out.println(birdName+"用翅膀飞");* 下一行又走到了这里* 这里就是一个典型的一个例子* 那我们在扩展的时候* 对于一些边界* 我们这里增加了if* 但是下边并没有放到else里* 这种情况也比较常见* 正确的写法应该是这样的* 如果继续扩展下来* 包括企鹅* 企鹅也是鸟* 企鹅也是用脚走* 那鸵鸟跟企鹅呢* 我们还可以细分一下* 那如果现在再传来一些特殊的鸟类* 那我们的这个方法还要继续扩展* 还记得我们说的* 单一职责原则其中有一个最重要的好处* 他就是变更时风险率降低* 那现在是不遵循单一原则的* 所以风险还是比较大* 当然我们看到的这个方法还比较简单* 那实际的业务比这个复杂* 边界比这个判断要 更多一些* 那我们现在从类的形式来把这个拆分开* */System.out.println(birdName+"用脚走");}else{System.out.println(birdName+"用翅膀飞");}}
}
package com.learn.design.principle.singleresponsibility;/*** 我们 创建一个类FlyBird* * * @author Leon.Sun**/
public class FlyBird {public void mainMoveMode(String birdName){System.out.println(birdName+"用翅膀飞");}
}
package com.learn.design.principle.singleresponsibility;/*** 我们再创建一个类WalkBird* 走路的鸟* * * @author Leon.Sun**/
public class WalkBird {public void mainMoveMode(String birdName){System.out.println(birdName+"用脚走");}
}
package com.learn.design.principle.singleresponsibility;/*** 我们写一个测试类* * * @author Leon.Sun**/
public class Test {public static void main(String[] args) {/*** new一个bird* 我们传进去一个大雁* 大雁用翅膀飞* 我现在再传一个鸵鸟* 那鸵鸟用翅膀飞* 就不对* 因为鸵鸟飞不起来* 那我们再看一下这个类* * 可以看到大雁没有问题* 用翅膀飞* 那鸵鸟用脚走* 鸵鸟用翅膀飞* * */
//        Bird bird = new Bird();
//        bird.mainMoveMode("大雁");
//        bird.mainMoveMode("鸵鸟");/*** 那我们飞的鸟和走的鸟都区分一下* 这块还是比较简单的* 我们应用层来判断这个逻辑* 如果是大雁* 我们就用FlyBird* 如果是鸵鸟我们就用行走的Bird* 那这个就是类的单一原则的体现* 我们把一个类进行拆分* 这样我们就使每个类的方法职责单一的* 比较简单* 也不至于引入的时候出现新的问题* 那我们来看一下类图* * */FlyBird flyBird = new FlyBird();flyBird.mainMoveMode("大雁");WalkBird walkBird = new WalkBird();walkBird.mainMoveMode("鸵鸟");}
}

课程类实现两个接口,我们可以通过实现一个接口或者多个接口,来组合出这个实现类的一个实现,但是我也可以实现一个接口,也就是我们这个实现类实现什么职责呢,都是有清楚明确的定义,复杂性也是降低了,复杂性降低了可读性也就提高了,可读性提高了也就更容易维护了,可读性也就提高了,同时变更引起的影响降低了,一个接口的更改只对相应的实现类有影响,与其他的接口无关,这一点对项目的帮助是非常大的,这个就是从接口级别上来讲,单一职责,刚刚类,接口,我们再来看看单一职责
package com.learn.design.principle.singleresponsibility;/*** 这个是一个接口* 我们来看一下这个接口* 对于课程来说* 获得课程的名字* 获得课程的视频* 那在接口的基础上做单一原则的话* 也就是ICourse这个接口* 可不只有一个职责* 首先一个大的职责是获得课程的信息* 比如名称和视频字节流* 另外一个职责是管理课程* 和课程内容无关* 例如学习课程* 那如果学习课程需要获取name* 视频字节流* 如果退了这个课程呢* 可能就获取不了这个名字和字节流了* 因为这个课程已经被我退掉了* 那退会影响获取内容的变化* 这两个职责是互相影响的* 现在我们退了这个课程* 那获取课程信息的时候* 我们这个实现就获取不到* 就可以了* 那整体来看* 这个接口两个职责* 获取课程相关信息* 还有课程管理上的相关处理* 那我们就可以把这个接口拆成两个接口* 一个是获取课程信息的接口* 另外是课程管理的接口* 我们来尝试一下* * * @author Leon.Sun**/
public interface ICourse {/*** 我是可以获得课程的名称的* * * @return*/String getCourseName();/*** 我还可以获得一个视频* 拿到一个字节流* * @return*/byte[] getCourseVideo();/*** 学习课程* */void studyCourse();/*** 退款* */void refundCourse();}
package com.learn.design.principle.singleresponsibility;public interface ICourseManager {/*** 然后把这个拿到这边* */void studyCourse();void refundCourse();
}
package com.learn.design.principle.singleresponsibility;/*** 注意这个关键字是interface* * @author Leon.Sun**/
public interface ICourseContent {/*** 我们把这两个拿到这里边* * @return*/String getCourseName();byte[] getCourseVideo();
}
package com.learn.design.principle.singleresponsibility;/*** 我们现在来实现一个Course的实现类* 他来实现ICourseManager这个接口* 同时来实现ICourseContent这个接口* CourseImpl实现类实现这两个接口* 我们来看一下类图* * * @author Leon.Sun**/
public class CourseImpl implements ICourseManager,ICourseContent {@Overridepublic void studyCourse() {}@Overridepublic void refundCourse() {}@Overridepublic String getCourseName() {return null;}@Overridepublic byte[] getCourseVideo() {return new byte[0];}
}
package com.learn.design.principle.singleresponsibility;/*** 那我们简单的总结一下* 类的单一职责原则和接口方法的单一职责是一样的* 但是我们在实际的项目开发中* 我们在创建类的时候* 包括依赖组合聚合* 受很多因素的影响* 包括我们项目的规模* 还有项目的周期* 技术人员的水平* 还有对进度的把控* 这个都是一个平衡的因素* 那另外有一个考虑* 也就是我们在扩展的时候* 如果我们没有面向接口的编程* 而又非常遵循单一职责原则* 可能引起类的一个爆炸* 类的数量会比较多* 所以我们在总结起来* 就是说在实际的开发中* 我们的接口和方法* 一定要做到单一职责* 这个其实还是蛮好的* 对于我们维护起来也会比较方便* 而且成本也非常低* * * @author Leon.Sun**/
public class Method {/*** 我们现在有一个方法叫updateUserInfo* 这里面可以更新用户名称* 还可以更新地址* 其实这个方法就是同时更新userName和地址* * * @param userName* @param address*/private void updateUserInfo(String userName,String address){/*** 这里是一个伪代码* 大家认为是一个更新的过程就可以了* * */userName = "geely";address = "beijing";}/*** 如果我们还有一种写法* 如果是一个可变长度的参数* 还有其他的properties* 其他的属性* 那这个方法的职责就更多了* 不一定更新什么* 这里是一个可变长的参数* 可变长的参数肯定是放在方法最后一个位置* 声明才可以* 这里面可能包括各种信息* 例如说他的体重* 那这个方法从命名上* 包括里面的实现上* 职责就不是单一的* * * @param userName* @param properties*/private void updateUserInfo(String userName,String... properties){userName = "geely";
//        address = "beijing";}/*** 那更好的方式应该是这样的* 大家可以理解他的一个变化* 只更新名字* 这个就叫做updateUsername* 需要更新name的话* 就调用这个方法* 这两个方法的职责是非常的单一且清晰的* 那我们在写方法的时候* 经常还会碰到这个场景* * * @param userName*/private void updateUsername(String userName){userName = "geely";}/*** 这个就叫做updateUserAddress* 我们把之前的那个方法拆分成两个方法* 如果我们需要更新地址的话* 那就调用这个方法* * * @param address*/private void updateUserAddress(String address){address = "beijing";}/*** 后面多了一个布尔* 这个方法里面传了一个布尔类型* 这就有意思了* 我们看一下* * * @param userName* @param address* @param bool*/private void updateUserInfo(String userName,String address,boolean bool){/*** 我们一般会这么写* 也就是布尔类型要么true要么false* 其实这个方法的职责要么todo something1* 还有todo something2* 那这种情况我们就应该把这个方法拆开* 因为这个方法很明显的就是两个职责* 如果你传进来的布尔你没有使用* 如果使用的就拆开* 有布尔的存在这个方法就不会有单一的职责* 这样开发起来简单* 维护起来也容易* * */if(bool){//todo something1}else{//todo something2}userName = "geely";address = "beijing";}}

单一职责原理讲解coding相关推荐

  1. 接口隔离原则原理讲解-coding

    我们先看一下他的定义,用多个专门的接口,而不使用单一的子接口,客户端不应该依赖他不需要使用的接口,那这个定义也比较好理解,在我们后面一起coding的时候也会很容易的理解他,我们接下来看一些需要注意的 ...

  2. 软件架构设计原则-开闭、依赖倒置、单一职责、接口隔离、迪米特、里氏替换、合成复用,附Java语言示例讲解

    场景 1.开闭原则(Open-Closed Principle,OCP) 是指一个软件实体(如类.模块和函数)应该对外扩展开放,对修改关闭.所谓的关闭,也正是对扩展和修改两个行为的一个原则. 它强调的 ...

  3. 【软件架构设计原则】单一职责原则和接口隔离原则

    文章目录 软件架构设计原则 单一职责原则 接口隔离原则 其他设计原则 软件架构设计原则 本文通过实例来讲解 单一职责原则 接口隔离原则 单一职责原则 单一职责(Simple Responsibilit ...

  4. 设计模式原则--单一职责原则

    单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因 场景: 一个公司有3类员工,分别是 主管,程序员,销售 代码: using System; using System.Coll ...

  5. pureMVC简单示例及其原理讲解四(Controller层)

    本节将讲述pureMVC示例中的Controller层. Controller层有以下文件组成: AddUserCommand.as DeleteUserCommand.as ModelPrepCom ...

  6. AMCL算法原理讲解

    ROS进阶教程(二)AMCL算法原理讲解 AMCL算法理解 蒙特卡洛定位算法 蒙特卡洛定位算法自适应变种 里程计运动模型 测距仪模型 波束模型 似然域模型 AMCL算法理解 AMCL(adaptive ...

  7. 经典设计原则:单一职责原则(SRP)

    本文详解设计原则中的单一职责原则,目的还是提高代码的可读性.可扩展性.复用性.可维护性等. 目录 1. 单一职责原则(SRP) 2. 如何理解单一职责原则? 3. 如何判断类的职责是否足够单一? 4. ...

  8. 设计模式-02.经典设计原则-第一节-单一职责原则,开闭原则,里式替换,接口隔离【万字长文系列】

    文章目录 设计模式经典设计原则-第一节 单一职责原则(SRP) 如何理解单一职责原则? 如何判断类的职责是否足够单一? 类的职责是否设计得越单一越好? 开闭原则(OCP) 如何理解"对扩展开 ...

  9. SOLID原则-单一职责原则

    简介 本文我们将讨论面向对象编程中著名的 SOLID 原则之一的单一职责原则.我们将深入讲解什么是单一职责原则和在设计代码时如何实现它,最后将如何避免滥用此设计规则.单一职责的英文表达为 Single ...

最新文章

  1. 从头认识Spring-2.3 注解装配-@autowired(5)-限定器@Qualifier(1)
  2. greenplum客户端工具_如何从Teradata迁移到Greenplum(上篇)
  3. SAP UI5 Simple form rendering
  4. php基础教程 第四步 学习运算符
  5. 【转】Unity3D研究院之设置自动旋转屏幕默认旋转方向
  6. TCP三次握手建立连接和四次挥手关闭连接
  7. 模拟java_【最强Java面试题系列】消息队列面试场景 “模拟”
  8. homelede软路由设置方法_小米路由器3 5G WiFi设置方法
  9. 美国公布自动驾驶新政AV4.0;微软Access数据库出现漏洞,或致8.5万家企业面临风险;苹果谈论隐私问题……...
  10. retrofit 解析百度地图api 返回数据_基于百度地图API的城市数据采集方式
  11. 计算机专业职业理想作文400字,我的理想作文400字(精选4篇)
  12. iOS项目添加pch文件
  13. 14.嵌入式控制器EC实战 SMBus读取电池信息并控制充放电
  14. python黑科技:让你无所遁形,附源码!
  15. JDK8之ConcurrentHashMap源码解读
  16. 树莓派是网盘?nextcloud在树莓派上的应用
  17. 用C语言做一个迷宫小游戏
  18. 一个Callable接口能有多少知识点?在裁员的大背景下,我仍然吊打了大厂面试官
  19. 如何为戴尔灵越15 5559加装内存条和固态硬盘
  20. python教程104-Python通过邮箱群发工资条

热门文章

  1. OSI七层-相关协议
  2. [从架构到设计]第二回:对象的旅行---对象和人,两个世界,一样情怀(转载)...
  3. [转] Transformer图解
  4. 产品经理与交互设计师的区别是什么?
  5. 数据可视化:浅谈热力图如何在前端实现
  6. AESNI/XData勒索病毒来袭 目前主要在乌克兰传播 它居然还能使用硬件加速加密过程...
  7. 福建物联网产业发展势头良好
  8. 以对象的形式动态获取宽高
  9. 架构设计:生产者/消费者模式 第3页:队列缓冲区
  10. hive 函数 Cube