Android开发经验谈Android开发Android技术知识

Android 设计模式之装饰模式

2017-10-17  本文已影响409人  AntDream

在日常开发过程中时常需要用到设计模式,但是设计模式有23种,如何将这些设计模式了然于胸并且能在实际开发过程中应用得得心应手呢?和我一起跟着《Android源码设计模式解析与实战》一书边学边应用吧!

设计模式系列文章

今天我们要讲的是装饰模式(包装模式)


定义

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

使用场景

使用例子


实现

四大角色

实现的要点

实现方式

首先先熟悉下装饰模式的概念

public class DecoratorActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);        
        initData();        
        initView();        
    }
    
    private void initData() {
        //初始化数据
    }
    
    private void initView() {
        //初始化页面
    }
}

下面我们以对在代理模式一文中的示例代码进行改造来简单应用装饰模式

首先抽象主题类Notify类不变
public abstract class Notify {

    protected Context context;
    protected NotificationManager notificationManager;
    protected NotificationCompat.Builder builder;

    public Notify(Context context) {
        this.context = context;
        notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        builder = new NotificationCompat.Builder(context);
        builder.setSmallIcon(R.drawable.ic_launcher)
                .setContentIntent(PendingIntent.getActivity(context, 0,
                        new Intent(context, NotifyActivity.class),
                        PendingIntent.FLAG_UPDATE_CURRENT));
    }

    /**
     * 发送一条通知
     */
    public abstract void send();

    /**
     * 取消一条通知
     */
    public abstract void cancel();
}
被代理类(这里是被装饰类)NotifyNormal要稍微变动下
public class NotifyNormal extends Notify {

    public NotifyNormal(Context context) {
        super(context);
    }

    @Override
    public void send() {
        Notification notification = builder.build();
        notificationManager.notify(0, notification);
    }

    @Override
    public void cancel() {
        notificationManager.cancel(0);
    }
}

接下来是抽象装饰者

public abstract class NotifyDecorator extends Notify {
    private Notify notify;

    public NotifyDecorator (Context context, Notify mNotify) {
        super(context);
        this.notify = mNotify;
    }

    @Override
    public void send() {
        notify.send();
    }

    @Override
    public void cancel() {
        notify.cancel();
    }
}
具体的装饰者,原来分别有NotifyNormal、NotifyBig、NotifyHeadersUp,这里对应三个具体的装饰者
public class NotifyNormalDecorator extends NotifyDecorator {

    public NotifyNormalDecorator (Context context, Notify notify) {
        super(context, notify);
    }

    @Override
    public void send() {
        builder.setContent(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        super.send();
    }
}
public class NotifyBigDecorator extends NotifyDecorator {

    public NotifyBigDecorator(Context context, Notify notify) {
        super(context, notify);
    }

    @Override
    public void send() {
        builder.setContent(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        builder.setCustomBigContentView(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        super.send();
    }
}
public class NotifyHeadsUpDecorator extends NotifyDecorator {

    public NotifyHeadsUpDecorator(Context context, Notify notify) {
        super(context, notify);
    }

    @Override
    public void send() {
        builder.setContent(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        builder.setCustomBigContentView(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        builder.setCustomHeadsUpContentView(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));
        super.send();
    }
}
以上都是在被装饰对象NotifyNormal的基础上增加或更改了通知的布局

代理类NotifyProxy也要相应的做修改

public class NotifyProxy extends Notify{
    private NotifyDecorator notifyDecorator;

    public NotifyProxy (Context context) {
        super(context);

        Notify notify = new NotifyNormal(context);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            notifyDecorator = new NotifyHeadsUpDecorator(context, notify);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            notifyDecorator = new NotifyBigDecorator(context, notify);
        } else {
            notifyDecorator = new NotifyNormalDecorator(context, notify);
        }
    }

    @Override
    public void send() {
        notifyDecorator.send();
    }

    @Override
    public void cancel() {
        notifyDecorator.cancel();
    }
}

调用的入口依然没变

new NotifyProxy(MainActivity.this).send();

总结

装饰模式和代理模式的区别

源码地址:https://github.com/snowdream1314/DesignPatternsExamples


欢迎关注我的微信公众号,期待与你一起学习,一起交流,一起成长!


AntDream
上一篇 下一篇

猜你喜欢

热点阅读