Java設(shè)計模式之單一職責(zé)原則精解
1.什么是單一職責(zé)原則?
首先我們可以對某個類來說,即一個類應(yīng)該只負責(zé)一項職責(zé)。如類A負責(zé)兩個不同職責(zé): 職責(zé)1,職責(zé)2。當(dāng)職責(zé)1需求變更而改變A時,可能造成職責(zé)2執(zhí)行錯誤,所以需要將類A的粒度分解為A1,A2。
我們來看下面這段代碼:??????
package com.szh.principle.singleresponsibility; /** * 交通工具類 * 方式1 * 1. 在方式1的run方法中,違反了單一職責(zé)原則 * 2. 解決的方案非常的簡單,根據(jù)交通工具運行方法不同,分解成不同類即可 */ class Vehicle { public void run(String vehicle) { System.out.println(vehicle + " 在公路上運行...."); } } public class SingleResponsibility1 { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.run("摩托車"); vehicle.run("汽車"); vehicle.run("飛機"); vehicle.run("輪船"); } }
乍一看沒什么問題吧,但是我們運行之后,看到的結(jié)果似乎就不太合乎思維邏輯了。摩托車、汽車在公路上運行肯定沒問題,但是飛機和輪船呢???(你是故意找茬是不是?)
2.改進代碼一
對于上面代碼案例中的問題,想必大家也都看出來了,Vehicle這個類負責(zé)的職責(zé)太多了,它既要管摩托車、汽車這種在公路上跑的,還要去管飛機這種在天上飛的,這就使得Vehicle這個類粒度太粗了,后期如果做出對公路方法的修改時,可能還會影響到其他的業(yè)務(wù)功能。
所以我們考慮將Vehicle這個類進行分解,分解為多個類,各干各的、各司其職。
package com.szh.principle.singleresponsibility; /** * 方案2的分析 * 1. 遵守單一職責(zé)原則 * 2. 但是這樣做的改動很大,即將類分解,同時修改客戶端 * 3. 改進:直接修改Vehicle 類,改動的代碼會比較少=>方案3 */ class RoadVehicle { public void run(String vehicle) { System.out.println(vehicle + "在公路運行"); } } class AirVehicle { public void run(String vehicle) { System.out.println(vehicle + "在天空運行"); } } class WaterVehicle { public void run(String vehicle) { System.out.println(vehicle + "在水中運行"); } } public class SingleResponsibility2 { public static void main(String[] args) { RoadVehicle roadVehicle = new RoadVehicle(); roadVehicle.run("摩托車"); roadVehicle.run("汽車"); AirVehicle airVehicle = new AirVehicle(); airVehicle.run("飛機"); WaterVehicle waterVehicle = new WaterVehicle(); waterVehicle.run("輪船"); } }
此時,我們將Vehicle拆解成了三個不同的類,再次運行。這樣看起來就正常了吧。
不過也有人說,這樣的改動比較大,也即直接在類的層面上做了修改,我們能不能不改動這個類,而是對它的方法做修改呢?答案是可以的。
3.改進代碼二
package com.szh.principle.singleresponsibility; /** * 方式3的分析 * 1. 這種修改方法沒有對原來的類做大的修改,只是增加方法 * 2. 這里雖然沒有在類這個級別上遵守單一職責(zé)原則,但是在方法級別上,仍然是遵守單一職責(zé) */ class Vehicle2 { public void runRoad(String vehicle) { System.out.println(vehicle + " 在公路上運行...."); } public void runAir(String vehicle) { System.out.println(vehicle + " 在天空上運行...."); } public void runWater(String vehicle) { System.out.println(vehicle + " 在水中行...."); } } public class SingleResponsibility3 { public static void main(String[] args) { Vehicle2 vehicle2 = new Vehicle2(); vehicle2.runRoad("汽車"); vehicle2.runAir("飛機"); vehicle2.runWater("輪船"); } }
此時我們并未將類進行拆解,而是將之前的run方法進行了拆解,雖然這樣的代碼沒有在類的層面上遵守單一職責(zé)原則,但是它卻在方法層面上遵守了單一職責(zé)原則,同樣可以做到正確的結(jié)果。
4.單一職責(zé)原則總結(jié)
- 降低類的復(fù)雜度,一個類只負責(zé)一項職責(zé)。
- 提高類的可讀性、可維護性。
- 降低代碼變更引起的風(fēng)險。
- 通常情況下,我們應(yīng)當(dāng)遵守單一職責(zé)原則。只有邏輯足夠簡單的情況下,才可以在代碼級違反單一職責(zé)原則;而只有類中方法數(shù)量足夠少的時候,才會建議在方法級別保持單一職責(zé)原則。
到此這篇關(guān)于Java設(shè)計模式之單一職責(zé)原則精解的文章就介紹到這了,更多相關(guān)Java 單一職責(zé)原則內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot FailureAnalyzer實例使用教程
FailureAnalyzer是一種在啟動時攔截exception并將其轉(zhuǎn)換為human-readable消息的好方法,包含在故障分析中。SpringBoot為application context相關(guān)的exceptions,JSR-303驗證等提供了這樣的分析器,實際上很容易創(chuàng)建自己的2022-12-12Java HttpClient實現(xiàn)socks代理的示例代碼
這篇文章主要介紹了Java HttpClient 實現(xiàn) socks 代理的示例代碼,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-11-11Java算法之BFS,DFS,動態(tài)規(guī)劃和貪心算法的實現(xiàn)
廣度優(yōu)先搜索(BFS)和深度優(yōu)先搜索(DFS)是圖遍歷算法中最常見的兩種算法,主要用于解決搜索和遍歷問題。動態(tài)規(guī)劃和貪心算法則用來解決優(yōu)化問題。本文就來看看這些算法的具體實現(xiàn)吧2023-04-04Java設(shè)計模式之原型模式(Prototype模式)介紹
這篇文章主要介紹了Java設(shè)計模式之原型模式(Prototype模式)介紹,本文講解了如何使用原型模式并給出了代碼實例,需要的朋友可以參考下2015-03-03深入理解Java SpringCloud Ribbon 負載均衡
Ribbon是一個客戶端負載均衡器,它提供了對HTTP和TCP客戶端的行為的大量控制。這篇文章主要介紹了SpringCloud Ribbon 負載均衡的實現(xiàn),感興趣的小伙伴們可以參考一下2021-09-09如何使用RequestHeaders添加自定義參數(shù)
這篇文章主要介紹了使用RequestHeaders添加自定義參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。2022-02-02