java中适配器模式
2016-04-28 15:03
267 查看
1、概述
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
2、适配器模式的用途
即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
3、模式中的角色
3.1 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
3.2 需要适配的类(Adaptee):需要适配的类或适配者类。
3.3 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
4、实现方式
(1)类的适配器模式(采用继承实现)
源代码:
结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能
(2)对象适配器(采用对象组合方式实现)
结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能
从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。
5、类适配器和对象适配器的权衡(摘自大牛博客)
● 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
● 对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义 Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
● 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。
● 对于对象适配器,需要额外的引用来间接得到Adaptee。
建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。
适配器模式的优点
更好的复用性
系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
更好的扩展性
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
适配器模式的缺点
过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
2、适配器模式的用途
即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
3、模式中的角色
3.1 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
3.2 需要适配的类(Adaptee):需要适配的类或适配者类。
3.3 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
4、实现方式
(1)类的适配器模式(采用继承实现)
源代码:
//目标接口,或称为标准接口 public interface Target { //普通功能 public void request(); } //已存在的、具有特殊功能、但不符合我们既有的标准接口的类 public class Adaptee { public void specificRequest() { System.out.println("被适配类...我是两孔插座 具有特殊功能"); } } //适配器类,继承了被适配类,同时实现标准接口 public class Adapter extends Adaptee implements Target { @Override public void request() { System.out.println("我是适配器类 我能适配任何两孔插座 让它正常工作"); this.specificRequest(); } } public class Client { public static void main(String[] args) { Target adapter = new Adapter(); //通过适配器调用特殊功能 adapter.request(); } }
结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能
(2)对象适配器(采用对象组合方式实现)
源代码: //目标接口,或称为标准接口 public interface Target { //普通功能 public void request(); } //已存在的、具有特殊功能、但不符合我们既有的标准接口的类 public class Adaptee { public void specificRequest() { System.out.println("被适配类...我是两孔插座 具有特殊功能"); } } //适配器类,直接关联被适配类,同时实现标准接口 class Adapter implements Target { // 直接关联被适配类 private Adaptee adaptee; // 可以通过构造函数传入具体需要适配的被适配类对象 public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } public void request() { // 这里是使用委托的方式完成特殊功能 System.out.println("我是适配器类 我能适配任何两孔插座 让它正常工作"); this.adaptee.specificRequest(); } } public class Client { public static void main(String[] args) { //使用特殊功能类,即适配类, // 需要先创建一个被适配类的对象作为参数 Target adapter = new Adapter(new Adaptee()); adapter.request(); } }
结果:
我是适配器类 我能适配任何两孔插座 让它正常工作
被适配类…我是两孔插座 具有特殊功能
从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。
5、类适配器和对象适配器的权衡(摘自大牛博客)
● 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
● 对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义 Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。
● 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。
● 对于对象适配器,需要额外的引用来间接得到Adaptee。
建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。
适配器模式的优点
更好的复用性
系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
更好的扩展性
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
适配器模式的缺点
过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
相关文章推荐
- java开发之匿名内部类,接口的使用
- Eclipse构建maven的Web项目
- 主题 Java学习从入门到精通
- Java 多线程实现接口Runnable和继承Thread区别
- eclipse项目找不到build path
- Java学习从入门到精通
- java中静态代码块、普通代码块、构造器的执行顺序
- springMVC文件上传
- eclipse中 将java项目转换为web项目
- SpringMVC上传、下载文件
- 一个经典例子让你彻彻底底理解java回调机制
- Maven模版Bug及解决办法
- Java:String和Date、Timestamp之间的转换
- springmvc事务管理详解
- Spring中编程式事务处理(使用TransactionTemplate)之一
- Java导入数据到Excel表格(poi方式)
- Java进程和线程的概述
- java 连接access数据库两种方式
- Spring bean是如何加载的
- 性能VS可靠性:为什么Java程序像F1赛车