Java設(shè)計(jì)模式之單一職責(zé)原則精解
1.什么是單一職責(zé)原則?
首先我們可以對(duì)某個(gè)類(lèi)來(lái)說(shuō),即一個(gè)類(lèi)應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)。如類(lèi)A負(fù)責(zé)兩個(gè)不同職責(zé): 職責(zé)1,職責(zé)2。當(dāng)職責(zé)1需求變更而改變A時(shí),可能造成職責(zé)2執(zhí)行錯(cuò)誤,所以需要將類(lèi)A的粒度分解為A1,A2。
我們來(lái)看下面這段代碼:??????
package com.szh.principle.singleresponsibility;
/**
* 交通工具類(lèi)
* 方式1
* 1. 在方式1的run方法中,違反了單一職責(zé)原則
* 2. 解決的方案非常的簡(jiǎn)單,根據(jù)交通工具運(yùn)行方法不同,分解成不同類(lèi)即可
*/
class Vehicle {
public void run(String vehicle) {
System.out.println(vehicle + " 在公路上運(yùn)行....");
}
}
public class SingleResponsibility1 {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("摩托車(chē)");
vehicle.run("汽車(chē)");
vehicle.run("飛機(jī)");
vehicle.run("輪船");
}
}
乍一看沒(méi)什么問(wèn)題吧,但是我們運(yùn)行之后,看到的結(jié)果似乎就不太合乎思維邏輯了。摩托車(chē)、汽車(chē)在公路上運(yùn)行肯定沒(méi)問(wèn)題,但是飛機(jī)和輪船呢???(你是故意找茬是不是?)

2.改進(jìn)代碼一
對(duì)于上面代碼案例中的問(wèn)題,想必大家也都看出來(lái)了,Vehicle這個(gè)類(lèi)負(fù)責(zé)的職責(zé)太多了,它既要管摩托車(chē)、汽車(chē)這種在公路上跑的,還要去管飛機(jī)這種在天上飛的,這就使得Vehicle這個(gè)類(lèi)粒度太粗了,后期如果做出對(duì)公路方法的修改時(shí),可能還會(huì)影響到其他的業(yè)務(wù)功能。
所以我們考慮將Vehicle這個(gè)類(lèi)進(jìn)行分解,分解為多個(gè)類(lèi),各干各的、各司其職。
package com.szh.principle.singleresponsibility;
/**
* 方案2的分析
* 1. 遵守單一職責(zé)原則
* 2. 但是這樣做的改動(dòng)很大,即將類(lèi)分解,同時(shí)修改客戶(hù)端
* 3. 改進(jìn):直接修改Vehicle 類(lèi),改動(dòng)的代碼會(huì)比較少=>方案3
*/
class RoadVehicle {
public void run(String vehicle) {
System.out.println(vehicle + "在公路運(yùn)行");
}
}
class AirVehicle {
public void run(String vehicle) {
System.out.println(vehicle + "在天空運(yùn)行");
}
}
class WaterVehicle {
public void run(String vehicle) {
System.out.println(vehicle + "在水中運(yùn)行");
}
}
public class SingleResponsibility2 {
public static void main(String[] args) {
RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("摩托車(chē)");
roadVehicle.run("汽車(chē)");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("飛機(jī)");
WaterVehicle waterVehicle = new WaterVehicle();
waterVehicle.run("輪船");
}
}
此時(shí),我們將Vehicle拆解成了三個(gè)不同的類(lèi),再次運(yùn)行。這樣看起來(lái)就正常了吧。
不過(guò)也有人說(shuō),這樣的改動(dòng)比較大,也即直接在類(lèi)的層面上做了修改,我們能不能不改動(dòng)這個(gè)類(lèi),而是對(duì)它的方法做修改呢?答案是可以的。

3.改進(jìn)代碼二
package com.szh.principle.singleresponsibility;
/**
* 方式3的分析
* 1. 這種修改方法沒(méi)有對(duì)原來(lái)的類(lèi)做大的修改,只是增加方法
* 2. 這里雖然沒(méi)有在類(lèi)這個(gè)級(jí)別上遵守單一職責(zé)原則,但是在方法級(jí)別上,仍然是遵守單一職責(zé)
*/
class Vehicle2 {
public void runRoad(String vehicle) {
System.out.println(vehicle + " 在公路上運(yùn)行....");
}
public void runAir(String vehicle) {
System.out.println(vehicle + " 在天空上運(yùn)行....");
}
public void runWater(String vehicle) {
System.out.println(vehicle + " 在水中行....");
}
}
public class SingleResponsibility3 {
public static void main(String[] args) {
Vehicle2 vehicle2 = new Vehicle2();
vehicle2.runRoad("汽車(chē)");
vehicle2.runAir("飛機(jī)");
vehicle2.runWater("輪船");
}
}
此時(shí)我們并未將類(lèi)進(jìn)行拆解,而是將之前的run方法進(jìn)行了拆解,雖然這樣的代碼沒(méi)有在類(lèi)的層面上遵守單一職責(zé)原則,但是它卻在方法層面上遵守了單一職責(zé)原則,同樣可以做到正確的結(jié)果。

4.單一職責(zé)原則總結(jié)
- 降低類(lèi)的復(fù)雜度,一個(gè)類(lèi)只負(fù)責(zé)一項(xiàng)職責(zé)。
- 提高類(lèi)的可讀性、可維護(hù)性。
- 降低代碼變更引起的風(fēng)險(xiǎn)。
- 通常情況下,我們應(yīng)當(dāng)遵守單一職責(zé)原則。只有邏輯足夠簡(jiǎn)單的情況下,才可以在代碼級(jí)違反單一職責(zé)原則;而只有類(lèi)中方法數(shù)量足夠少的時(shí)候,才會(huì)建議在方法級(jí)別保持單一職責(zé)原則。
到此這篇關(guān)于Java設(shè)計(jì)模式之單一職責(zé)原則精解的文章就介紹到這了,更多相關(guān)Java 單一職責(zé)原則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot實(shí)現(xiàn)圖片上傳功能
這篇文章主要為大家詳細(xì)介紹了Spring Boot實(shí)現(xiàn)圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
gRPC在Java中的實(shí)現(xiàn)與應(yīng)用詳解
gRPC是由Google開(kāi)發(fā)的高性能、開(kāi)源的通用遠(yuǎn)程過(guò)程調(diào)用(RPC)框架,本文將詳細(xì)介紹如何在Java中使用gRPC,包括服務(wù)定義、服務(wù)器端實(shí)現(xiàn)、客戶(hù)端調(diào)用以及一些高級(jí)特性,我們將通過(guò)代碼示例來(lái)幫助理解gRPC的工作原理,需要的朋友可以參考下2024-06-06
Java GUI編程之貪吃蛇游戲簡(jiǎn)單實(shí)現(xiàn)方法【附demo源碼下載】
這篇文章主要介紹了Java GUI編程之貪吃蛇游戲簡(jiǎn)單實(shí)現(xiàn)方法,詳細(xì)分析了貪吃蛇游戲的具體實(shí)現(xiàn)步驟與相關(guān)注意事項(xiàng),并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2017-09-09
Mybatis示例講解注解開(kāi)發(fā)中的單表操作
這篇文章主要介紹了使用Mybatis對(duì)數(shù)據(jù)庫(kù)進(jìn)行單表操作的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
詳解SpringBoot優(yōu)雅編碼之Lombok加持
這篇文章主要介紹了詳解SpringBoot優(yōu)雅編碼之Lombok加持,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
Spring?Boot?MQTT?Too?many?publishes?in?progress錯(cuò)誤的解決方
本文介紹Spring?Boot?MQTT?Too?many?publishes?in?progress錯(cuò)誤的解決方案,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07
如何對(duì)Mysql數(shù)據(jù)表查詢(xún)出來(lái)的結(jié)果進(jìn)行排序
這篇文章主要介紹了如何對(duì)Mysql數(shù)據(jù)表查詢(xún)出來(lái)的結(jié)果進(jìn)行排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08

