Android 外觀模式
Android 設計模式系列文章Android 23種設計模式
一、前言
Android 外觀模式(Facade),這個模式的使用率就非常高了。我們經常引用一些第三方的功能,或者GitHub上別人封裝好的功能。很多都使用的時外觀模式。封裝過後,我們在使用這些庫的時候,只需要呼叫極少數的方法就可以達到目的。我相信大家已經無數次的使用外觀模式了。接下來讓我們“重新”認識一下外觀模式。
二、定義
提供一個介面,使得客戶端只通過介面訪問。隱藏內部子系統的實現。
三、例子
認識設計模式最好的方法就是理解它的demo。下面我們通過一個生產nokia手機的例子來說明。我們分為三個步驟,設計,開發和生產來模擬整個過程。
3.1、最高層介面
抽象出API方法,並實現
public abstract class NokiaPhone { public abstract void design(); public abstract void development(); public abstract void production(); } public class NokiaPhoneImpl extends NokiaPhone{ private Software software = new SoftwareImpl(); private Hardware hardware = new HardwareImpl(); private Production production = new ProductionImpl(); @Override public void design() { hardware.design(); software.design(); } @Override public void development() { hardware.development(); software.development(); } @Override public void production() { hardware.test(); software.test(); production.production(); } }
最高層介面就是為了統一API,客戶端呼叫只需要呼叫設計,開發和生產三個方法舉行了,具體內部實現無須關注。具體的實現由內部的子系統去完成。
3.2、子系統
硬體部
public interface Hardware { public void design(); public void development(); public void test(); } public class HardwareImpl implements Hardware { private static final String TAG = HardwareImpl.class.getSimpleName(); @Override public void design() { Log.d(TAG,"design"); } @Override public void development() { Log.d(TAG,"development"); } @Override public void test() { Log.d(TAG,"test pass"); } }
軟體部
public interface Software { public void design(); public void development(); public void test(); } public class SoftwareImpl implements Software{ private static final String TAG = SoftwareImpl.class.getSimpleName(); @Override public void design() { Log.d(TAG,"design"); } @Override public void development() { Log.d(TAG,"development"); } @Override public void test() { Log.d(TAG,"test pass"); } }
生產部
public interface Production { public void production(); } public class ProductionImpl implements Production { private static final String TAG = ProductionImpl.class.getSimpleName(); @Override public void production() { Log.d(TAG,"production nokia"); } }
三個部門的職能寫的比較簡化,子系統還可以包含更多的子系統,比如軟體部還有測試組、系統組等等。這裡為了篇幅就不舉例了。
3.3、呼叫
NokiaPhoneImpl nokiaPhoneImpl = new NokiaPhoneImpl(); nokiaPhoneImpl.design(); nokiaPhoneImpl.development(); nokiaPhoneImpl.production();
客戶端的呼叫就很簡單了,和抽象類抽象出的方法一樣。統一的API只有三個。具體的實現由子系統去完成。輸出如下:
02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/HardwareImpl: design 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/SoftwareImpl: design 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/HardwareImpl: development 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/SoftwareImpl: development 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/HardwareImpl: test pass 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/SoftwareImpl: test pass 02-21 10:07:51.896 6606-6606/com.yink.designpattern.designpattern D/ProductionImpl: production nokia
四、Context
Android原始碼中,Context就是外觀模式的一個例子。Context這個抽象類定義了很多我們熟知的方法。它具體的實現都是在ContextImpl.java這個類裡邊。篇幅原因,多餘的方法就省略了。
public abstract class Context { public abstract void sendBroadcast(@RequiresPermission Intent intent); public abstract ComponentName startService(Intent service); ... class ContextImpl extends Context { @Override public void sendBroadcast(Intent intent, String receiverPermission) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); String[] receiverPermissions = receiverPermission == null ? null : new String[] {receiverPermission}; try { intent.prepareToLeaveProcess(this); ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, false, mUser); }
而ContextImpl實現這些抽象方法時,又通過了ActivityManager、PackageManager一系列的其他子系統。