文章首發於公衆號:松花皮蛋的黑板報數據庫
做者就任於京東,在穩定性保障、敏捷開發、高級JAVA、微服務架構有深刻的理解設計模式
許多文章都在強調不要過分設計本身的系統,可是沒有道出個因此然來,因此本文列出一些經典的過分設計,但願能給你帶來啓發,在工程上作一些平衡,避免過分設計把咱們推到另一個複雜度上安全
一、Engineering is more clever than Business架構
工程師一般認爲本身是最聰明的,這第一個錯誤容易讓本身過於工程化。咱們計劃了100件事,業務方會提出咱們以前沒有考慮到的第101件。若是咱們解決了100個問題,那麼接下來還可能會有1000個問題。咱們覺得一切都是掌握之中,然而實際徹底不知道將來會發生什麼app
在研發生涯中,從未碰到過業務在需求上是收斂,它們老是發散的,這是業務的原本面目,不是產品經理的錯微服務
二、Reusable Business Functionality工具
當業務方提出了愈來愈多的需求時,咱們第一反應是儘可能分組和泛化業務,這是大部分MVC架構最後成爲由大量模型或者控制器堆積的緣由,正如前面所說的,業務永遠不會是收斂的,它們老是發散的學習
在系統中,共享邏輯和抽象應該是趨於穩定的,然而隨着功能迭代愈來愈多,它們要麼會保持平穩,要麼會變得脆弱。當相反的狀況發生時,就會成爲太大而失敗的系統測試
好比說,有個業務是實現用戶屬性管理,咱們持着任何東西都是類似的這種觀點,首先完成通用的CRUD邏輯,可是這個需求實際上要求知足13個不一樣的註冊流程,也就是說通用的邏輯代碼沒有任何意義。同理,一個訂單視圖和訂單編輯視圖流程是徹底不同的,可恰恰有些人會合並視圖ui
咱們在橫向分割業務前,應該先嚐試縱向分割,同時也要考慮從一種方式切換到另一種方式的可操做性和便捷性,不然重寫系統將是災難性的工做,也就是說分離行爲比強行合併好
3、Everything is Generic
須要鏈接數據庫,那就寫個通用的泛化適配器
須要查詢數據庫,那就寫個泛化查詢
須要對參數進行校驗,那就寫個通用的參數校驗器
須要對結果進行包裝,那就寫個通用的數據映射器
等等
當在實現需求時,浪費大量的時間嘗試總結出完美的抽象層,甚至本來業務問題的答案很是顯而易見。即便奇蹟般地總結出了一個完美的抽象時,它每每會很快變得不適用,目前最好的代碼設計側重點應該是編碼易於被刪除的,而不是盲目追求易於擴展
實際上,重複代碼比錯誤的抽象更好,只有當你看到系統裏有邏輯重複的代碼,才能更好地進行抽象,同時重複代碼暴露了許多用例,有助於使得邊界上下文清晰
四、Shallow Wrappers
咱們習慣使用外部庫時都封裝一層,這種封裝是淺層的,不幸的是,咱們容易在提供功能和編寫好的包裝器之間模棱兩可,混淆着大量的業務邏輯,使得它既不是一個好的包裝器,也不是一個好的業務解決方案。實際上要封裝一個優質的庫,須要投入大量的時間編寫,同時保證高代碼質量和完善的代碼測試,具有清晰、可測試的、可測量的API。須要注意的是,封裝應該是例外,不該該是常態,不要爲了封裝而封裝
五、Applying Quality like a Tool
高質量的代碼一般知足SOLID原則,使用相應的設計模式和代碼技術,好比factory、builder、strategy、generics、enums。若是你不加思索地運用質量概念,好比說將全部的變量修飾修改成private final,這並不能將編碼質量提升,或者改變過去鏈式繼承的方式,每一個類都有接口和實現,而後注入到下一層,看似知足SOLID概念。實際上SOLID的設計初衷是爲了反對濫用繼承與其餘OOP概念,然而大部分工程師沒有搞清楚這些概念從哪裏來,如何出現,只是照單全收,沒有從思惟上消化,只是工具化地盲目應用
學習一門其餘語言,嘗試以另外的思惟模式去作事情,這樣會成爲一個更好的開發者。新瓶裝舊酒對咱們沒有任何幫助,咱們沒必要爲了應用一個新概念而弄亂一個清晰的設計
六、Overzealous Adopter Syndrome
發現了泛型技術,將一個簡單的 「HelloWorldPrinter」 修改爲了「HelloWorldPrinter」,那怕事實上只會有特定的數據類型,或者有足夠的普通類型簽名
發現了策略模式,如今每一個條件語句都是一個策略
處處使用枚舉/擴展方法/Traits等各類炫酷的技術
上面都體現出了過分適配問題
七、<X>–ity
例子一、實現一個CMS系統,要求具有可擴展性,業務人員可輕鬆添加字段
結果:業務人員歷來不使用這個功能,當他們須要時,會要求工程師在旁邊協助,也許咱們所須要的只是一個簡單的開發人員指南,能夠在幾個小時內添加一個新字段,而不是點擊式界面
例子2:設計一個可輕鬆配置的一應俱全的數據庫層,咱們能夠經過文件配置輕鬆切換數據源
結果: 過了很長時間由於某種緣由須要切換數據源,可是修改配置文件沒法知足咱們的要求,如今業務有了不少的功能差距,致使不兼容
實際上,建議將數據庫視爲解決方案的一部分,拋棄可配置性,不然很難保證兼容性。當設計時,多問本身使用場景是什麼,而後深挖下去,你可能會發現大部分特性都是沒有必要的,包括可配置性、安全性、可擴展性、可維護性、可繼承性。總之,不要在沒有被要求時加上各類特性,應該明確地定義與評估場景、用戶故事、需求、用途
文章翻譯修改自:
文章來源:www.liangsonghua.me
做者介紹:京東資深工程師-梁鬆華,在穩定性保障、敏捷開發、JAVA高級、微服務架構方面有深刻的理解