欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java设计模式之代理模式(Porxy)详解

程序员文章站 2023-12-15 17:34:40
一、什么是代理模式(porxy)   概念:代理模式就是为其他对象提供一种代理以控制对这个对象的访问。   现实生活中也有很多行为吻合代理模式。比如店外卖,客户在a...

一、什么是代理模式(porxy)

  概念:代理模式就是为其他对象提供一种代理以控制对这个对象的访问。

  现实生活中也有很多行为吻合代理模式。比如店外卖,客户在app上下单后,店长会接单。这个时候店长可以选择自己去送这份外卖,也可以委托送餐员代理店长去送这份外卖。当然店长是可以自己送,但店长送了外卖店就没人看着了,而让送餐员代理送外卖就不会这样了。这里很显然店长是对象本尊(subject),送餐员是代理对象(proxy ),代理对象中有店长给的订单信息,比如送到哪里,几点之前要送到,这就说明代理对象中需要包含本尊。下面根据实际代码来说明代理模式和非代理的具体实现。

二、模式对比

1、非代理模式

非代理模式即店长自己送,无须委托送餐员代理送。即直接创建本尊对象并访问本尊方法,没有中间的代理对象。

本尊代码

public class shopkeeper {

  //客户信息
  private consumer consumer;
  
  public shopkeeper(consumer consumer){
    this.consumer = consumer;
  }
  
  //外卖订单信息
  public void send(){
    system.out.println(consumer.getconname() + "的订单,店长自己送,送到胶东路520弄,11:30之前送达...");
  }
  
}

客户代码

public class consumer {

  private string conname;
  
  public consumer(string conname){
    this.conname = conname;
  }

  public string getconname() {
    return conname;
  }
}

客户端测试代码

public class show {

  public static void main(string[] args) {
    consumer consumer = new consumer("tom");
    shopkeeper shopkeeper = new shopkeeper(consumer);
    shopkeeper.send();
  }
  
}

这样店长和客户的代码就耦合在一起,不利于后期维护升级。再者店长和客户本来就不需要相互包含,他们之间是无状态的。像很多pub/sub的中间件,比如dubbo,activemq等等,他们都是基于消息的发布的订阅机制,生产者和消费者之间没有必要有状态交互,你消费者挂了我生产者还是继续生产消息,互不影响,其实很多技术都是想通的,这里和代理模式就和类似。下面来看看代理模式是怎么处理的。

2、代理模式

提供了一个共有的送外卖接口

public interface send {

  void sendname();
  void sendtime();
  void sendaddress();
  
}

店长本尊对象,实现了共有的送外卖接口。

/**
 * 店长对象(本尊)需要实现send接口
 * @author user
 */
public class shopkeeper implements send{

  private consumer consumer;
  
  public shopkeeper(consumer consumer){
    this.consumer = consumer;
  }
  
  @override
  public void sendname() {
    system.out.print(consumer.getconname() + "的订单,");
  }
  
  @override
  public void sendtime() {
    system.out.print("12:00之前送达,");
  }

  @override
  public void sendaddress() {
    system.out.print("送到长岛路520弄,由代理对象配送...");
  }

新增了代理对象,代理对象需要包含本尊,并且也要实现送外卖(send)接口

/**
 * 代理对象也需要实现send接口
 * @author user
 *
 */
public class proxysend implements send{

  private shopkeeper shopkeeper;
  
  public proxysend(consumer consumer){
    this.shopkeeper = new shopkeeper(consumer);
  }
  
  @override
  public void sendname() {
    shopkeeper.sendname();
  }

  @override
  public void sendtime() {
    shopkeeper.sendtime();
  }

  @override
  public void sendaddress() {
    shopkeeper.sendaddress();
  }

}

客户对象没有变化

public class consumer{
  
  private string conname;

  public string getconname() {
    return conname;
  }

  public void setconname(string conname) {
    this.conname = conname;
  }
}

客户端测试代码

public class show {

  public static void main(string[] args) {
    
    consumer consumer = new consumer();
    consumer.setconname("外卖张");
    proxysend proxy = new proxysend(consumer);
    proxy.sendname();
    proxy.sendtime();
    proxy.sendaddress();
    
  }
  
}

看输出

外卖张的订单,12:00之前送达,送到长岛路520弄...

这样代理对象就帮本尊完成了任务,可以看到客户端的代码变化很大,客户端根本不知道本尊的存在,因为在客户端代码中至始至终都没有看到本尊对象的创建,连实例都没有,这其实就是代理对象的作用之一,隐藏本尊。

3、代理模式基本结构

subject类,定义了realsubject和proxy的共用接口,这样就在任何使用realsubject的地方都可以使用proxy,这里使用抽象类

public abstract class subject {

  public abstract void request(); 
  
}

realsubject类,定义了proxy所代表的真是实体

public class realsubject extends subject {

  @override
  public void request() {
    system.out.println("真实的请求");
  }

}

proxy类,保存了一个引用使得代理对象可以访问实体对象,并提供一个与subject的接口相同的接口,这样代理就可以用来代理实体。

public class proxy extends subject{

  realsubject realsubject;
  
  @override
  public void request() {
    if (realsubject == null) {
      realsubject = new realsubject();
    }
    realsubject.request();
  }

}

客户端代码

public class show {

  public static void main(string[] args) {
    proxy proxy = new proxy();
    proxy.request();
  }
  
}

测试结果

真实的请求

4、uml图

java设计模式之代理模式(Porxy)详解

三、总结

代理模式一般用在一下几种场合。1、远程代理,也就是为了一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。2、虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。3、安全代理,用来控制真实对象访问是的权限。4、智能指引,是指当前调用真实的对象时,代理处理另外一些事情。所以代理模式还算比较常用的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: