导引
例子1:
小明要租房,就去找中介,然后中介根据他的需求给他介绍房子。最终小明找到了想要租的房子,然后交钱给中介。
例子2:
校园代理。比如我大学所在的城市,有聚会别墅,会在各个学校选一个学生做代理,具体内容不知道干啥,大概打广告吧。
例子3:
想买迪奥的口红,你就得去迪奥专卖店买,而不是直接去生产迪奥的厂家去买。专卖店就是代理。
以上这些例子便可以引出一种设计模式——代理模式。
问题1:代理模式的定义
Proxy Pattern,对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
问题2: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中有哪些应用?!?
ActivityManagerProxy类(它是ActivityManagerNative的代理,它们都有一个共有的接口IActivityManager)
AIDL(Inter Process Communication,进程间通信)
问题8:AIDL用法
- 创建一个AIDL文件
interface ProxyAIDL {
void hasGirlFriend(String name);
}
注:参数类型
- 所有基础类型(int, char, 等)
- String,List,Map,CharSequence等类
- 其他AIDL接口类型
- 所有Parcelable的类
编译后会自动生成一个java接口
- 为远程服务实现对应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与模式》