摘要:前言關于設計模式,想必大家的第一感覺就是過于高深,有點虛吧。為什么要學習設計模式因為要裝逼啊咳咳,大家請忽略前面那句話。處處都是設計模式的體現,所以若想攻下,設計模式是必學的。下節預告單例模式
前言
關于設計模式,想必大家的第一感覺就是過于高深,有點虛吧。相對來說,我們還是更熟悉ssh或者ssm之類的開發框架,一個工具用久了就會熟能生巧,就像刷漆工,時間長了也知道如何刷的一手漂亮的好墻。我們把springmvc用的很溜,把mybatis用的很溜,但這只是一個合格的程序員應該具備的能力之一。于是我們便成為了代碼工人,想站在更高角度去設計,設計模式是必不可少的。簡介
廢話那么多,我們直接進入正題呢,到底什么是設計模式呢?我在設計模式之禪上摘抄出這一句話:
為什么要學習設計模式設計模式(Designpattern)是一套理論,由軟件界的先輩們總結出的一套可以反復使用的經驗,它可以提高代碼的可重用性,增強系統的可維護性,以及解決一系列的復雜問題。
因為要裝逼啊...咳咳,大家請忽略前面那句話。相信大家都有閱讀spring源碼的經歷吧,看到類層次設計圖,為什么會有這么多的接口,這么多的抽象類,這么多實現,心里有一萬只草泥馬狂奔而過。spring處處都是設計模式的體現,所以若想攻下spring,設計模式是必學的。其次,作為一個coder,最煩的就是需求變更,我們可以分析現有的需求,預測可能發生的變更,但是我們不能控制需求的變更。既然需求不可變更,那如何擁抱變化呢?設計模式給了我們知道,提出了6大原則,在此基礎上提出了23種設計模式。如果你通曉了23種設計模式,那你就可以站在一個更高的層次去賞析程序代碼,完成從代碼工人到架構師的轉變~>~.
設計模式六大原則 單一職責原則(最容易理解,最難實施的一個原則)描述:應該有且僅有一個原因引起類的變更 相信大家已經很不屑了,切,這么簡單的東西還拿出來說。可是道理簡單實現難啊。下面我給大家示例一些代碼: public interface IUserInfo { void setUserName(String name); void setUserAge(int age); void walk(); void seeMovie(); void addRole(Role role); } 相信初級程序員都不會犯這樣的錯,將用戶信息和用戶行為放在同一個類里。最佳的做法就是將用戶信息和用戶行為分開管理,加角色動作也應該放在相應的實現類里。這是我臨時想的例子,雖然很簡單,但足以表達單一原則的意思。單一職責原則最難劃分的就是職責,職責沒有量化的標準,職責劃分的過于細,類的數量會暴增,系統復雜度會以指數趨勢增長,所以建議是接口一定要做到單一職責,累類設計盡量做到單一職責。里氏替換原則(使用時一定要注意子類的個性化..)
描述:所有引用基類的地方必須能透明地使用其子類的對象。 java與c++不同,java是一門單根繼承的語言。使用extend關鍵字聲明繼承,若不使用,則代表繼承Object。子類繼承父類,會擁有父類的方法和屬性,很多開源框架的擴展接口都是通過繼承父類來完成的。通過這個特性,我們明白只要父類存在的地方,我們都可以替換成子類,并且編譯器不會報錯。但是java允許子類重寫父類方法,這種子類的個性化有時會嚴重違背里氏替換原則.給大家上個示例:
public class AnyClazz{ //有某一個方法,使用了一個父類類型 public void someoneMethod(Parent parent){ parent.method(); } } public class Parent { public void method(){ System.out.println("parent method"); } } public class SubClass extends Parent{ //結果某一個子類重寫了父類的方法,說不支持該操作了 public void method() { throw new Exception(); } } public class Test{ public static void main(String[] args) { AnyClazz anyClazz = new AnyClazz(); anyClazz.someoneMethod(new Parent()); anyClazz.someoneMethod(new SubClass()); } }
程序運行結果肯定會報錯,這就相當于我們埋了一個雷,子類復寫父類方法,編譯期不報錯,運行期就會報錯。所以建議在項目中使用此原則時,應盡量避免子類的個性,一旦子類有個性,子類和父類的矛盾將可能直接破壞整個程序。
依賴倒置原則(很常見,現在的企業開發中業務層都有對應接口)描述:面向接口編程。 在Java中的語言表現就是:模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系是通過接口或抽象類發生的。接口和抽象類不依賴于實現類。實現類依賴接口或抽象類。簡而言之,就是之前的描述~~。給大家舉個例子:
public class Cooker { public void work(){ System.out.println("我會做飯"); } } public class Boss { public void recruitPerson (Cooker cooker){ cooker.work(); } } public class Test { public static void main(String[] args) { Boss boss = new Boss(); boss.recruitPerson(new Cooker()); } } 運行結果:我會做飯
上面代碼一個大老板剛開了一個超市,在招廚師。假如我們要是招大堂經理怎么辦?創建經理類,在boss中增加招經理的方法同時在test中修改。這樣改好嗎?僅僅是需求改了一點點,我們就要在所有代碼里進行一些改動,這代價也太大了吧,耦合性忒高了~ 不要著急,依賴倒置原則可以幫我們解決這個問題,它可以減少類間的耦合性,提高系統的穩定性,降低并行開發引起的風險,提高代碼可讀性和維護性。修改之后的例子如下:
public interface IWorker { void work(); } public class Cooker implements IWorker { @Override public void work(){ System.out.println("我會做飯"); } } public class Manager implements IWorker { @Override public void work() { System.out.println("糊弄老板,指揮其他人干活"); } } public interface IBoss { void recruitPerson(IWorker iWorker); } public class Boss implements IBoss{ @Override public void recruitPerson(IWorker iWorker) { iWorker.work(); } } public class Test { public static void main(String[] args) { Boss boss = new Boss(); IWorker iWorker = new Manager(); boss.recruitPerson(iWorker); } } 運行結果: 糊弄老板,指揮其他人干活
咋一看,類變得更多了..使用技術總是要有點成本的嗎,但假如以后我們在增加招理貨員,招收銀員等等改動就小了。其實這個原則的本質就是通過抽象是各個類和模塊的實現獨立,不互相影響,實現松耦合。接口隔離原則(六大原則中身材最好的那個小姐姐)
描述:接口盡量細化,同時接口中方法盡量少。 看到上面的描述可能會有點疑惑,這個和第一個的小姐姐(單一職責原則)有點像啊。單一職責衡量的是類的和接口職責要單一,對,是職責!而接口隔離原則就只是要求接口的粒度盡可能的小,最好就是一個接口一個方法(這是完美符合接口隔離原則的),不過這樣做的話是明顯要被其他小伙伴干死的(2333~~~)。接口粒度太小,接口數就會暴增,開發人員嗆死在接口的海洋里,接口粒度太大,靈活性降低,無法提供定制服務。給大家舉個例子:
//美食 public interface ICate { void goodLool(); void niceTaste(); void cleanFood(); } public class Cate implements ICate{ @Override public void goodLool() { System.out.println("色相看起來很好O(∩_∩)O哈哈~"); } @Override public void niceTaste() { System.out.println("吃起來,味絕了(*^▽^*)"); } @Override public void cleanFood() { System.out.println("食材很干凈,食用放心"); } } public abstract class AbstractPerson { protected ICate iCate; public AbstractPerson(ICate iCate) { this.iCate = iCate; } abstract void eat(); } public class Person extends AbstractPerson { public Person(ICate iCate) { super(iCate); } @Override void eat() { iCate.cleanFood(); iCate.goodLool(); iCate.niceTaste(); } } public class Test { public static void main(String[] args) { ICate iCate = new Cate(); AbstractPerson abstractPerson = new Person(iCate); abstractPerson.eat(); } } 運行結果: 食材很干凈,食用放心 色相看起來很好O(∩_∩)O哈哈~ 吃起來,味絕了(*^▽^*)
上面的例子我去吃美食,我對美食的標準是看起來,聞起來像,吃起來放心(吃貨up!up!)。可是每個人對美食的標準都是一樣的,你總不能因為臭豆腐聞起來很臭就不是美食吧。可是現在接口定義了只有三個條件都滿足才能叫美食,這個該怎么辦?難道要再擴展一個美食接口,只定義味道標準,可是我們的抽象類依賴的是ICate接口,我們的person又怎么只根據味道去分辨是不是美食呢?我們采用接口隔離原則去細化接口,示例如下:
public interface IGoodLookCate { void goodLook(); } public interface IGoodTasteCate { void niceTaste(); void cleanFood(); } public class Cate implements IGoodLookCate,IGoodTasteCate{ @Override public void goodLook() { System.out.println("色相看起來很好O(∩_∩)O哈哈~"); } @Override public void niceTaste() { System.out.println("吃起來,味絕了(*^▽^*)"); } @Override public void cleanFood() { System.out.println("食材很干凈,食用放心"); } }
通過這樣的重構后,不僅是要好吃的美食還是要好看的美食,都可以保持接口的穩定。當然你如果要說美食的標準又變了,接口還得改。沒錯,但是設計是有限度的,不能無限考慮未來,不然會陷入到過度設計的泥潭當中。迪米特法則(六大原則中最害羞的小姐姐)
描述:一個對象盡量不要知道太多關于其他對象的事
這個原則的核心觀念就是類間解耦,低耦合。通俗一點來講就是1.只和朋友交流2.朋友之間也是有距離的。舉個例子說明下吧:
public class Goods { } public class Worker { public void sendGoods(Listlist){ System.out.println("送貨嘍:"+list); } } public class Boss { private static final List list = new ArrayList (); static { list.add(new Goods()); list.add(new Goods()); list.add(new Goods()); } public static void main(String[] args) { Worker worker = new Worker(); worker.sendGoods(list); } }
工人送貨的場景,老板和工人是直接關系,工人和貨物是直接關系,但是代碼中老板和貨物也攪在了一起,出現了過多依賴,破壞了老板類的健壯性,已經違反了迪米特法則。正確做法應該是將貨物的邏輯抽取到工人當中(因為非常簡單,就不上代碼示例了)。朋友之間也是有距離的應當如何理解呢?假如類A提供了getA(),getB(),getC()三個方法,類B在邏輯內對ABC三個方法進行調用或者根據其返回值決定邏輯,這樣也違反了迪米特法則,正確做法應是將對ABC三個方法調用的邏輯抽取封裝到A中,同時將ABC三個方法進行私有化。
開閉原則(六大原則中當之無愧的大姐大)描述:對擴展開放,對修改關閉
開閉原則是六大原則里的精神領袖,也是最虛的原則。前面五個原則就是對開閉原則的具體解釋。意思就是現在的系統中,不需要修改原有的代碼,只需要擴展一些新的實現就可以搞定。但是沒有任何一個系統可以做到,哪怕是spring也不可以,雖說他的擴展性已經強的{{BANNED}}。
以上6個原則是為了之后23種設計模式的描述,基本上都是我自己的理解,或許形容有好有差,不需要在意,各位完全可以有自己的理解。
下節預告:單例模式文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68019.html
摘要:探究系統登錄驗證碼的實現后端掘金驗證碼生成類手把手教程后端博客系統第一章掘金轉眼間時間就從月份到現在的十一月份了。提供了與標準不同的工作方式我的后端書架后端掘金我的后端書架月前本書架主要針對后端開發與架構。 Spring Boot干貨系列總綱 | 掘金技術征文 - 掘金原本地址:Spring Boot干貨系列總綱博客地址:http://tengj.top/ 前言 博主16年認識Spin...
摘要:不知不覺寫已經將近年時間了,在其中嘗試著看了一下其它語言,發現其它語言都有很好的調試工具,協助調試和開發。難道就能依靠這樣的斷點調試么直到我發現了說來慚愧,這么久才發現,才發現是真心好用,于是花點時間總結一下,大致的內容框架如下 不知不覺寫php已經將近5年時間了,在其中嘗試著看了一下其它語言,發現其它語言都有很好的調試工具,協助調試和開發。難道php就能依靠var_dump 、ech...
摘要:我打算寫一個鏈表操作的系列,來自的系列,實現語言是。通過自己實現一個鏈表和常用操作,可以加深理解這類數據結構的優缺點。鏈表經常用來訓練指針操作,雖然這只對適用,但等高級語言中控制引用的思路其實也差不多。 TL;DR 我打算寫一個鏈表操作的系列,來自 Codewars 的 Linked List 系列 kata ,實現語言是 JavaScript 。這篇是開篇,簡單描述了一下我寫這個的目...
摘要:系列文章更新計劃列表主要對一些中常用的框架進行簡單的介紹及快速上手,外加相關資料的收集更新列表會不定期的加入新的內容以進行擴充,如果你對此感興趣可以站內聯系我。 導讀: 從第一次接觸Spring Boot 至今已經有半年多了,在這期間也瀏覽了許多和Spring Boot 相關的書籍及文章,公司里面的許多項目也一直在使用Spring Boot。關于Spring Boot的一些看法:Spr...
閱讀 1160·2021-11-16 11:45
閱讀 1014·2021-09-04 16:41
閱讀 3076·2019-08-29 16:40
閱讀 2851·2019-08-29 15:34
閱讀 2672·2019-08-29 13:11
閱讀 1734·2019-08-29 12:58
閱讀 1725·2019-08-28 18:00
閱讀 1775·2019-08-26 18:26