设计模式学习——代理模式(Proxy Pattern)
概述
代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理、远程代理、虚拟代理、缓冲代理等,它们应用于不同的场合,满足用户的不同需求。
远程代理(Remote Proxy)
给一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
虚拟代理(Virtual Proxy)
如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
保护代理(Protect Proxy)
控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
缓冲代理(Cache Proxy)
为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
智能引用代理(Smart Reference Proxy)
当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。

简单理解:
代理模式是在不更改原功能、原代码的前提下,对被代理目标进行拓展。这样做的好处在于侵入性低,拓展性强。原目标不会有任何改变,避免出现修了水管破了顶的情况。
例子
用一个简单的理解来理解代理模式,Android中常用的点击事件,经常我们需要处理短时间重复点击以及请求状态中禁止重复请求的操作。我们可以写一个Proxy动态代理OnClickListener。
package com.wusy.adv;
import android.content.Context;
import android.view.View;
import android.widget.Toast;
/**
* Created by XIAO RONG on 2018/10/24.
*/
public class ClickProxy implements View.OnClickListener{
private static boolean isStartLoadingClick=false;
private static boolean isStartSingleClick=false;
private View.OnClickListener onClickListener;
private Context mC;
private long lastClickTime=0;
private long times=1000;
private boolean isLoading=false;
public ClickProxy(View.OnClickListener onClickListener, Context context){
this.onClickListener=onClickListener;
this.mC=context;
}
@Override
public void onClick(View v) {
if (isStartLoadingClick){
if(isLoading){
Toast.makeText(mC,"正在加载,请稍后",Toast.LENGTH_SHORT).show();
return;
}else{
isLoading=true;
}
}
if(isStartSingleClick){
if (System.currentTimeMillis() - lastClickTime >= times) {
lastClickTime = System.currentTimeMillis();
}else{
Toast.makeText(mC,"您点得太快了",Toast.LENGTH_SHORT).show();
return;
}
}
onClickListener.onClick(v);
}
public void setLoading(boolean loading) {
isLoading = loading;
}
}
使用起来也非常简单,因为我们再Proxy中打印了Toast所以需要传入Context,同时需要判断是否正在处于加载中,所以提取了Proxy的对象。否则使用方式和普通的OnclickListener使用没有差别。
private Button button;
private ClickProxy clickProxy;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_proxy);
button=findViewById(R.id.button);
clickProxy=new ClickProxy(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(TextActivity.this,"点了button",Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
clickProxy.setLoading(false);
}
},500);
}
},this);
button.setOnClickListener(clickProxy);
}
参考文章
https://www.jianshu.com/p/d98e22c127ed
https://blog.csdn.net/yanbober/article/details/45480965