设计模式学习之代理模式

设计模式系列往期文章

  1. 设计模式学习之策略模式
  2. 设计模式学习之策略模式在前端的应用
  3. 设计模式学习之简单工厂模式
  4. 设计模式学习之工厂方法模式
  5. 设计模式学习之抽象工厂模式
  6. 设计模式学习之策略模式和简单工厂模式的对比
  7. 设计模式学习之观察者模式
  8. 设计模式学习之模板方法模式

代理模式是结构型设计模式的一种,如下图所示——这种设计模式通过提供一个代理供调用方使用,代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
请添加图片描述

应用场景

当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口

举个栗子

某程序库提供了视频下载类。 但是该类的效率非常低。 如果客户端程序多次请求同一视频, 程序库会反复下载该视频, 而不会将首次下载的文件缓存下来复用。

这个时候就可以添加一个代理类(这个代理类实现和原视频下载类相同的接口),该代理类将所有工作委派给原下载器。不过代理类也不是什么都不做,代理类能够保存所有的文件下载记录, 如果程序多次请求同一文件, 它会返回缓存的文件,这样便可以完成优化。

说明:因此代理类相当于在被代理类的基础上做了一层封装,可以额外添加一些属性或者方法。

对应的类图为:

实现伪代码如下:

/** 三方视频下载接口 */
public interface ThirdPartyTVLib {
	List<Video> listVidos();
    Video getVideoInfo(String videoId);
    Video downloadVideo(String videoId);
}

/** 三方视频下载类 */
public class ThirdPartyTVClass implements ThirdPartyTVLib {
    @Override
    public List<Video> listVidos() {
        // TOOD
    }
	
	@Override
    public Video downloadVideo(String videoId) {
        // TODO
    }
    
	@Override
    public Video getVideoInfo(String videoId) {
        connectToServer("http://www.youtube.com/" + videoId);
        return getSomeVideo(videoId);
    }

    private int random(int min, int max) {
        return min + (int) (Math.random() * ((max - min) + 1));
    }

    private void connectToServer(String server) {
        System.out.print("Connecting to " + server + "... ");
        experienceNetworkLatency();
        System.out.print("Connected!" + "\n");
    }
    
	private Video getSomeVideo(String videoId) {
        System.out.print("Downloading video... ");

        Video video = new Video(videoId, "Some video title");

        System.out.print("Done!" + "\n");
        return video;
    }
}

/** 代理类 */
public class CachedTVClass implements ThirdPartyTVLib {
	private HashMap<String, Video> cache = new HashMap<String, Video>();
    private ThirdPartyTVLib thirdPartyTVLib;

    public CachedTVClass() {
        this.thirdPartyTVLib = new ThirdPartyTVClass();
    }

    @Override
    public Video getVideoInfo(String videoId) {
        Video video = cache.get(videoId);
        if (video == null) {
            video = thirdPartyTVLib.getVideo(videoId);
            cacheAll.put(videoId, video);
        } else {
            System.out.println("Retrieved video '" + videoId + "' from cache.");
        }
        return video;
    }

	@Override
    public List<Video> listVidos() {
        // TOOD
    }
	
	@Override
    public Video downloadVideo(String videoId) {
        // TODO
    }

    public void reset() {
        cache.clear();
    }
}

UML图

在这里插入图片描述

对应的plantUML代码:

@startuml

skinparam linetype ortho

package "Proxy" <<Frame>> {
  interface Subject {
    + method()
  }

  class RealSubject {
    + method()
  }

  class ProxySubject {
    - subject: RealSubject
    + method()
    + otherMethod()
  }

  class Client {
  }

  note right of Client
    // Client直接调用代理类
    subject = new ProxySubject();
    subject.method();
  end note

  note right of ProxySubject
    // 在代理类中保存了一个被代理类的实例
  end note

  Subject <|.. RealSubject
  Subject <|.. ProxySubject
  RealSubject <-- ProxySubject

  Client ..> Subject

}
@enduml
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值