设计模式讲解2:static proxy和decorator的不同点
声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635
在常见的23种设计模式中,static proxy和decorator在代码结构上是特别相似的。那它们的不同具体体现在什么地方呢,本文就通过静态代理模式代码和装饰器模式代码的比较说明这个问题。
本文给出的例子将会尽可能简单的例子,把最核心的接口及继承关系展现出来,以期读者不被繁复的业务逻辑所束缚。
static proxy模式代码如下
接口类
package com.test.designpattern.staticproxyexample;
public interface Subject {
void printString(String url);
}
接口实现类
package com.test.designpattern.staticproxyexample;
public class ConcreteSubject implements Subject {
@Override
public void printString(String url) {
String dataFormUrl = mockNetRequest(url);
System.out.println("data from internet is :" + dataFormUrl);
}
private String mockNetRequest(String url) {
return new StringBuilder("data from ").append(url).append(" is:").append("200").toString();
}
}
代理类,实现接口类
package com.test.designpattern.staticproxyexample;
public class Proxy implements Subject {
private Subject subject;
public Proxy(Subject subject) {
this.subject = subject;
}
@Override
public void printString(String url) {
System.out.println("This is a proxy server in hongkong, you can accesss google through it");
subject.printString(url);
}
}
测试类
package com.test.designpattern.staticproxyexample;
public class TestStaticProxy {
public static void main(String[] args) {
//如果这里直接访问ConcreteSubject,将因为各种原因受限而返回404,模拟代码实现作为读者的家庭作业
Subject proxySubject = new Proxy(new ConcreteSubject());
proxySubject.printString("https://xxx.xxx.xxx");
}
}
运行结果如下
This is a proxy server in hongkong, you can accesss google through it
data from internet is :data from https://xxx.xxx.xxx is:200
decorator模式代码如下
接口类
package com.test.designpattern.docoratorexample;
public interface Component {
void printString(String s);
}
接口实现类
package com.test.designpattern.docoratorexample;
public class ConcreteComponent implements Component {
@Override
public void printString(String s) {
System.out.println("Input String is:" + s);
}
}
抽象装饰类,提供了接口方法的一般实现,也可以不需要这个类
package com.test.designpattern.docoratorexample;
public class Decorator implements Component {
private Component component;
public Decorator(Component c) {
component = c;
}
@Override
public void printString(String s) {
component.printString(s);
}
}
具体装饰类,完善功能
package com.test.designpattern.docoratorexample;
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component c) {
super(c);
}
@Override
public void printString(String s) {
printPromptMesage();
//保留原有的功能
super.printString(s);
//加强已有的功能
printStringLen(s);
}
private void printPromptMesage() {
System.out.println("begin to output message by decorator A");
}
private void printStringLen(String s) {
System.out.println("The length of string is:" + s.length());
}
}
测试类
package com.test.designpattern.docoratorexample;
public class TestDecorator {
public static void main(String[] args) {
Component myComponent = new ConcreteComponent();
myComponent.printString("A test String");
Decorator myDecorator = new ConcreteDecoratorA(myComponent);
myDecorator.printString("A test String");
}
}
运行结果
Input String is:A test String
begin to output message by decorator A
Input String is:A test String
The length of string is:13
单从代码结构上来讲,静态代理模式和装饰器模式是一样的,但是它们有本质的不同,本文作者挑选的2个例子,尽可能把函数名都写成一样的,但是它们的内涵是不一样的。
从意图上来说,Proxy中模拟在本地直接调用接口实现类ConcreteSubject 无法实现而必须经过Proxy才能实现的功能。Decorator中模拟了完善接口实现类ConcreteComponent的功能。
作者在公司工作的时候,有一个功能是实现限流,就是控制存取磁盘数据的数据流量,这时采用的就是装饰器类而非代理类,装饰器装饰的是Java原生的InputStream、OutputStream。
学习设计模式,最应该认真反复学习的书籍当然是“四人帮”编写的《Design Pattern—Elements of Reusable Object-Oriented Software》.
借用其中的一段话表述Proxy和Decorator的区别。
这2种模式都描述了怎样为对象提供一定程度上的间接引用,proxy和decorator对象的实现部分都保留了指向另一个对象的指针,它们向这个对象发送请求。然而,它们具有不同的设计目的。
像Decorator模式一样,Proxy模式构成一个对象并为用户提供一致的接口,但与Decorator模式不同的是,Proxy模式不能动态地添加或分离性质,它也不是为递归组合而设计的。它的目的是,当直接访问一个实体不方便或者不符合需要时,为这个实体提供一个替代者,例如,实体在远程设备上,访问受到限制或者实体是持久存储的。
在Proxy模式中,实体定义了关键功能,而Proxy提供(或拒绝)对它的访问。
Proxy模式访问模型如下:
Client——>Proxy——>ConcreteSubject,目标在ConcreteSubject,如果Client能直接访问到ConcreteSubject,是不会去麻烦Proxy的。
Decorator模式访问模型如下:
Client——>ConcreteDecorator——>ConcreteComponent,此时的目标不是ConcreteComponent了,就是ConcreteDecorator,因为ConcreteDecorator才能提供Client需要的完整功能。比如上文说的IO限流器。
设计模式讲解2:static proxy和decorator的不同点的更多相关文章
- Java设计模式(7)装饰模式(Decorator模式)
Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...
- 设计模式:代理(Proxy)模式
设计模式:代理(Proxy)模式 一.前言 代理模式或许我们都听说过,至少知道代理(Proxy)这个东西的,否则看这篇博客也没任何意义的.什么叫做代理,代理是代替服务器去接受请求者的请求的中间人 ...
- 设计模式讲解4:Bridge模式源码
声明:迁移自本人CSDN博客https://blog.csdn.net/u013365635 桥接模式可以和排列组合关联起来理解,一个对象有多种不通种类的属性,如attributeA1,attribu ...
- 设计模式-代理模式(Proxy Model)
文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/5988145.html 目录 1.写在前面 2.概述 3.目的 4.结构组成 5.实现 5 ...
- 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)
原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...
- PHP设计模式之装饰器模式(Decorator)
PHP设计模式之装饰器模式(Decorator) 装饰器模式 装饰器模式允许我们给一个类添加新的功能,而不改变其原有的结构.这种类型的类属于结构类,它是作为现有的类的一个包装 装饰器模式的应用场景 当 ...
- 深入浅出设计模式——代理模式(Proxy Pattern)
模式动机在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到 ...
- C#设计模式(9)——装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- 设计模式之美:Proxy(代理)
索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用相同 Subject 接口实现 Proxy. 别名 Surrogate 意图 为其他对象提供一种代理以控制对这个对象的 ...
随机推荐
- SpringMVC中 controller方法返回值
1)ModelAndView @RequestMapping(value="/itemEdit") public ModelAndView itemEdit(){ //创建模型视图 ...
- spring第9天(事务)
依赖:spring-context,spring-jdbc(这个本身有依赖spring-tx,关于事务的),druid,mysql-connector-java,aspectjweaver五个 由于我 ...
- inkscape批量将svg转为pdf
for i in *.svg;do inkscape --export-pdf=${i%.*}.pdf $i;done
- Python 自省指南
原作者:Patrick K. O'Brien 什么是自省? 在日常生活中,自省(introspection)是一种自我检查行为.自省是指对某人自身思想.情绪.动机和行为的检查.伟大的哲学家苏格拉底将生 ...
- python保留小数位
前言 保留小数位是我们经常会碰到的问题,尤其是刷题过程中.那么在python中保留小数位的方法也非常多,但是笔者的原则就是什么简单用什么,因此这里介绍几种比较简单实用的保留小数位的方法: 方法一:fo ...
- 2020/2/3 PHP代码审计之PHP伪协议
0x00 简介 开局一张图233 0x01 file://协议 说明: file:// 文件系统是 PHP 使用的默认封装协议,展现了本地文件系统.当指定了一个相对路径(不以/..\或 Windows ...
- POJ 1149:PIGS 网络流经典题
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18345 Accepted: 8354 Description ...
- jQuery.ajax提交JSON数据
$.ajax({ type: 'POST', url: "URL", contentType:'application/json', //需要加contentType crossD ...
- Uber推出全新交通估算体系能颠覆传统模式吗?
当下,大众的交通出行正在被全面颠覆.除了传统的出行方式外,共享打车.共享单车.共享滑板车.分时租赁的共享汽车等,正在形成一个全新交通出行矩阵.鉴于交通出行市场的巨大潜力,众多巨头及独角兽企业在绞尽脑汁 ...
- 从1到n整数中1的个数
[问题]求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了.A ...