solid设计原则_SOLID设计原则
solid設計原則
介紹:
Robert C. Martin定義了五項面向對象的設計原則:
- 小號英格爾-責任原則
- ?筆封閉原則
- 大號 iskov的替換原則
- 我覆蓋整個院落分離原則,并
- d ependency倒置原則
這些一起被普遍稱為SOLID原則。 在設計面向對象的系統時,我們應盡可能遵循這些原則。 這些原則有助于我們設計一個更可擴展,可理解和可維護的系統。
隨著應用程序規模的擴大,使用這些原則可以幫助我們節省很多工作。
單一責任原則:
顧名思義,“單一責任原則”(SRP)指出, 每個類都必須恰好要做一件事。 換句話說,我們修改類的原因不應多于一個。
眾所周知,大型系統通常具有數千個類。 如果對于任何新要求,需要涉及多個類,那么我們就有更多的機會通過破壞另一種功能來引入錯誤。
單一責任原則為我們帶來以下好處:
- 更少的耦合:由于每個類都只會做一件事,因此依賴性將大大減少
- 易于測試:更少的測試用例可以覆蓋整個系統,從而使代碼更易于測試
我們系統的模型類通常始終遵循SRP原則。 可以這么說,我們需要修改系統中用戶的狀態,我們只需觸摸User類:
public class User { ?private int id; private String name; private List<Address> addresses; ????//constructors, getters, setters }因此,它遵循SRP原則。
開閉原理:
開放式封閉原則指出, 必須打開軟件組件才能進行擴展,但必須關閉才能進行修改。 此處的目的是避免由于代碼修改而破壞某些現有的工作功能,從而避免在系統中引入錯誤。 我們應該擴展現有的類以支持任何其他功能。
此規則適用于我們的系統中更穩定的類,這些類已通過測試階段并且在生產中運行良好 。 我們將希望避免破壞現有代碼中的任何內容,因此我們應該擴展其支持的功能以滿足新的需求。
假設我們的系統中有一個EventPlanner類,該類在生產服務器上長期運行良好:
public class EventPlanner { ?private List<String> participants; private String organizer; ?public void planEvent() { System.out.println( "Planning a simple traditional event" ); ... } ?... }但是現在,我們計劃改用ThemeEventPlanner ,它將使用隨機主題來計劃事件,以使事件更加有趣。 與其直接跳入現有代碼并添加選擇事件主題并使用它的邏輯,不如擴展我們的生產穩定類:
public class ThemeEventPlanner extends EventPlanner { private String theme; ?... }對于大型系統,確定類可能出于什么目的使用并不是很簡單。 因此,僅通過擴展功能, 我們就減少了處理系統未知數的機會。
里斯科夫的替代原則:
Liskov的“替換原理”說, 派生類型必須能夠完全替代其基本類型,而不改變現有行為。 因此,如果我們有兩個類A和B使得B擴展了A,那么我們應該能夠在整個代碼庫中用B替換A而不影響系統的行為。
為了使我們能夠實現這一點, 子類的對象的行為必須與超類對象的行為完全相同。
該原則有助于我們避免類型之間的錯誤關系,因為它們可能導致意外的錯誤或副作用。
讓我們看下面的例子:
public class Bird { public void fly() { System.out.println( "Bird is now flying" ); } } ? public class Ostrich extends Bird { @Override public void fly() { throw new IllegalStateException( "Ostrich can't fly" ); } }盡管鴕鳥是鳥 ,但它仍然不會飛,因此這明顯違反了Liskov替代原理(LSP)。 同樣,涉及類型檢查邏輯的代碼清楚地表明已建立了不正確的關系。
重構代碼以遵循LSP有兩種方法:
- 消除對象之間的錯誤關系
- 使用“ 告訴,不要問 ”原理消除類型檢查和轉換
假設我們有一些涉及類型檢查的代碼:
//main method code for (User user : listOfUsers) { if (user SubscribedUser) { (user instanceof SubscribedUser) { user.offerDiscounts(); } user.makePurchases(); }使用“告訴,不要問”的原則,我們將重構上面的代碼,使其看起來像:
public class SubscribedUser extends User { @Override public void makePurchases() { this .offerDiscounts(); super .makePurchases(); } ?public void offerDiscounts() {...} } ? //main method code for (User user : listOfUsers) { user.makePurchases(); }接口隔離原理:
根據接口隔離原則, 不應強迫客戶端處理不使用的方法。 我們應該在需要時將較大的接口拆分為較小的接口。
假設我們有一個ShoppingCart界面:
public interface ShoppingCart { ?void addItem(Item item); void removeItem(Item item); void makePayment(); boolean checkItemAvailability(Item item); ??? }付款和檢查商品的可用性不是購物車要執行的操作。 我們很可能會遇到不使用這些方法的該接口的實現。
因此,最好將上述接口改為:
public interface BaseShoppingCart { void addItem(Item item); void removeItem(Item item); } ? public interface PaymentProcessor { void makePayment(); } ? public interface StockVerifier { boolean checkItemAvailability(Item item); }接口隔離原則(ISP)還加強了其他原則:
- 單一職責原則:實現較小接口的類通常更加集中并且通常具有單一目的
- Liskov替換原理:使用較小的接口,我們有更多的機會讓類實現它們以完全替代接口
依賴倒置:
它是最流行和有用的設計原則之一,因為它促進了對象之間的松散耦合。 依賴倒置原則指出高級模塊不應該依賴于低級模塊; 兩者都應取決于抽象。
高級模塊告訴我們該軟件應該做什么 。 用戶授權和付款是高級模塊的示例。
另一方面, 低級模塊告訴我們該軟件應如何執行各種任務,即它涉及實現細節。 低級模塊的一些示例包括安全性(OAuth),網絡,數據庫訪問,IO等。
讓我們編寫一個UserRepository接口及其實現類:
public interface UserRepository { List<User> findAllUsers(); } public class UserRepository implements UserRepository { ?public List<User> findAllUsers() { //queries database and returns a list of users ... } }我們在這里提取了接口中模塊的抽象。
現在說我們有高級模塊UserAuthorization ,它檢查用戶是否被授權訪問系統。 我們將僅使用UserRepository接口的引用:
public class UserAuthorization { ?... ?public boolean isValidUser(User user) { UserRepository repo = UserRepositoryFactory.create(); return repo.getAllUsers().stream().anyMatch(u -> u.equals(user)); } }此外,我們使用工廠類來實例化UserRepository 。
請注意, 我們僅依靠抽象而不是依賴。 因此,我們可以輕松添加UserRepository的更多實現,而對我們的高級模塊沒有太大影響。
多么優雅!
結論:
在本教程中,我們討論了SOLID設計原則。 我們還查看了上述每種原則的Java代碼示例。
翻譯自: https://www.javacodegeeks.com/2019/09/solid-design-principles.html
solid設計原則
總結
以上是生活随笔為你收集整理的solid设计原则_SOLID设计原则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: azure 部署java_jClarit
- 下一篇: 家庭网络ddos如何恢复(家庭网络ddo