代理模式

导引


例子1:

小明要租房,就去找中介,然后中介根据他的需求给他介绍房子。最终小明找到了想要租的房子,然后交钱给中介。

例子2:

校园代理。比如我大学所在的城市,有聚会别墅,会在各个学校选一个学生做代理,具体内容不知道干啥,大概打广告吧。

例子3:

想买迪奥的口红,你就得去迪奥专卖店买,而不是直接去生产迪奥的厂家去买。专卖店就是代理。

以上这些例子便可以引出一种设计模式——代理模式。

问题1:代理模式的定义


Proxy Pattern,对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

问题2:UML图


代理模式UML图

问题3:代理模式有哪些角色?


抽象主题角色

声明代理主题和真实主题的共同接口

abstract class Subject {
    public abstract void request();
}

代理主题角色

  • 代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题的对象

  • 代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题

  • 控制对真实主题的引用,负责在需要的时候创建/删除真实主题对象

  • 代理角色通常在将客户端调用传递给真实主题前/后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象

public class ProxySubject extends Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        preRequest();
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();
        postRequest();
    }

    private void preRequest() {
        //something you want to do before request.
        System.out.println("before");
    }

    private void postRequest() {
        //something you want to do after request.
        System.out.println("after");
    }
}

真实主题角色

定义代理角色所代表的真实对象

public class RealSubject extends Subject {

    public RealSubject() {
    }

    @Override
    public void request() {
        System.out.println("From Real Subject");
    }
}

测试

public class ProxyTest {

    public static void main(String[] args) {
        Subject subject = new ProxySubject();
        subject.request();
    }
}

问题4:代理模式顺序图


代理模式顺序图

问题5:代理模式种类以及优缺点


  • 远程代理

优点:系统可以将网络细节隐藏起来,使得客户端不必考虑网络的存在。

缺点:代理对象承担了大部分的网络通信工作,由于客户可能没有意识到会启动一个耗费时间的远程调用,因此,客户没有必要的思想准备。

  • 虚拟代理

优点:代理对象可以在必要的时候才将被代理的对象加载。代理可以对加载的过程加以必要的优化。

  • 智能引用代理

优点:在访问一个对象是可以执行一些业务处理操作。

  • Copy-on-Write代理

优点:在对数据进行修改的时候,不会直接在原来的数据位置上进行操作,而是重新找个位置修改,保证数据的完整性,这样的好处是一旦系统突然断电,重启之后不需要做Fsck。

缺点:内存占用问题,数据一致性问题。

  • 保护代理

优点:可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象

  • Cache代理

  • 防火墙代理

  • 同步化代理

问题6:注意!


代理模式可能并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口。这时,代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建,并传入。

问题7:在Android中有哪些应用?!?


  1. ActivityManagerProxy类(它是ActivityManagerNative的代理,它们都有一个共有的接口IActivityManager)

  2. AIDL(Inter Process Communication,进程间通信)

问题8:AIDL用法


  • 创建一个AIDL文件
interface ProxyAIDL {
    void hasGirlFriend(String name);
}

注:参数类型

  1. 所有基础类型(int, char, 等)
  2. String,List,Map,CharSequence等类
  3. 其他AIDL接口类型
  4. 所有Parcelable的类

编译后会自动生成一个java接口

AIDL接口类

  • 为远程服务实现对应aidl接口中的内部抽象类Stub(Stub类继承了Binder)(Service)
    public class ProxyService extends Service{

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBind;
    }

    public ProxyAIDL.Stub mBind = new ProxyAIDL.Stub() {

        @Override
        public void hasGirlFriend(String name) throws RemoteException {
            if (name == null) {
                Log.i("test", "oh! your don't have girlfriend!!!");
            } else {
                Log.i("test", "your girlfriend is " + name);
            }
        }
    };
}
  • 将服务“暴露”出去
public class ProxyActivity extends Activity {
    private ProxyAIDL proxyAIDL;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //绑定
            proxyAIDL = ProxyAIDL.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proxy);
        Intent intent = new Intent(this, ProxyService.class);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
        startService(intent);
    }

    public void hasGirlFriend(String name){
        try {
            proxyAIDL.hasGirlFriend(name);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}
//代码只贴了主要部分

这是我所用的比较简单的用法

PS:各位亲用的时候一定在AndroidManifest注册服务哟~(就我犯这种低级错误,出来一堆错误T_T)

ENDING


时间太紧,写得比较仓促,有什么错误欢迎指正^_^
参考书籍:《Java与模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值