Android與設(shè)計(jì)模式――裝飾者(Decorator)模式
來(lái)源:程序員人生 發(fā)布時(shí)間:2014-12-14 09:12:11 閱讀次數(shù):4986次
在閻宏博士的《JAVA與模式》1書(shū)中開(kāi)頭是這樣描寫(xiě)裝潢(Decorator)模式的:
裝潢模式又名包裝(Wrapper)模式。裝潢模式以對(duì)客戶端透明的方式擴(kuò)大對(duì)象的功能,是繼承關(guān)系的1個(gè)替換方案。
裝潢模式的結(jié)構(gòu)
裝潢模式以對(duì)客戶透明的方式動(dòng)態(tài)地給1個(gè)對(duì)象附加上更多的責(zé)任。換言之,客戶端其實(shí)不會(huì)覺(jué)得對(duì)象在裝潢前和裝潢后有甚么不同。裝潢模式可以在不使用創(chuàng)造更多子類(lèi)的情況下,將對(duì)象的功能加以擴(kuò)大。(上文來(lái)源于網(wǎng)絡(luò))
裝潢模式的類(lèi)圖以下:

在裝潢模式中的角色有:
● 抽象構(gòu)件(Context)角色:給出1個(gè)抽象接口,以規(guī)范準(zhǔn)備接收附加責(zé)任的對(duì)象。
● 具體構(gòu)件(ContextImpl)角色:定義1個(gè)將要接收附加責(zé)任的類(lèi)。
● 裝潢(ContextWrapper)角色:持有1個(gè)構(gòu)件(Component)對(duì)象的實(shí)例,并定義1個(gè)與抽象構(gòu)件接口1致的接口。
● 具體裝潢(Activity/Service/Application)角色:負(fù)責(zé)給構(gòu)件對(duì)象“貼上”附加的責(zé)任。
ContextImpl是抽象類(lèi)Context的具體實(shí)現(xiàn),ContextWrapper及所有其子類(lèi)對(duì)象持有的Context均是ContextImpl對(duì)象。以Activity的Context為例,Activity創(chuàng)建是在ActivityThread中,Activity創(chuàng)建時(shí):
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對(duì)象后,通過(guò)activity.attach()將ContextImpl對(duì)象與Activity關(guān)聯(lián)起來(lái)。
裝潢模式和代理模式的區(qū)分:
裝潢模式:以對(duì)客戶端透明的方式擴(kuò)大對(duì)象的功能,是繼承關(guān)系的1個(gè)替換方案;
代理模式:給1個(gè)對(duì)象提供1個(gè)代理對(duì)象,并有代理對(duì)象來(lái)控制對(duì)原有對(duì)象的援用;
裝潢模式應(yīng)當(dāng)為所裝潢的對(duì)象增強(qiáng)功能;代理模式對(duì)代理的對(duì)象施加控制,其實(shí)不提供對(duì)象本身的增強(qiáng)功能。
2者的實(shí)現(xiàn)機(jī)制確切是1樣的,可以看到他們的實(shí)例代碼重復(fù)是很多的。但就語(yǔ)義上說(shuō),這二者的功能是相反的,模式的1個(gè)重要作用是簡(jiǎn)化其他程序員對(duì)你程序的理解,
你在1個(gè)地方寫(xiě)裝潢,大家就知道這是在增加功能,你寫(xiě)代理,大家就知道是在限制,雖然代碼極可能相同,但如果你都叫他們裝潢,他人會(huì)很迷惑的。(轉(zhuǎn))
未完待續(xù),有不對(duì)的地方,請(qǐng)指正。
生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)