装饰模式与适配器模式的的区别

做java也两年多的时间了,java入门不久就买了一本阎宏的《java与模式》研究,那时看模式简直就像看天书一样,特别是装饰模式适配器模式,于是就束之高阁了。

工作之后,在项目中也经常用到模式,体会到模式的好处,也渐渐理解了一些常用的模式。

现在有时间也把《java与模式》翻翻,加深对模式的理解。就上周看的装饰模式适配器模式做个小结,有总结才会有进步嘛,但在开始之前,谈一点我对《java与模式》这本书的评价,这本书在对模式的解释还是很成功的,对模式的说明,案例以及应用都有很精彩的阐述,软件开发是一门艺术,不是一门哲学,阎老师搜肠刮肚,博古论今,讲了那么多的道家的思想,java模式是牛X,但也不用上升到这么高的高度。

装饰模式适配器模式都有一个别名叫包装模式,但包装的形式是不一样的。

定义上:

装饰模式:对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。使用原来被装饰的类的一个子类的实例,把客户端的调用委派到被装饰类。

适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。

从定义上看装饰模式是对核心对象或者功能的扩展,适配器模式是把对象或者功能放到一个新对象中引用。举个例子,现在书城卖道德经的书,有线装版,有精装版,有日文版,有英文版,其中线装版和精装版就是装饰模式,日文版和英文版就是适配器模式,各种版本都是为迎合不同消费者的不同需求。为什么呢?因为线装版和精装版的道德经虽然包装不同,但内容相同,日文版和英文版就不同,这两个版本的内容就可能和原版的不同,文化差异嘛,翻译的内容虽来自道德经,但根据不同国家的文化,思维逻辑什么的就可能改变一些想法。

使用条件:

装饰模式一般在下列情况使用:需要扩展一个类的功能或者给你个类增加附加责任;需要动态的给一个对象增加功能,这些功能可以再动态的撤销;需要增加有一些基本功能的排列组合而产生非常大量的功能,从而使得继承关系变得不现实。

适配器模式一般使用的情况包括:系统需要使用现有的类,但此类已经不符合系统的需要;

想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的的类一起工作。适配器模式在系统升级的时候使用的频率很高,对旧系统的一些功能方法在新系统中引用。

Java中的应用:

装饰模式适配器模式在java中的I/O文件的操作中都有体现。

Java的IO库中处理流的类有FIleInputStream,FileOutputStream,DataInputStream,DataOutputStream类等。在InputStream,OutputStream,Reader,Writer结构的内部,有一些流处理器可以对另一些流处理器起到装饰作用,形成新的,改善的流处理器。这就体现了装饰模式的作用。同时在一些流处理器的内部有对其他流处理器的功能的适配引用,这体现了适配器模式的优点。

模式概念的出现,完善到合理应用是前辈们在实际的应用中不断总结的结晶。对于不同的需求合理的使用模式能起到事半功倍的效果,但是模式不是放之四海而皆准的,况且模式也不是一成不变死板的,随着技术的发展,工程师的智慧总结,可能会有新的模式出现和旧的模式的消亡,模式就是为实际需要而生,没必要上升到哲学这种高度。

这是我对装饰模式适配器模式的一点浅见,欢迎指正 

### 装饰器模式适配器模式的主要差异 #### 功能目的不同 装饰器模式旨在为已有的对象动态地添加新的功能,而不必修改原有类的定义或使用继承的方式实现这一点[^4]。相反,适配器模式主要目的是使原本由于接口不匹配而无法一起工作的那些类可以协同工作,即解决现有组件之间接口不兼容的问题[^2]。 #### 结构特性有别 尽管两者都属于结构型设计模式,并且可能具有类似的UML类图外观,但在实际应用中的角色却截然不同。对于装饰器而言,它通常会持有一个指向被装饰者的引用,在运行时构建一层或多层围绕着核心业务逻辑的对象层次;而对于适配器来说,则更侧重于转换源接口到目标接口的过程,从而让客户端能够透明地调用所需的服务[^1]。 #### 实现方式各异 在具体编码实践中,采用装饰器模式时往往涉及创建一系列具体的装饰者子类来封装特定的行为增强机制,这些装饰者遵循相同的抽象基类或者接口规范以便灵活组合运用。相比之下,适配器的设计更多体现在如何巧妙地映射两个独立系统的操作方法,有时甚至可以通过内部持有适应对象实例的方式来间接完成这一任务[^3]。 ```java // 示例:简单的装饰器模式实现 public abstract class Beverage { public String getDescription() { return ""; } public abstract double cost(); } public class Espresso extends Beverage { @Override public String getDescription() { return "Espresso"; } @Override public double cost() { return 1.99; } } public abstract class CondimentDecorator extends Beverage { protected Beverage beverage; public CondimentDecorator(Beverage b) { this.beverage = b; } @Override public String getDescription() { return beverage.getDescription(); // 子类应覆盖此方法并追加描述 } } ``` ```java // 示例:简单的适配器模式实现 interface Target { void request(); } class Adaptee { public void specificRequest() { System.out.println("Adaptee's specific behavior"); } } class Adapter implements Target { private final Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值