代理模式——虚拟代理(二)

举报
yd_221104950 发表于 2020/12/02 23:22:00 2020/12/02
【摘要】 代理模式定义 为另一个对象提供一个替身或占位符以控制对这个对象的访问。使用代理模式创建代表对象,让代表对象控制对某对象的访问,被代理的对象可是远程的对象、创建开销大的对象或需要安全控制的对象。 代理分三种: 1.远程代理,帮助我们控制访问远程对象: 远程代理可以作为另一个JVM上对象的本地代表。调用代理的方法,会被代理利用网络转发到远程执行,并且结果会通过网络返回给...

代理模式定义
为另一个对象提供一个替身或占位符以控制对这个对象的访问。使用代理模式创建代表对象,让代表对象控制对某对象的访问,被代理的对象可是远程的对象、创建开销大的对象或需要安全控制的对象。

代理分三种:

1.远程代理,帮助我们控制访问远程对象:
远程代理可以作为另一个JVM上对象的本地代表。调用代理的方法,会被代理利用网络转发到远程执行,并且结果会通过网络返回给代理,再由代理将结果转给客户。
2.虚拟代理,帮助我们控制访问创建开销大的资源
虚拟代理作为创建开销大的对象的代表,经常会直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时,由虚拟代理地来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。
3.保护代理,基于权限控制对资源的访问。

本篇讲一讲虚拟代理:
虚拟代理用于隐藏开销大的对象,如我们需要通过网络取得图像数据。
在这里插入图片描述
ImageProxy的工作过程:

  1. ImageProxy首先创建一个ImageIcon,然后开始从网络URL上加载图像
  2. 在加载过程中,ImageProxy显示占位图
  3. 当图像加载完毕,ImageProxy把所有方法调用都委托给真正的ImageIcon,这些方法包括getIconHeight()、getIconWidth()、paintIcon()。
  4. 如果用户请求请的图像,我们就创建新的代理,重复这样的过程。

Icon接口:

public interface Icon { int getIconWidth(); int getIconHeight(); void paintIcon(ImageView imageView);
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

ImageProxy代码:

public class ImageProxy implements Icon { ImageIcon imageIcon; //这是加载后显示出来的真正图像 URL imageURL;  //真正图像的URL Thread retrievalThread; boolean retrieving = false; Bitmap bitmap;//占位图 ImageView imageView;显示图片的容器 private Handler refresh = new Handler(){ @Override public void handleMessage(Message msg) { ImageProxy.this.paintIcon(imageView); } }; public ImageProxy(URL url,Bitmap bitmap){ this.imageURL = url; this.bitmap = bitmap; } @Override public int getIconWidth() { if(imageIcon != null){ return imageIcon.getIconWidth(); }else{ return 800; } } @Override public int getIconHeight() { if(imageIcon != null){ return imageIcon.getIconHeight(); }else{ return 600; } } @Override public void paintIcon(ImageView imageView) { this.imageView = imageView; if(imageIcon != null){ imageIcon.paintIcon(imageView); }else{ imageView.setImageBitmap(bitmap); if(!retrieving){ retrieving = true; retrievalThread = new Thread(new Runnable() { @Override public void run() { if(imageURL != null){ try { HttpURLConnection conn = (HttpURLConnection) imageURL.openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); Bitmap bitmap1 = BitmapFactory.decodeStream(is); imageIcon = new ImageIcon(bitmap1); is.close(); refresh.sendEmptyMessage(1); //图像加载完成后,自动刷新 }catch (Exception e){ e.printStackTrace(); } } } }); retrievalThread.start(); } } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

ImageIcon代码:

public class ImageIcon implements Icon { Bitmap bitmap; public ImageIcon(Bitmap bitmap) { this.bitmap = bitmap; } @Override public int getIconWidth() { if (bitmap != null) { return bitmap.getWidth(); } return 0; } @Override public int getIconHeight() { if (bitmap != null) { return bitmap.getHeight(); } return 0; } @Override public void paintIcon(ImageView imageView) { if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

ImageProxy控制ImageIcon的访问。代理将客户从ImageIcon解耦了,如果它们之间没有解耦,客户就必须等到每幅图像都被取回,然后才能把它绘制到界面上。

代理模式有很多变体,这些变体都有一个共通点:都会将客户对主题(subject)施加的方法调用拦截下来。这种间接的级别让我们可以做很多事,包括将请求分发到远程主题;给创建开销大的对象提供代表;提供某些级别的保护,这种保护能决定哪些客户能调用哪些方法

这里要与装饰者区分开,装饰者为对象增加行为,而代理是控制对象的访问。

最后分享Demo代码

谢谢阅读!有兴趣可以前往《代理模式——保护代理(三)》进行阅读。

文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_40763897/article/details/88661822

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。