代理模式(学习笔记)

  1. 意图

  提供对象的替代品或其占位符。代理控制着对于原对象的访问,允许在将请求提交给对象前后进行一些处理

  2. 动机

   在面向对象的系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问对象会给使用者或者系统结构带来很多麻烦      

  3. 适用性

  • 延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可使用代理模式
  • 访问控制(保护代理)。如果只希望特定客户端使用服务对象,这里的对象可以是操作系统中非常重要的部分,而客户端则是各种已启动的程序(包括恶意程序),此时可使用代理模式
  • 本地执行远程服务 (远程代理)。适用于服务对象位于远程服务器上的情形。代理通过网络传递客户端请求,负责处理所有与网络相关的复杂细节
  • 记录日志请求(日志记录代理)。适用于当你需要保存对于服务对象的请求历史记录时。代理可以在向服务传递请求前进行记录
  • 缓存请求结果 (缓存代理)。适用于需要缓存客户请求结果并对缓存生命周期进行管理时,特别是当返回结果的体积非常大时。代理可对重复请求所需的相同结果进行缓存,还可使用请求参数作为索引缓存的键值
  • 智能引用。可在没有客户端使用某个重量级对象时立即销毁该对象。

  代理会将所有获取了指向服务对象或其结果的客户端记录在案。代理会时不时地遍历各个客户端,检查它们是否仍在运行。如果相应的客户端列表为空,代理就会销毁该服务对象,释放底层系统资源。代理还可以记录客户端是否修改了服务对象。其他客户端还可以复用未修改的对象

  4. 结构

  

  5. 效果

  1)可以在客户端毫无察觉的情况下控制服务对象

  2)客户端对服务对象的生命周期没有特殊要求, 你可以对生命周期进行管理

  3)开闭原则。 你可以在不对服务或客户端做出修改的情况下创建新代理

  4)Proxy模式可以对用户隐藏另一种称为copy-on-write的优化方式,该优化与根据需要创建对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果这个拷贝并没有被修改,那么开销就没有必要。可以用代理延迟这一拷贝过程。在实现copy-on-write时必须对实体进行引用计数。只有当用户请求一个修改该实体的操作时,代理才会真正的拷贝它。此时,代理需要减少实体引用计数,当引用数目为零时,这个实体将被删除

  5)服务响应可能会延迟  

  6. 代码实现

   some_cool_media_library/ThirdPartyYouTubeLib.java: 远程服务接口  

package proxy.some_cool_media_library;import java.util.HashMap;/** * @author GaoMing * @date 2021/7/20 - 19:25 */public interface ThirdPartyYouTubeLib { HashMap<String, Video> popularVideos(); Video getVideo(String videoId);}

  some_cool_media_library/ThirdPartyYouTubeClass.java: 远程服务实现

package proxy.some_cool_media_library;import java.util.HashMap;/** * @author GaoMing * @date 2021/7/20 - 19:22 */public class ThirdPartyYouTubeClass implements ThirdPartyYouTubeLib{ @Override public HashMap<String, Video> popularVideos() {  connectToServer("http://www.youtube.com");  return getRandomVideos(); } @Override public Video getVideo(String videoId) {  connectToServer("http://www.youtube.com/" + videoId);  return getSomeVideo(videoId); } // ----------------------------------------------------------------------- // Fake methods to simulate network activity. They as slow as a real life. private int random(int min, int max) {  return min + (int) (Math.random() * ((max - min) + 1)); } private void experienceNetworkLatency() {  int randomLatency = random(5, 10);  for (int i = 0; i < randomLatency; i++) {   try {    Thread.sleep(100);   } catch (InterruptedException ex) {    ex.printStackTrace();   }  } } private void connectToServer(String server) {  System.out.print("Connecting to " + server + "... ");  experienceNetworkLatency();  System.out.print("Connected!" + "\n"); } private HashMap<String, Video> getRandomVideos() {  System.out.print("Downloading populars... ");  experienceNetworkLatency();  HashMap<String, Video> hmap = new HashMap<String, Video>();  hmap.put("catzzzzzzzzz", new Video("sadgahasgdas", "Catzzzz.avi"));  hmap.put("mkafksangasj", new Video("mkafksangasj", "Dog play with ball.mp4"));  hmap.put("dancesvideoo", new Video("asdfas3ffasd", "Dancing video.mpq"));  hmap.put("dlsdk5jfslaf", new Video("dlsdk5jfslaf", "Barcelona vs RealM.mov"));  hmap.put("3sdfgsd1j333", new Video("3sdfgsd1j333", "Programing lesson#1.avi"));  System.out.print("Done!" + "\n");  return hmap; } private Video getSomeVideo(String videoId) {  System.out.print("Downloading video... ");  experienceNetworkLatency();  Video video = new Video(videoId, "Some video title");  System.out.print("Done!" + "\n");  return video; }}

  some_cool_media_library/Video.java: 视频文件

package proxy.some_cool_media_library;/** * @author GaoMing * @date 2021/7/20 - 19:22 */public class Video { public String id; public String title; public String data; Video(String id, String title) {  this.id = id;  this.title = title;  this.data = "Random video."; }}

  proxy/YouTubeCacheProxy.java: 缓存代理

package proxy.proxy;import proxy.some_cool_media_library.ThirdPartyYouTubeClass;import proxy.some_cool_media_library.ThirdPartyYouTubeLib;import proxy.some_cool_media_library.Video;import java.util.HashMap;/** * @author GaoMing * @date 2021/7/20 - 19:23 */public class YouTubeCacheProxy implements ThirdPartyYouTubeLib{ private ThirdPartyYouTubeLib youtubeService; private HashMap<String, Video> cachePopular = new HashMap<String, Video>(); private HashMap<String, Video> cacheAll = new HashMap<String, Video>(); public YouTubeCacheProxy() {  this.youtubeService = new ThirdPartyYouTubeClass(); } @Override public HashMap<String, Video> popularVideos() {  if (cachePopular.isEmpty()) {   cachePopular = youtubeService.popularVideos();  } else {   System.out.println("Retrieved list from cache.");  }  return cachePopular; } @Override public Video getVideo(String videoId) {  Video video = cacheAll.get(videoId);  if (video == null) {   video = youtubeService.getVideo(videoId);   cacheAll.put(videoId, video);  } else {   System.out.println("Retrieved video '" + videoId + "' from cache.");  }  return video; } public void reset() {  cachePopular.clear();  cacheAll.clear(); }}

  downloader/YouTubeDownloader.java: 媒体下载应用

package proxy.downloader;import proxy.some_cool_media_library.ThirdPartyYouTubeLib;import proxy.some_cool_media_library.Video;import java.util.HashMap;/** * @author GaoMing * @date 2021/7/20 - 19:23 */public class YouTubeDownloader { private ThirdPartyYouTubeLib api; public YouTubeDownloader(ThirdPartyYouTubeLib api) {  this.api = api; } public void renderVideoPage(String videoId) {  Video video = api.getVideo(videoId);  System.out.println("\n-------------------------------");  System.out.println("Video page (imagine fancy HTML)");  System.out.println("ID: " + video.id);  System.out.println("Title: " + video.title);  System.out.println("Video: " + video.data);  System.out.println("-------------------------------\n"); } public void renderPopularVideos() {  HashMap<String, Video> list = api.popularVideos();  System.out.println("\n-------------------------------");  System.out.println("Most popular videos on YouTube (imagine fancy HTML)");  for (Video video : list.values()) {   System.out.println("ID: " + video.id + " / Title: " + video.title);  }  System.out.println("-------------------------------\n"); }}

  Demo.java: 初始化代码

package proxy;import proxy.downloader.YouTubeDownloader;import proxy.proxy.YouTubeCacheProxy;import proxy.some_cool_media_library.ThirdPartyYouTubeClass;/** * @author GaoMing * @date 2021/7/20 - 19:21 */public class Demo { public static void main(String[] args) {  YouTubeDownloader naiveDownloader = new YouTubeDownloader(new ThirdPartyYouTubeClass());  YouTubeDownloader smartDownloader = new YouTubeDownloader(new YouTubeCacheProxy());  long naive = test(naiveDownloader);  long smart = test(smartDownloader);  System.out.print("Time saved by caching proxy: " + (naive - smart) + "ms"); } private static long test(YouTubeDownloader downloader) {  long startTime = System.currentTimeMillis();  // User behavior in our app:  downloader.renderPopularVideos();  downloader.renderVideoPage("catzzzzzzzzz");  downloader.renderPopularVideos();  downloader.renderVideoPage("dancesvideoo");  // Users might visit the same page quite often.  downloader.renderVideoPage("catzzzzzzzzz");  downloader.renderVideoPage("someothervid");  long estimatedTime = System.currentTimeMillis() - startTime;  System.out.print("Time elapsed: " + estimatedTime + "ms\n");  return estimatedTime; }}

  执行结果

Connecting to http://www.youtube.com... Connected!Downloading populars... Done!-------------------------------Most popular videos on YouTube (imagine fancy HTML)ID: sadgahasgdas / Title: Catzzzz.aviID: asdfas3ffasd / Title: Dancing video.mpqID: 3sdfgsd1j333 / Title: Programing lesson#1.aviID: mkafksangasj / Title: Dog play with ball.mp4ID: dlsdk5jfslaf / Title: Barcelona vs RealM.mov-------------------------------Connecting to http://www.youtube.com/catzzzzzzzzz... Connected!Downloading video... Done!-------------------------------Video page (imagine fancy HTML)ID: catzzzzzzzzzTitle: Some video titleVideo: Random video.-------------------------------Connecting to http://www.youtube.com... Connected!Downloading populars... Done!-------------------------------Most popular videos on YouTube (imagine fancy HTML)ID: sadgahasgdas / Title: Catzzzz.aviID: asdfas3ffasd / Title: Dancing video.mpqID: 3sdfgsd1j333 / Title: Programing lesson#1.aviID: mkafksangasj / Title: Dog play with ball.mp4ID: dlsdk5jfslaf / Title: Barcelona vs......

原文转载:http://www.shaoqun.com/a/900493.html

跨境电商:https://www.ikjzd.com/

美菜:https://www.ikjzd.com/w/1874

一淘比价网:https://www.ikjzd.com/w/1698

心怡:https://www.ikjzd.com/w/1327


1.意图  提供对象的替代品或其占位符。代理控制着对于原对象的访问,允许在将请求提交给对象前后进行一些处理  2.动机  在面向对象的系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问对象会给使用者或者系统结构带来很多麻烦  3.适用性延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源时,可
blackbird:https://www.ikjzd.com/w/950
游客遭"保证金" 没下落 旅行社"失联"追讨不易:http://www.30bags.com/a/417870.html
游客最满意vs最不满意国家榜单出炉:http://www.30bags.com/a/418007.html
游览稻城亚丁秋季必备衣物 :http://www.30bags.com/a/412484.html
游览河南云台山秘笈 - :http://www.30bags.com/a/407541.html
第一次玩交换真实经历 不带套交换真实感受:http://lady.shaoqun.com/a/247065.html
喜欢让人㖭我下面啊 女人口述被亲下面的感觉:http://www.30bags.com/m/a/249841.html
舌尖分开她的细缝舔舐 他的舌尖在她的小核上逗弄:http://www.30bags.com/m/a/249712.html
2021泰国哪里好玩 泰国哪些地方好玩 :http://www.30bags.com/a/527697.html
洗澡时,下面的头发总是容易脱落,正常吗?或者有四种危害需要注意:http://lady.shaoqun.com/a/436502.html
女人要明白,男人越爱你,睡觉时这六个"小把戏"就越频繁!:http://lady.shaoqun.com/a/436503.html
HPV阳性=宫颈癌?女性必须了解这些知识:http://lady.shaoqun.com/a/436504.html

Comments

Popular posts from this blog

指纹浏览器定制开发全面助力企业安全与智能升级

跨境电商资讯:一文带你走进亚马逊19大海

利用 Google 购物广告促进销量的初学者指南