单一职责原则----设计模式的七大原则
今天刚开始学习设计模式的七大原则,哈哈,由于下一学期要开这门课,暑假没事做从b站开始自学,进入正题~
单一职责原则,见名思义,即单一的职责,要求一个类或者一个方法实现的功能或完成的操作单一纯粹,要做什么就光做什么,不能有其它方面的操作,以造成程序代码的冗余和可读性差,遵守单一职责,可以设计出高内聚、低耦合的软件程序。
下面我们从一段程序开始看起(原谅我只会照搬,,,嘿嘿嘿,以后我尽量都会以先写原则再通过案例进行应用说明)
题目:设计一个交通工具类,可以模拟交通工具的运行状态
第一种方式
package com.gaoliwei.test;
//单一职责原则案例1
public class SingleResponsibility01 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle(); //实例化交通工具类
vehicle.run("汽车"); //调用它们的动作方法
vehicle.run("自行车");
vehicle.run("飞机");
}
}
//交通工具类
/**
* 此类为单一职责原则的模式1
* 1. 在方式一的run方法中,违反了单一职责的设计原则,飞机是无法在公路上跑的
* 2. 解决方案有很多,根据交通工具运行方式的不同,我们可以将交通工具类分解成不同的交通工具类
*/
class Vehicle{
public void run(String vehicle){ //输出交通工具类的动作
System.out.println(vehicle + "在公路上运行......");
}
}
运行结果
汽车在公路上运行......
自行车在公路上运行......
飞机在公路上运行......
等等???飞机还可以在公路上跑吗,显然是不能的,显然这个案例违反了单一职责原则,此类只能够支持在公路上运行的交通工具,因此我们可以对此类进行扩充修改进行分解,如下方案二
第二种方式
package com.gaoliwei.test;
//单一职责原则案例2,以类的方式分解不同运行方式的交通工具类
public class SingleResponsibility02 {
public static void main(String[] args) {
RoadVehicle roadVehicle = new RoadVehicle(); //实例化路上交通工具类
WaterVehicle waterVehicle = new WaterVehicle(); //实例化水中交通工具类
AirVehicle airVehicle = new AirVehicle(); //实例化天空中交通工具类
roadVehicle.run("自行车"); //调用路上交通工具的运行方法
roadVehicle.run("公交车");
waterVehicle.run("航空母舰"); //调用水上交通工具的运行方法
airVehicle.run("直升飞机"); //调用空中交通工具的运行方法
}
}
//交通工具类
/**
* 单一职责原则的模式2分析
* 1. 遵守了单一职责原则,每个类只负责一个职能
* 2. 这样做的改动花销比较大,即对类进行分解,还要修改客户端
* 3. 再进行改进,直接修改Vehicle类,改动的代码会较少
*/
class RoadVehicle{
public void run(String vehicle){ //输出交通工具类的动作
System.out.println(vehicle + "在公路上运行......");
}
}
class WaterVehicle{
public void run(String vehicle){ //输出交通工具类的动作
System.out.println(vehicle + "在水里运行......");
}
}
class AirVehicle{
public void run(String vehicle){ //输出交通工具类的动作
System.out.println(vehicle + "在天空中运行......");
}
}
运行结果
自行车在公路上运行......
公交车在公路上运行......
航空母舰在水里运行......
直升飞机在天空中运行......
这下好了,第二种方式很好地实现了单一职责设计模式,通过分解为三个不同交通方式的类完成,但还有一点欠缺的是,这样写是不是太复杂了啊,这些类的功能方法太单纯,改动花销太大还要修改客户端等操作。我们可以对这种方式再进行改进,如方案三
第三种方式
package com.gaoliwei.test;
//单一职责原则案例3,为原始交通类添加不同的方法,使其完成各自独立的功能
public class SingleResponsibility03 {
public static void main(String[] args) {
Vehicle02 vehicle02 = new Vehicle02(); //实例化再次改进后的交通工具类
vehicle02.roadRun("时风三轮车"); //调用路上交通工具的运行方法
vehicle02.roadRun("爱玛电动车");
vehicle02.waterRun("小皮艇"); //调用水中交通工具的运行方法
vehicle02.airRun("热气球"); //调用天空中交通工具的运行方法
}
}
/**
* 单一职责原则的模式3分析
* 1. 此种方式在原来的类中并无做大的修改,只是增加了些不同的方法
* 2. 此处虽然木有在类的级别上保持单一职责原则,但是在方法级别上遵守了单一设计原则
*/
class Vehicle02{
public void roadRun(String vehicle){ //输出公路上的动作
System.out.println(vehicle + "在公路上运行......");
}
public void waterRun(String vehicle){ //输出水中方式的动作
System.out.println(vehicle + "在水上运行......");
}
public void airRun(String vehicle){ //输出天空方式的动作
System.out.println(vehicle + "在天空中运行......");
}
}
运行结果
时风三轮车在公路上运行......
爱玛电动车在公路上运行......
小皮艇在水上运行......
热气球在天空中运行......
此时只是在原来的类中增加了些不同交通工具运行的方法,虽然木有在类的级别上保持单一职责原则,但是在方法级别上遵守了单一设计原则,每个方法完成不同模式的交通工具类的运行方式,因此我们采用第三种案例。
我自己的想法
小伙伴们,仔细思考思考,我们能否采用方法的重载方式完成单一职责的设计呢?就是定义多个重名run()方法,通过传递不同的类实例进行不同的运行方式呢,如
- void run(路上交通工具类 路上交通工具实例){输出路上运行方法}
- void run(水中交通工具类 水中交通工具实例){输出水中运行方法}
- void run(空中交通工具类 空中交通工具实例){输出空中运行方法}
是不是也挺好呢,哈哈哈,原谅我献一个丑,其实在System.out.println()就可以根据接收不同的参数完成不同的输出啊,看来编程不缺少单一职责设计,只是缺少发现的眼睛~哈哈
总结
单一职责原则可以降低类的复杂度,即一个类只负责一项的职责,可以提高类的可读性,可维护性,降低变更引起的风险,通常情况下,我们该遵守单一职责原则,只有逻辑足够简单时,才可以在代码级别违反单一职责原则;只有类的方法足够少时,可以在方法级别保持单一职责原则。
嘿嘿,上面的一段话并非原创,从b站尚硅谷韩老师视频出摘抄,能学习就成,对设计模式有兴趣的伙伴们也可以学习哦!共同进步~