意图:
为其他对象提供一种代理以控制对这个对象的访问.
适用性:
1.远程代理:为一个对象在不同的地址空间提供局部代表.
2.虚代理:根据需要创建开销很大的对象.
3.保护代理:控制对原始对象的访问.
4.智能指引:取代了简单的指针,他在访问对象时执行一些附加操作.
效果:
Proxy模式在访问对象时引入了一定程度的间接性.根据代理类型,附加的间接性有多种用途:
1.Remote Proxy 可以隐藏一个对象存在于不同地址空间的事实.
2.Virtual Proxy 可以进行最优化,例如根据要求创建对象.
3.Protection Proxies 和 Smart Reference 都允许在访问一个对象时有一些附加的内务处理.
代码实现:
主要实现了三种模式:虚代理,保护代理,智能指引.
虚代理:
package com.git.books.b_design_patterns.l_proxy.a;
/**
* @Description: 图片代理接口类
* @author: songqinghu
* @date: 2017年3月8日 下午4:38:02
* Version:1.0
*/
public interface ImageProxy {
/**
* @描述:展示图片
* @createTime:2017年3月8日
* @author: songqinghu
*/
public void showImage();
}
package com.git.books.b_design_patterns.l_proxy.a;
/**
* @Description: 图片虚拟代理
* @author: songqinghu
* @date: 2017年3月8日 下午4:31:24
* Version:1.0
*/
public class VirtualImageProxy implements ImageProxy{
private int height = 100;
private int width = 200;
@Override
public void showImage() {
Image image = new Image();
image.showImage();
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
}
package com.git.books.b_design_patterns.l_proxy.a;
public class Image implements ImageProxy {
@Override
public void showImage() {
try {
System.out.println("start load image ! ");
Thread.sleep(1000);
System.out.println("end load iamge !");
} catch (Exception e) {
System.out.println("load image occor error !");
}
}
}
package com.git.books.b_design_patterns.l_proxy.a;
/**
* @Description: 测试客户端 加载时间过久,等到需要时候再进行加载
* @author: songqinghu
* @date: 2017年3月8日 下午5:35:23
* Version:1.0
*/
public class VirtualClient {
public static void main(String[] args) {
VirtualImageProxy proxy = new VirtualImageProxy();
System.out.println(proxy.getHeight());
proxy.showImage();
}
}
保护代理:
package com.git.books.b_design_patterns.l_proxy.b;
/**
* @Description: 保护代理 账号信息顶级接口
* @author: songqinghu
* @date: 2017年3月8日 下午5:38:36
* Version:1.0
*/
public interface AccountInfoProxy {
/**
* @描述:展示指定的用户信息
* @param userId
* @return void
* @createTime:2017年3月8日
* @author: songqinghu
*/
public void showUserInfo(String userId);
}
package com.git.books.b_design_patterns.l_proxy.b;
/**
* @Description: 保护代理用户交互代理类 用来完成验证保护工作及代理转发
* @author: songqinghu
* @date: 2017年3月8日 下午5:44:25
* Version:1.0
*/
public class ProtectionAccountInfoProxy implements AccountInfoProxy {
private AccountInfoProxy accountInfo;
public ProtectionAccountInfoProxy(AccountInfoProxy accountInfo) {
this.accountInfo = accountInfo;
}
@Override
public void showUserInfo(String userId) {
if(UserInfoCheck.getInstance().check(userId)){
accountInfo.showUserInfo(userId);
}else{
System.out.println("You do not have access rights!");
}
}
}
class UserInfoCheck{
private UserInfoCheck() {
//write some thing
}
//内部类单例
private static class AccountInner{
private static UserInfoCheck check = new UserInfoCheck();
}
public static UserInfoCheck getInstance(){
return AccountInner.check;
}
public boolean check(String userId){
if(UserToken.Admin.toString().equals(userId)){
return true;
}else{
return false;
}
}
}
enum UserToken{
Admin,ReadOnly,Tourist
}
package com.git.books.b_design_patterns.l_proxy.b;
public class AccountInfo implements AccountInfoProxy {
@Override
public void showUserInfo(String userId) {
System.out.println("the user name is :xxx and The amount of the account is $100000 ");
}
}
package com.git.books.b_design_patterns.l_proxy.b;
/**
* @Description: 保护代理测试类
* @author: songqinghu
* @date: 2017年3月8日 下午5:58:16
* Version:1.0
*/
public class ProtectionClient {
public static void main(String[] args) {
ProtectionAccountInfoProxy proxy = new ProtectionAccountInfoProxy(new AccountInfo());
proxy.showUserInfo("Admin");
proxy.showUserInfo("ReadOnly");
}
}
智能指引:
package com.git.books.b_design_patterns.l_proxy.c;
/**
* @Description:智能指引代理模式 顶级接口 有效访问 计数器加一
* @author: songqinghu
* @date: 2017年3月8日 下午6:13:12
* Version:1.0
*/
public interface AccessTimes {
public void access();
}
package com.git.books.b_design_patterns.l_proxy.c;
public class SmartReferenceAccessTimesProxy implements AccessTimes {
private AccessTimesProxy proxy;
public SmartReferenceAccessTimesProxy(AccessTimesProxy proxy) {
this.proxy = proxy;
}
@Override
public void access() {
proxy.access();
AccessCount.getInstance().add();
}
}
//访问计数器
class AccessCount{
private long countNum=0;
private AccessCount() {
//write some thing
}
//内部类单例
private static class AccessInner{
private static AccessCount count = new AccessCount();
}
public static AccessCount getInstance(){
return AccessInner.count;
}
public void add(){
countNum++;
}
public long getCountNum(){
return countNum;
}
}
package com.git.books.b_design_patterns.l_proxy.c;
/**
* @Description: 具体类
* @author: songqinghu
* @date: 2017年3月8日 下午6:18:58
* Version:1.0
*/
public class AccessTimesProxy implements AccessTimes {
@Override
public void access() {
System.out.println("your access the bloging");
}
}
package com.git.books.b_design_patterns.l_proxy.c;
/**
* @Description: 智能指引测试类
* @author: songqinghu
* @date: 2017年3月8日 下午6:28:21
* Version:1.0
*/
public class SmartReferenceClient {
public static void main(String[] args) {
AccessTimes proxy = new SmartReferenceAccessTimesProxy(new AccessTimesProxy());
proxy.access();
proxy.access();
proxy.access();
proxy.access();
proxy.access();
System.out.println("访问次数: "+AccessCount.getInstance().getCountNum());
}
}
结构图:
重点:
掌握动态代理及几种模式,区分其和适配器,装饰者区别
参考:
<<设计模式>>
<<Java与模式>>
转载请注明原文地址: https://ju.6miu.com/read-5205.html