任何設計模式都是爲了解決某些特定場景下所遇到的問題,要知道設計模式實際上是能夠有一些變更的,說白了設計模式是一種思想而並不是一種代碼,不要爲了使用某種模式生搬硬套。當咱們理解一種設計模式的思想時,不要去鑽牛角尖。咱們在開發中遇到一些問題的時候,就能夠在腦海中翻一翻咱們所積攢的知識,是否是能夠用某一些設計模式來解決這個問題,又或者是用其餘方式來解決。固然咱們也須要去看一些文章和書籍,不少都寫得很是不錯,可是咱們不能只瞭解書中所說的例子如: 小轎車的建立過程,電腦的組裝,銀行辦理業務等等,更多須要花時間去思考,怎樣用咱們本身的項目框架中,不然看過了大量的文章和書籍,發現好像知道那麼回事,但就是項目中不知道怎麼用。思想要打通,但實戰更爲重要。java
####1.問題思考android
仍記得去年剛到公司那會,跟着你們夥一塊兒工做,那時公司已有 7 我的在作 android 開發,我也不知道整個項目寫得怎樣,我看了大部分代碼,發現不少有問題,其中保存用戶信息是這麼寫的:面試
ACache mCache = ACache.get(this); mCache.put("userName", "darren"); mCache.put("userHeader", "http://www.xxxxx.jpg"); 複製代碼
當時看到這個代碼我就在想後面確定會有問題,先不說沒有用 LoginSession 去管理,單拿數據的存儲來講,這樣直接寫確定是有問題的。由於今天的主要內容講的是講工廠設計模式,這裏我就不說與 LoginSession 相關的內容,也不說這個框架 ASimpleCache 怎麼樣,今天特地查了一下有 2000+ 的star。果不其而後面快要上線的時候,由於當時因爲清理緩存的功能,須要清理某一部分數據,可是部分數據(用戶信息)是須要保留的,當咱們調用 clear 的方法是所有清理。這個時候擺在咱們面前的解決方法有不少,第一種,乾脆就不作清理只是作一個假數據的顯示和 Toast ;第二種,把用戶信息用另外一種緩存存着;第三種,就是把 ASimpleCache 的依賴刪除,通通改掉。第一種多是最快的方式,第三種是最慢的,後來通過商量以後仍是決定所有改掉,而且由我來改採用第三種方式。好在當時只有 20+ 的地方用了,大概改了一個小時就改好了,把依賴去掉,哪裏報錯改哪裏。當咱們碰到這個問題的時候,我想應該不是立馬去解決問題,就像我文章開頭所說的同樣,而是想避免下次再出現這樣的問題,今天咱們就用工廠設計模式,看下數據存儲應該怎麼存。數據庫
####2.工廠設計模式介紹設計模式
2.1 模式定義緩存
定義一個建立對象的接口,讓子類決定實例化哪一個類,而對象的建立統一交由工廠去生成,既作到了解耦也保證了最少知識原則。通常分爲三類:簡單工廠模式,工廠方法模式,抽象工廠模式bash
2.2 簡單工廠模式markdown
目前按照數據的存儲咱們通常是有這麼幾類,內存,SharedPreferences,數據庫,磁盤,存儲的數據通常分爲基本數據類型和對象,先上 UML 圖架構
public class IOFactory implements Factory{ // 經過 Factory 去建立 IOHandler 對象 public static IOHandler createIOHandler(IOType type){ switch (type){ case IOType.MEMORY: // 內存緩存 return new MemoryIOHandler(); case IOType.PREFERENCES: // Preferences緩存 return new PreferencesIOHandler(); case IOType.DISK: // 磁盤緩存 return new DiskIOHandler(); default: return null; } } } 複製代碼
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 獲取磁盤緩存的 IOHandler IOHandler ioHandler = IOFactory.createIOHandler(IOFactory.IOType.DISK); // 保存數據 ioHandler.save("userName","darren"); ioHandler.save("userPwd","940223"); } public void click(View view){ // 獲取磁盤緩存的 IOHandler IOHandler ioHandler = IOFactory.createIOHandler(IOFactory.IOType.DISK); // 獲取數據 String userName = ioHandler.getString("userName"); String userPwd = ioHandler.getString("userPwd"); Log.e("TAG","userName = "+userName+" userPwd = "+userPwd); } } 複製代碼
上面就是咱們的簡單工廠模式,就這麼簡單,能夠看到咱們不是直接經過 new 對象來保存數據的,而是用不一樣的類型,經過 IOFactory 去建立咱們的對象。這樣目前來說也看不出什麼好處,並且問題仍是有不少。框架
2.3 工廠方法模式
IOFactory 掌管了全部的業務邏輯處理。這樣的類,咱們稱爲上帝類/全能類。上帝類耦合度很是高,每當須要增長一種緩存是,就須要大量更改 IOFactory 中的代碼,並且也不符合開閉原則,好比我想加一個 DatabaseIOHandler 等等。接下來看下工廠方法模式, 先上 UML 圖
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 建立 IOFactory 生成 IOHandler DiskIOFactory diskIOFactory = new DiskIOFactory(); IOHandler ioHandler = diskIOFactory.createIOHandler(); // 保存數據 ioHandler.save("userName","darren"); ioHandler.save("userPwd","940223"); } public void click(View view){ // 建立 IOFactory 生成 IOHandler DiskIOFactory diskIOFactory = new DiskIOFactory(); IOHandler ioHandler = diskIOFactory.createIOHandler(); // 獲取數據 String userName = ioHandler.getString("userName"); String userPwd = ioHandler.getString("userPwd"); Log.e("TAG","userName = "+userName+" userPwd = "+userPwd); } } 複製代碼
工廠方法模式也是很好理解的,這個時候咱們想增長 DatabaseIOHandler 就只須要新增 DatabaseIOFactory 建立一個 DatabaseIOHandler 就好了,而不是去修改咱們原來的代碼。可是隨着數據存儲方式的增長,相應的工廠類也會同比增長,形成項目文件十分臃腫巨大。咱們可能也須要好好考慮,到底要不要用,因而爲了減小工廠類的出現數量,抽象工廠模式誕生了。
2.4抽象工廠模式
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 獲取默認的 IOHandler , 默認是磁盤存儲 IOHandler ioHandler = IOFactory.getFactory().getDefaultIOHandler(); // 保存數據 ioHandler.save("userName","darren"); ioHandler.save("userPwd","940223"); } public void click(View view){ // 獲取默認的 IOHandler , 默認是磁盤存儲 IOHandler ioHandler = IOFactory.getFactory().getDefaultIOHandler(); // 獲取數據 String userName = ioHandler.getString("userName"); String userPwd = ioHandler.getString("userPwd"); Log.e("TAG","userName = "+userName+" userPwd = "+userPwd); } } 複製代碼
最近有不少認識的哥們在找工做,都說感受不是很好找,不少哥們都給我看了簡歷,換工做以前要想好準備好,騎驢找馬等等這裏先不說,單拿我看的簡從來講,簡歷必定要有突出的亮點,好比你會用 RXjava+OKhttp+Retrofit 來作項目,我想不少人都會用,若是你能知道原理這就算是一個亮點,而面試的時候我通常也會問一些這方面的內容,又或者你看過大量的 FrameWorker 層的源碼,讀過大公司的一些開源框架像阿里騰訊的熱修復源碼,360和滴滴的插件化開發源碼等等,固然最好是去讀最新版的,這些都算是亮點。
全部分享大綱:Android進階之旅 - 系統架構篇
視頻講解地址:http://pan.baidu.com/s/1hrSaQl2