在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

概述


  • 意图

    为其他对象提供一种代理以控制对这个对象的访问。

  • 主要解决

    在直接访问对象时带来的问题。

    比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

  • 何时使用

    想在访问一个类时做一些控制。

  • 如何解决

    增加中间层。

  • 关键代码

    实现与被代理类组合。

  • 应用实例

  1. Windows 里面的快捷方式。
  2. 买火车票不一定在火车站买,也可以去代售点。
  3. 一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。
  4. Spring Aop。
  • 优点
  1. 职责清晰。
  2. 高扩展性。
  3. 智能化。
  • 缺点
  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
  • 使用场景

    按职责来划分,通常有以下使用场景:
  1. 远程代理。
  2. 虚拟代理。
  3. Copy-on-Write 代理。
  4. 保护(Protect or Access)代理。
  5. Cache代理。
  6. 防火墙(Firewall)代理。
  7. 同步化(Synchronization)代理。
  8. 智能引用(Smart Reference)代理。
  • 注意事项

    • 与适配器模式的区别

      适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
    • 与装饰器模式的区别

      装饰器模式为了增强功能,而代理模式是为了加以控制。

实现


原有售票服务,现在代理售票点同样提供售票服务,不必跑到机场、长途大巴车站购买票。

代理售票点,只是简单做了记账。

  • 适配器模式有如下三个角色

    Target:目标接口SellTicketsService

    Product:目标实现产品类SellTicketsServiceImpl

    Proxy:代理实现类ProxySellTicketsServiceImpl

  • step 1:目标接口

public interface SellTicketsService {
String sell(String type, BigDecimal amount);
}
  • step 2:目标实现产品类
public class SellTicketsServiceImpl implements SellTicketsService {
private Map<String, Integer> ticketCollection = new ConcurrentHashMap<String, Integer>() {{
put("air", 15);
put("bus", 35);
}}; @Override
public String sell(String type, BigDecimal amount) {
if (amount.doubleValue() < 0.0D) {
throw new IllegalArgumentException("amount can not less than zero.");
}
Integer count = ticketCollection.get(type);
if (count == null || count < 0) {
throw new IllegalStateException("ticket collection is empty");
}
count = ticketCollection.computeIfPresent(type, (k,v) -> v - 1);
if (count == 0){
ticketCollection.remove(type);
}
return "ok";
}
}
  • step 3:代理实现类
public class ProxySellTicketsServiceImpl implements SellTicketsService {

    private static final Logger logger = LoggerFactory.getLogger(ProxySellTicketsServiceImpl.class);
private SellTicketsService service = new SellTicketsServiceImpl(); @Override
public String sell(String type, BigDecimal amount) {
logger.info("sell type:{} amount:{}",type,amount);
return service.sell(type,amount);
} public static void main(String[] args) {
System.out.println(new ProxySellTicketsServiceImpl().sell("bus",BigDecimal.ONE));
}
}

设计模式学习心得<代理模式 Proxy>的更多相关文章

  1. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  2. 设计模式学习之代理模式(Proxy,结构型模式)(11)

    参考地址:http://www.cnblogs.com/zhili/p/ProxyPattern.html 一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访 ...

  3. 设计模式学习之代理模式(Proxy)

    一.代理模式的初衷 不想让客户端直接访问具体实现接口,客户端不应该直接访问具体实现,一般会涉及到以下四个对象 业务接口:定义客户端访问的接口,是实现类和代理类都需要实现的 实现类:实现了业务接口,真正 ...

  4. Java设计模式学习记录-代理模式

    代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...

  5. 设计模式入门之代理模式Proxy

    //代理模式定义:为其它对象提供一种代理以控制对这个对象的訪问 //实例:鉴于书中给出的样例不太好.并且有些疑问,所以直接用保护代理作为实例 //要求,一旦订单被创建,仅仅有订单的创建人才干够改动订单 ...

  6. 学习笔记——代理模式Proxy

    代理模式,主要是逻辑和实现解耦.具体逻辑如何,由代理Proxy自己来设计,我们只需要把逻辑Subject交给代理即可. 主要应用场景,包括创建大开销对象时,使用代理来慢慢创建:远程代理,如网络不确定时 ...

  7. 《JAVA设计模式》之代理模式(Proxy)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...

  8. javascript设计模式学习之六——代理模式

    一.代理模式定义 代理模式的关键是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.代理模式需要和本体对外提供相同的接口,对用户来说是透明的.代理模式的种类有 ...

  9. 设计模式学习心得<组合模式 Composite>

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

随机推荐

  1. 图像处理、显示中的行宽(linesize)、步长(stride)、间距(pitch)

    在图像数据传输和显示的过程中有一个不常用的参数:间距. 间距的名称:它有很多的别名,在使用d3d显示的时候,它叫pitch:在用ffmpeg解码的时候,它叫linesize: 在用ffmpeg转换格式 ...

  2. MVC人员管理系统

    基本都要使用C控制器中的两个action来完成操作,一个用于从主界面跳转到新页面.同时将所需操作的数据传到新界面,另一个则对应新界面的按钮,用于完成操作.将数据传回主界面以及跳转回主界面.根据不同情况 ...

  3. Kafka(1)--kafka基础知识

    Kafka 的简介: Kafka 是一款分布式消息发布和订阅系统,具有高性能.高吞吐量的特点而被广泛应用与大数据传输场景.它是由 LinkedIn 公司开发,使用 Scala 语言编写,之后成为 Ap ...

  4. request和response的常用方法

    一.request   1.setAttribute()在Request域中存储数据  2.setCharacterEncoding()设置请求参数的编码方式,只对post请求有效  3.getMet ...

  5. Verilog笔记——Verilog数字系统设计(第二版)夏宇闻

    本片记录Verilog学习笔记,主要是和以往用的C语言的不同之处,以例子.代码的形式记录.学习以<Verilog数字系统设计>(第二版)为参考资料,援助作者夏宇闻. 1. C语言和Veri ...

  6. JAVA并发-基于AQS实现自己的显示锁

    一.了解什么是AQS 原文链接:http://www.studyshare.cn/blog-front/blog/details/1131 AQS是AbstractQueuedSynchronizer ...

  7. spark总结

    算子总结 1.变换操作,包括过滤,变换,去重,排序,分区操作 filter过滤操作,无法触发重新分区 map,flatMap,flatMapValues,mapValues,mapPartitions ...

  8. 注意UTF-8-BOM 这个编码格式

    有时候文本文件处理出现异常,找不到其他原因的时候,注意查看下文件的编码: Notepad:编码菜单 如果发现是UTF-8-BOM,需要改成UTF-8

  9. 关于VMware虚拟机安装镜像时黑屏的解决办法

    新下载的VMware14,设置了新的虚拟机,镜像放的是ubuntu系统,然后开机要安装系统的时候黑屏,并没有进入到安装系统的界面 解决办法:在管理员权限下打开cmd,然后运行netsh winsock ...

  10. Working with Excel Files in Python

    Working with Excel Files in Python from: http://www.python-excel.org/ This site contains pointers to ...