由Android MVP設計模式引發的Java介面思考
1.前言
最近算忙完了身邊的事情,想著做些什麼,就把丟下大半年的“Android開發”重新拿起來做做,然後發現自己對”MVP“的設計模式有些不能理解。主要問題在於:
為什麼對於每個功能的presenter,view都要各寫一個介面再寫一個唯一(對,強調一下唯一)的實現類?如果說為了實現重用性,那麼我覺得定義介面是對的,但是隻有唯一的實現類時,為什麼也要定義介面呢?
2. 資料搜尋
帶著這樣的疑惑,google了一堆博文資料來看,發現大多數博文就是講解了MVP是什麼,比起MVC有什麼好處,舉個例子講解下MVP該如何使用。綜合我看到的文章,我並沒發現哪一篇文章說到了我的這個問題。於是準備從google的開源專案-todo-mvp(
花費了半天時間,解決了各種依賴衝突,得到能夠編譯的專案目錄樹如下:
1540370019429.png可以看出,google大大是以功能來劃分目錄的,隨便展開一個功能看看有些什麼檔案:
1540370193067.png經過一波簡單的分析,發現google大大也是對每個功能都建立了對應的presenter和view介面,然後在分別實現,並沒有找到我想要的東西。
之後又想到既然是Java介面,那麼肯定是自己介面的意義沒有理解好。於是又去google了一波“Java介面的實際意義”,部分文章講得都很巨集觀,沒有給人以實際落到地的感覺。直到發現了一個知乎大佬的超形象的回答:
這是一個初學者非常常見的問題。
例如我定義了一個介面,但是我在繼承這個介面的類中還要寫介面的實現方法,那我不如直接就在這個類中寫實現方法豈不是更便捷,還省去了定義介面?
介面就是個招牌。
比如說你今年放假出去杭州旅遊,玩了一上午,你也有點餓了,突然看到前面有個店子,上面掛著KFC,然後你就知道今天中飯有著落了。
KFC就是介面,我們看到了這個介面,就知道這個店會賣炸雞腿(實現介面)。
那麼為神馬我們要去定義一個介面涅,這個店可以直接賣炸雞腿啊(直接寫實現方法),是的,這個店可以直接賣炸雞腿,但沒有掛KFC的招牌,我們就不能直接簡單粗暴的衝進去叫服務員給兩個炸雞腿了。
要麼,我們就要進去問,你這裡賣不賣炸雞腿啊,賣不賣漢堡啊,賣不賣聖代啊(這就是反射)。很顯然,這樣一家家的問實在是非常麻煩(反射效能很差)。
要麼,我們就要記住,中山路108號賣炸雞,黃山路45號賣炸雞(硬編碼),很顯然這樣我們要記住的很多很多東西(程式碼量劇增),而且,如果有新的店賣炸雞腿,我們也不可能知道(不利於擴充套件)。
另外一篇博文也以一個程式設計中的實際問題回答了這個問題:
眾所周知,介面(interface)是java中很重要的作用,其中介面作用如下:1.使java擁有擁有強大的面向物件的能力,2.簡單,規範,3.維護/可擴充套件性;4.安全嚴密
之前一直不能很好的理解介面的作用,會有種種疑問,如:1.為啥要定義介面,直接在類中實現方法不行嗎?
針對這個問題在網上看到一個舉例然後恍然大悟.例子如下:像java內建的介面Comparable裡的方法:compareTo就被很多類實現,如各種不同資料型別裡有不同的實現.如果不定義介面直接在類裡定義方法可能不同的類就會命名不同的方法名,即不能統一規範..並且如果沒有介面的話也不能很好的知道每個類裡的對應方法都是用來比較的.2.如果某個接口裡的方法只被一個類實現的話那還有必要寫這個介面嗎?
思考這個問題是因為看我們的工程裡每個service都是介面,然後基本上都只有一個類實現了該介面.所以一直不太理解為什麼要這麼做.心想為啥還多此一舉的定義介面呢.後來瞭解到這樣做是為了以後更好的擴充套件,比如有個userService介面,裡面有個方法getUserInfoById的,有一個實現類UserServiceImpl實現時限制了傳入的uid必須是數字且長度在8-12位之間.但後面又有新的需求了要求uid長度在10-15位之間,這樣已有的方法肯定是無法滿足需求的,但也不能直接在已有的方法上進行修改,因為有很多地方都在呼叫此方法,若修改就會導致問題.這個時候就可以再新建個類實現該介面了..這個就是介面的可維護/可擴充套件性..
3. 總結
看到這裡也就基本理解了,其實介面主要功能其實是一種規範,有了這種規範,大家可以各司其職,便於拓展,重用。之所以不能理解,其實是因為以前做過的專案中,沒有做過維護工作,一直處於“外包”只要實現其功能的狀態,所以不懂介面的意義。如果專案處於維護狀態,需求功能會逐漸增多,當發現某個類A的功能不能滿足當前需求,如果沒有介面,我們必須在當前類上進行修改,這就會影響到引用這個A的其他類。如果有了介面,其餘類中只用存放介面的控制代碼,我們只需要新建一個類實現這個介面(或者之前的實現類,作為子實現類)即可了。
嗯,簡單記下,方便備查。