修饰者模式—大话设计模式笔记

2019-01-04  本文已影响17人  粉色小猫与蓝色小妖

1.装饰者模式介绍

装饰者模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

2.代码结构

装饰者模式结构图.jpg

3.代码基本实现

Component定义一个对象接口,可以给这些对象动态地添加职责

public interface Component {
    public abstract void operation();

}

ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责

public class ConcreteComponent implements Component{

    @Override
    public void operation() {
        System.out.println("ConcreteComponent operation()");
    }
    

}

Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,对于Component来说,是无需知道Decorator的存在

public abstract class Decorator implements Component{

    private Component mComponent;
    @Override
    public void operation() {
        if(mComponent != null) {
            mComponent.operation();
        }
    }
    
    protected void setComponent(Component cn) {
        this.mComponent = cn;
    }   

}

ConcreteDecorator 就是具体的装饰对象,起到给Component添加职责功能

public class ConcreteDecoratorA extends Decorator{

    @Override
    public void operation() {
        super.operation();//先运行原Component的operation(),再执行本类的功能,相当于对原Component进行了装饰
        addedBehavior();
    }
    
    private void addedBehavior() {
        System.out.println(" addedBehavior()");
    }

}
public class ConcreteDecoratorB extends Decorator{

    private String addedState;
    @Override
    public void operation() {
        // TODO Auto-generated method stub
        super.operation();
        System.out.println("addedState!!");
    }
    

}

public class Main {

    public static void main(String[] args) {
        ConcreteComponent c = new ConcreteComponent();
        ConcreteDecoratorA d1 = new ConcreteDecoratorA();
        ConcreteDecoratorB d2 = new ConcreteDecoratorB();
        d1.setComponent(c);
        d2.setComponent(c);
        
        d1.operation();
        d2.operation();
    }
}

4.适用场景

当系统需要新的功能的时候,是向旧的类增加新的代码。这些新加的代码通常装饰了原有类的核心职责或者主要行为。在主类中增加了新的字段、新的方法和新的逻辑,从而增加了主类的复杂度;而这些新加入的东西仅仅是为了满足一些只有在某种特定情况下才会执行的特殊行为的需要。而装饰者模式提供了一个非常好的解决方案,它把每一个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象,这样,客户代码就可以在运行时根据需要有选择地、按顺序地是有装饰功能包装对象。

5.优点

有效的把类的核心职责和装饰功能分开,而且可以去除相关类中重复的装饰逻辑

6.修饰者模式在Android中应用—Context抽象类

代码结构:

Context.jpg

Context相当于Component,
ContextImpl相当于ConcreteComponent,
ContextWrapper 相当于Decorator.
Activity、Service、Application相当于具体的ConcreteDecorator

Context
Context是一个抽象类,提供了一系列的抽象方法。

ContextImpl
Context的基本实现,给Activity和其他应用组件提供了context 对象。
ContextWrapper 当中的成员mBase context。
看其中几个实现和提供创建Context的方法:

    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null);
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));
        return context;
    }

    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null);
    }

    static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, IBinder activityToken) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        if (activityToken == null) throw new IllegalArgumentException("activityInfo");
        return new ContextImpl(null, mainThread,
                packageInfo, activityToken, null, false, null, null);
    }
    @Override
    public ContentResolver getContentResolver() {
        return mContentResolver;
    }

    @Override
    public Looper getMainLooper() {
        return mMainThread.getLooper();
    }

    @Override
    public Context getApplicationContext() {
        return (mPackageInfo != null) ?
                mPackageInfo.getApplication() : mMainThread.getApplication();
    }

ContextWrapper
ContextWrapper继承Context,对方法的几个实现:
mBase 指向的是ContextIml对象。

    public Resources getResources() {
        return mBase.getResources();
    }

    @Override
    public PackageManager getPackageManager() {
        return mBase.getPackageManager();
    }

    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }
上一篇下一篇

猜你喜欢

热点阅读