Android 设计模式之代理模式

来源:互联网 发布:kyocera打印机驱动mac 编辑:程序博客网 时间:2024/06/03 21:53

原创文章,如有转载,请注明出处:http://blog.csdn.net/myth13141314/article/details/78254838


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

设计模式系列文章

  • Android 设计模式之面向对象的六大原则
  • Android 设计模式之Builder模式
  • Android 设计模式之观察者模式
  • Android 设计模式之单例模式
  • Android设计模式之装饰模式
  • Android 设计模式之外观模式
  • Android 设计模式之原型模式
  • Android 设计模式之工厂方法模式
  • Android 设计模式之策略模式
  • Android 设计模式之适配器模式
  • Android 设计模式之桥接模式
  • Android 设计模式之状态模式

今天我们要讲的是代理模式(委托模式)


定义

为其他对象提供一种代理以控制对这个对象得访问

使用场景

  • 当无法或不想直接访问某个对象或访问某个对象存在困难时,可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口

使用例子

  • Android源码中的ActivityManagerProxy代理ActivityManagerService类

实现

三大角色

  • 抽象主题类:声明真实主题与代理的共同接口方法,该类既可以是一个抽象类也可以是一个接口
  • 真实主题类:也称为被委托类或被代理类,该类定义了代理所表示的真实对象,由其执行具体的业务逻辑
  • 代理类:也称为委托类或代理类,该类持有一个对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行

实现的要点

  • 代理模式从实现上分为静态代理和动态代理,这里我们主要关注静态代理
  • 代理类和被代理类都要继承或实现相同的接口或方法
  • 代理类通过被代理类的引用来调用具体的业务逻辑

实现方式

这里我们主要通过适配不同API版本下发送消息Notification来应用代理模式

抽象主题类

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();}
  • 初始化了子类都会用到的NotificationManager和Builder
  • 定义了2个公共的方法:send方法和cancel方法

真实主题类(被代理类)

  • 常规的通知的构建
public class NotifyNormal extends Notify {    public NotifyNormal(Context context) {        super(context);    }    @Override    public void send() {        builder.setContent(new RemoteViews(context.getPackageName(), R.layout.layout_notify_normal));        Notification notification = builder.build();        notificationManager.notify(0, notification);    }    @Override    public void cancel() {        notificationManager.cancel(0);    }}
  • 大视图的通知的构建
public class NotifyBig extends Notify {    public NotifyBig (Context context) {        super(context);    }    @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));        Notification notification = builder.build();        notificationManager.notify(0, notification);    }    @Override    public void cancel() {        notificationManager.cancel(0);    }}
  • 浮动展示的通知的构建
public class NotifyHeadersUp extends Notify {    public NotifyHeadersUp (Context context) {        super(context);    }    @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));        Notification notification = builder.build();        notificationManager.notify(0, notification);    }    @Override    public void cancel() {        notificationManager.cancel(0);    }}

代理类

public class NotifyProxy extends Notify {    private Notify notify;    public NotifyProxy (Context context) {        super(context);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            notify = new NotifyHeadersUp(context);        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {            notify = new NotifyBig(context);        } else {            notify = new NotifyNormal(context);        }    }    @Override    public void send() {        notify.send();    }    @Override    public void cancel() {        notify.cancel();    }}

调用

new NotifyProxy(MainActivity.this).send();
  • 可见接口很简洁,通过代理模式,我们把复杂的判断和生成通知的逻辑都屏蔽了,这样代码更加清晰

补充

  • 不知道大家看了上面的示例代码有什么想法?有没有可以优化的地方呢?
  • 上面的示例中,3个Notify的子类中有很多重复的代码,有没有什么方法能进一步优化呢?

总结

  • 代理模式应用广泛,会经常和其他设计模式结合使用
  • 代理模式是细分化至很小的一种设计模式,几乎没有缺点

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

原创粉丝点击