Android與設計模式――裝飾者(Decorator)模式
來源:程序員人生 發布時間:2014-12-14 09:12:11 閱讀次數:4996次
在閻宏博士的《JAVA與模式》1書中開頭是這樣描寫裝潢(Decorator)模式的:
裝潢模式又名包裝(Wrapper)模式。裝潢模式以對客戶端透明的方式擴大對象的功能,是繼承關系的1個替換方案。
裝潢模式的結構
裝潢模式以對客戶透明的方式動態地給1個對象附加上更多的責任。換言之,客戶端其實不會覺得對象在裝潢前和裝潢后有甚么不同。裝潢模式可以在不使用創造更多子類的情況下,將對象的功能加以擴大。(上文來源于網絡)
裝潢模式的類圖以下:

在裝潢模式中的角色有:
● 抽象構件(Context)角色:給出1個抽象接口,以規范準備接收附加責任的對象。
● 具體構件(ContextImpl)角色:定義1個將要接收附加責任的類。
● 裝潢(ContextWrapper)角色:持有1個構件(Component)對象的實例,并定義1個與抽象構件接口1致的接口。
● 具體裝潢(Activity/Service/Application)角色:負責給構件對象“貼上”附加的責任。
ContextImpl是抽象類Context的具體實現,ContextWrapper及所有其子類對象持有的Context均是ContextImpl對象。以Activity的Context為例,Activity創建是在ActivityThread中,Activity創建時:
public final class ActivityThread {
.......
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
.......
}
........
}
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
Context baseContext = appContext;
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
for (int displayId : dm.getDisplayIds()) {
if (displayId != Display.DEFAULT_DISPLAY) {
Display display = dm.getRealDisplay(displayId, r.token);
baseContext = appContext.createDisplayContext(display);
break;
}
}
}
return baseContext;
}
}
createBaseContextForActivity()方法返回ContextImpl對象后,通過activity.attach()將ContextImpl對象與Activity關聯起來。
裝潢模式和代理模式的區分:
裝潢模式:以對客戶端透明的方式擴大對象的功能,是繼承關系的1個替換方案;
代理模式:給1個對象提供1個代理對象,并有代理對象來控制對原有對象的援用;
裝潢模式應當為所裝潢的對象增強功能;代理模式對代理的對象施加控制,其實不提供對象本身的增強功能。
2者的實現機制確切是1樣的,可以看到他們的實例代碼重復是很多的。但就語義上說,這二者的功能是相反的,模式的1個重要作用是簡化其他程序員對你程序的理解,
你在1個地方寫裝潢,大家就知道這是在增加功能,你寫代理,大家就知道是在限制,雖然代碼極可能相同,但如果你都叫他們裝潢,他人會很迷惑的。(轉)
未完待續,有不對的地方,請指正。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈