裝飾模式(Decorator Pattern)也被稱爲包裝模式(Wrapper Pattern),是結構型設計模式之一,能夠在不改變一個對象自己功能的基礎上給對象增長額外的新行爲,以對客戶端透明的方式來動態擴展對象的功能(注意,並非改變對象本質),同時也是一種很好的替代繼承關係的方案。在現實生活中也能夠看到不少裝飾模式的例子。java
穿衣服是使用裝飾的一個例子。 以爲冷時, 你能夠穿一件毛衣。 若是穿毛衣還以爲冷, 你能夠再套上一件夾克。 若是遇到下雨, 你還能夠再穿一件雨衣。 全部這些衣物都 「擴展」 了你的基本行爲, 但它們並非你的一部分, 若是你再也不須要某件衣物, 能夠方便地隨時脫掉。編程
人老是要穿衣服的,將人定義爲抽象類,穿衣服的行爲定義爲一個抽象方法:設計模式
/** * 須要被裝飾類的基類 */
public abstract class Person {
public abstract void dressed();
}
/** * 具體須要被裝飾的"對象" */
public class Boy extends Person {
@Override
public void dressed(){
System.out.println("穿了內衣");
}
}
複製代碼
Boy 類繼承自 Person,該類僅對 Person 中的 dressed 方法做了具體實現,Boy 類則是咱們所要裝飾的具體「對象」,如今須要一個裝飾者來裝飾 Boy 對象。app
/** * 裝飾器基類 */
public abstract class PersonCloth extends Person {
protected Person mPerson;// 保持一個對 Person 對象的引用
public PersonCloth(Person mPerson) {
this.mPerson = mPerson;
}
@Override
public void dressed(){
mPerson.dressed();
}
}
/** * 裝飾器一 */
public class ExpensiveCloth extends PersonCloth {
public ExpensiveCloth(Person person) {
super(person);
}
@Override
public void dressed(){
super.dressed();
dressLeather();
dressJean();
}
private void dressLeather() {
System.out.println("穿件皮衣");
}
private void dressJean() {
System.out.println("穿條牛仔褲");
}
}
/** * 裝飾器二 */
public class CheapCloth extends PersonCloth {
public CheapCloth(Person person) {
super(person);
}
@Override
public void dressed(){
super.dressed();
dressShorts();
}
private void dressShorts() {
System.out.println("穿條短褲");
}
}
複製代碼
客戶端調用:編程語言
public class Client {
public static void main(String[] args) {
Person person = new Boy();
PersonCloth clothCheap = new CheapCloth(person);
// clothCheap.dressed();
PersonCloth clothExpensive = new ExpensiveCloth(clothCheap);
// PersonCloth clothExpensive = new ExpensiveCloth(new CheapCloth(person));
clothExpensive.dressed();
}
}
複製代碼
輸出:ide
穿了內褲
穿條短褲
穿件皮衣
穿條牛仔褲
複製代碼
組合模式this
責任鏈模式spa
策略模式設計
「在一個真正的裝飾模式中,每個裝飾者都不容許修改被裝飾對象的行爲,只能擴展其功能。從代碼的角度講,每個裝飾者在重寫的某個方法中都要直接或間接調用到被裝飾對象的實現方法,不然不能稱之爲裝飾模式。」code
Android 中 Context、Contextwrapper、Activity 等結構就使用了裝飾模式
/** * Interface to global information about an application environment. This is * an abstract class whose implementation is provided by the Android system. * ... */
public abstract class Context {
public abstract Resources getResources();
...
}
/** * Common implementation of Context API, which provides the base * context object for Activity and other application components. */
class ContextImpl extends Context {
@Override
public Resources getResources() {
return mResources;
}
...
}
/** * ... Can be subclassed to modify behavior without changing * the original Context. */
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
@Override
public Resources getResources() {
return mBase.getResources();
}
...
}
/** * A context wrapper that allows you to modify or replace the theme of the * wrapped context. */
public class ContextThemeWrapper extends ContextWrapper {
private int mThemeResource;
private Resources.Theme mTheme;
private LayoutInflater mInflater;
private Configuration mOverrideConfiguration;
private Resources mResources;
@Override
public Resources getResources() {
if (mResources == null) {
if (mOverrideConfiguration == null) {
mResources = super.getResources();
} else {
final Context resContext = createConfigurationContext(mOverrideConfiguration);
mResources = resContext.getResources();
}
}
return mResources;
}
}
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory2, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks2, Window.OnWindowDismissedCallback, WindowControllerCallback, AutofillManager.AutofillClient {
...
}
複製代碼
Article by Panxc