这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
这篇文章主要为大家详细介绍了 java 设计模式之适配器模式笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
适配器(Adapter)模式:
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.
生活中的场景:
1,笔记本电源适配器,可以将 220v 转化为适合笔记本使用的电压.
2,给笔记本电脑的 usb 接口插入台式机的 ps/2 接口的键盘,需要一个 usb 和 ps/2 的接口转接器,此时 usb 和 ps/2 的接口转接器就充当了适配器的角色.
通用类图:
在上面的通用类图中,Cient 类最终面对的是 Target 接口(或抽象类),它只能够使用符合这一目标标准的子类;而 Adaptee 类则是被适配的对象(也称 源角色),因为它包含 specific (特殊的)操作,功能等,所以我们想要在自己的系统中使用它,将其转换成符合我们标准的类,使得 Client 类可以在透明的情况下任意选择使用 ConcreteTarget 类或是具有特殊功能的 Adaptee 类.
适配器模式中的角色:
目标接口 (Target):客户所期待得到的接口.目标可以是具体的或抽象的类,也可以是接口.
需要适配的类 (Adaptee):需要适配的接口或适配类.
适配器 (Adapter):适配器类是本模式的核心.适配器通过包装一个需要适配的对象,把源接口转换成目标接口.显然,这一角色不可以是接口,而必须是具体类.
适配器模式的结构:
适配器模式有类的适配器模式和对象的适配器模式两种不同的形式.
类的适配器模式把适配的类的 API 转换成为目标类的 API.
对象的适配器模式与类的适配器模式一样,对象的适配器模式把被适配的类的 API 转换成为目标类的 API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到 Adaptee 类,而是使用委派关系连接到 Adaptee 类.
类的适配器模式
1,创建一个被适配的类:
/**
* 被适配的类
* 已存在的,具有特殊功能,但不符合我们既有的标准接口的类
* (相当于例子中的,PS/2键盘)
2,创建一个目标接口,能处理一些特殊请求
* @author ChuanChen
*
*/
public class Adaptee {
public void specificRequest() {
System.out.println("可以完成客户请求的需要的功能!");
}
}
/**
* 目标接口,或称为标准接口
3,创建一个适配器 (类适配器方式)
* @author ChuanChen
*
*/
public interface Target {
void handleReq();
}
/**
* 适配器 (类适配器方式)
* (相当于usb和ps/2的转接器)
4,创建一个客户端
* @author ChuanChen
*
*/
public class Adapter extends Adaptee implements Target {
@Override
public void handleReq() {
super.specificRequest();
}
}
/**
* 客户端类
* (相当于例子中的笔记本,只有USB接口)
上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能.
* @author ChuanChen
*
*/
public class Client {
public void test(Target t) {
t.handleReq();
}
public static void main(String[] args) {
Client c = new Client();
Adaptee a = new Adaptee();
Target t = new Adapter();
c.test(t);
}
}
对象的适配器模式
1,创建一个被适配的类:
/**
* 被适配的类
* 已存在的,具有特殊功能,但不符合我们既有的标准接口的类
* (相当于例子中的,PS/2键盘)
2,创建一个目标接口,能处理一些特殊请求
* @author ChuanChen
*
*/
public class Adaptee {
public void specificRequest() {
System.out.println("可以完成客户请求的需要的功能!");
}
}
/**
* 目标接口,或称为标准接口
3,创建一个适配器 (对象适配器方式, 使用了组合的方式跟被适配对象整合)
* @author ChuanChen
*
*/
public interface Target {
void handleReq();
}
/**
* 适配器 (对象适配器方式,使用了组合的方式跟被适配对象整合)
* (相当于usb和ps/2的转接器)
4,创建一个客户端
* @author ChuanChen
*
*/
public class Adapter implements Target{
private Adaptee adaptee;
@Override
public void handleReq() {
adaptee.specificRequest();
}
public Adapter(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
}
/**
* 客户端类
* (相当于例子中的笔记本,只有USB接口)
我们只需要修改 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现.使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类.这样看起来的话,似乎对象适配器模式更加灵活一点.
* @author ChuanChen
*
*/
public class Client {
public void test(Target t) {
t.handleReq();
}
public static void main(String[] args) {
Client c = new Client();
Adaptee a = new Adaptee();
Target t = new Adapter(a);
c.test(t);
}
}
类适配器和对象适配器的权衡:
类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式.
对于类适配器,由于适配器直接继承了 Adaptee,使得适配器不能和 Adaptee 的子类一起工作,因为继承是静态的关系,当适配器继承了 Adaptee 后,就不可能再去处理 Adaptee 的子类了.
对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标.换言之,同一个适配器可以把源类和它的子类都适配到目标接口.因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓.
对于类适配器,适配器可以重定义 Adaptee 的部分行为,相当于子类覆盖父类的部分实现方法.
对于对象适配器,要重定义 Adaptee 的行为比较困难,这种情况下,需要定义 Adaptee 的子类来实现重定义,然后让适配器组合子类.虽然重定义 Adaptee 的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源.
对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到 Adaptee.
对于对象适配器,需要额外的引用来间接得到 Adaptee.
建议尽量使用对象适配器的实现方式,多用合成 / 聚合,少用继承.当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的.
适配器模式的优点:更好的复用性:
系统需要使用现有的类,而此类的接口不符合系统的需要.那么通过适配器模式就可以让这些功能得到更好的复用.
更好的扩展性:
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能.
适配器模式的缺点
过多的使用适配器,会让系统非常零乱,不易整体进行把握.比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难.因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构.
适配器模式在工作中的场景:
1,已经存在的类的接口不符合我们的需求;
2,创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;
3,在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类.
适配器模式经常用于旧系统改造和升级.如果我们的系统开发之后再也不需要维护,那么很多模式都是没有必要的.但是不幸的是,事实上维护一个系统的代价往往是开发一个系统的数倍.
来源: http://www.phperz.com/article/18/0114/352936.html