博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式讲解2:static proxy和decorator的不同点
阅读量:5329 次
发布时间:2019-06-14

本文共 4051 字,大约阅读时间需要 13 分钟。

声明:迁移自本人CSDN博客

在常见的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 {	@Overridepublic 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;}@Overridepublic 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 itdata 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);	}	@Overridepublic 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 Stringbegin to output message by decorator AInput String is:A test StringThe 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限流器。

 

转载于:https://www.cnblogs.com/xsl-thumb-rfcs/p/9941599.html

你可能感兴趣的文章
面向对象
查看>>
lintcode83- Single Number II- midium
查看>>
移动端 响应式、自适应、适配 实现方法分析(和其他基础知识拓展)
查看>>
selenium-窗口切换
查看>>
使用vue的v-model自定义 checkbox组件
查看>>
[工具] Sublime Text 使用指南
查看>>
Hangfire在ASP.NET CORE中的简单实现方法
查看>>
Algorithm——何为算法?
查看>>
Web服务器的原理
查看>>
小强升职计读书笔记
查看>>
常用的107条Javascript
查看>>
#10015 灯泡(无向图连通性+二分)
查看>>
elasticsearch 集群
查看>>
忘记root密码,怎么办
查看>>
linux设备驱动归纳总结(三):1.字符型设备之设备申请【转】
查看>>
《黑客与画家》 读书笔记
查看>>
bzoj4407: 于神之怒加强版
查看>>
mysql统计一张表中条目个数的方法
查看>>
ArcGIS多面体(multipatch)解析——引
查看>>
JS 在火狐浏览器下关闭弹窗
查看>>