设计模式(13)适配器模式
一、介绍:
1、定义:是一种结构型设计模式,它可以将一个类的接口转换成客户端所期望的另一种接口。适配器模式常用于系统的不兼容性问题。
2、组成:
(1)目标接口(Target):客户端所期望的接口,适配器通过实现目标接口来对外提供服务。
(2)适配器(Adapter):将源接口转换成目标接口的类,它实现了目标接口,并且包含一个对源接口的引用。
(3)源接口(Adaptee):需要被适配的类,其接口与目标接口不兼容。
3、UML类图:
4、优缺点:
(1)优点:
更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
更好的扩展性:在实现适配器功能的时候,可以扩展自己源的行为(增加方法),从而自然地扩展系统的功能。
完美实现解耦,通过增加适配器类将适配者与目标接口联系起来,无需修改原有实现;
符合开闭原则
(2)缺点:会导致系统紊乱:滥用适配器,会让系统变得非常零乱。例如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
5、适配器模式有2种:面向类的适配器模式,面向对象的适配器模式。常说的是对象适配器。
二、demo:
1、类适配器模式:
//源:
class Person {
public void speakJapanese() {
System.out.println("I can speak Japanese!");
}
public void speakEnglish() {
System.out.println("I can speak English!");
}
}
//目标:
interface Target {
void speakJapanese();
void speakEnglish();
void speakFrench();
}
//适配器:
class Adapter extends Person implements Target {
@Override
public void speakFrench() {
}
}
2、对象适配器模式:把“源”作为一个对象聚合到适配器类中。
//源
class Person {
public void speakJapanese() {
System.out.println("I can speak Japanese!");
}
public void speakEnglish() {
System.out.println("I can speak English!");
}
}
//对象
interface Target {
void speakJapanese();
void speakEnglish();
void speakFrench();
}
//适配器
class Adapter implements Target {
Person mPerson;
public Adapter(Person person) {
this.mPerson = person;
}
@Override
public void speakJapanese() {
mPerson.speakJapanese();
}
@Override
public void speakEnglish() {
mPerson.speakEnglish();
}
@Override
public void speakFrench() {
}
}
3、接口适配器模式(缺省适配模式):
这种模式的核心归结如下:当你想实现一个接口但又不想实现所有接口方法,只想去实现一部分方法时,就用默认的适配器模式,他的方法是在接口和具体实现类中添加一个抽象类,而用抽象类去空实现目标接口的所有方法。而具体的实现类只需要覆盖其需要完成的方法即可。
public interface Job {
public abstract void speakJapanese();
public abstract void speakEnglish();
public abstract void speakFrench();
public abstract void speakChinese();
}
public abstract class JobDefault implements Job{
public void speakChinese() {
}
public void speakEnglish() {
}
public void speakFrench() {
}
public void speakJapanese() {
}
}
public class JobImpl extends JobDefault{
public void speakChinese(){
System.out.println("I can speak Chinese!");
}
}