设计模式讲解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 意图 为其他对象提供一种代理以控制对这个对象的 ...
随机推荐
- 配置多个数据源datasource
https://www.jianshu.com/p/34730e595a8c @Primary.@Qualifire.@Autowired.@Resource https://blog.csdn.ne ...
- (转)zookeeper理解
分布式服务框架 Zookeeper -- 管理分布式环境中的数据 Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题 ...
- objectarx 批量倒角
这个插件支持AcDbPolyline的倒角,封闭的和没封闭的都可以.刚开始做的时候,发现倒一个角借助云幽课堂里的代码就可以做,后来做一条从左开始画的非封闭的多段线,发现向上凹和向下凹的角不能同时被倒, ...
- JavaWeb开发校园二手平台项目 源码
开发环境: Windows操作系统开发工具:MyEclipse/Eclipse + JDK+ Tomcat + MySQL 数据库 项目简介: JAVAWEB校园二手平台项目,基本功能包括:个人信息. ...
- 六十八、SAP中内表插入的三种方法之二,COLLECT的使用,用于计算数字字段之和
一.使用COLLECT时,如果关键字没有,那么插入,如果有则求所有关键字列的和,代码如下 二.sy-index在循环中,每次循环从1开始递增 三.查看T_DATA数据 四.如下 五.循环时候,我们查看 ...
- Spring 面向切面编程(AOP)
Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...
- 【Vue中的坑】Vue打包上传线上报Uncaught SyntaxError: Unexpected token <
今天在vue打包上传线上后,报一下错误,一下就懵了,这可咋整啊,一如既往的想都没想就开始复制错误,上网开搜 Uncaught SyntaxError: Unexpected token < Un ...
- VS Code使用.vue的v-for方法提示错误的解决办法
1.在使用v-for的时候在后面跟上:key="key" <div v-for="(value, key) in [1,2,3]" :key=" ...
- 51nod 1287: 加农炮 好题啊好题
1287 加农炮 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个长度为M的正整数数组A,表示从左向右的地形高度. ...
- 刷题31. Next Permutation
一.题目说明 题目是31. Next Permutation,英文太差看不懂,翻译了一下.才知道是求字典顺序下的下一个排列,不允许使用额外空间.题目难度是Medium! 二.我的实现 首先要进一步理解 ...