适配器模式属于结构型模式,它主要分为三类:类适配器模式,对象适配器模式, 接口适配器模式。
类适配器模式
场景:现在只有一个苹果充电接口,需要一个转接器让它变成安卓接口。
先创建一个已有的苹果类
public class Iphone {
public void getInfo(){
System.out.println("我是苹果接口");
}
}
再来一个接口,接口提供可以让苹果转Android或者转Typec的两个方法
public interface IChangeType {
public void changeAndroid();
public void changeTypeC();
}
再创建一个适配器,这才是真正可以实现苹果转Android或者转Typec的功能。我们去超市买了转接器首先是不是将它插在苹果的接口上,那么可以理解成苹果里的东西都给了转接器,在这里Adapter 需要继承Iphone类,这样就有了Iphone的功能,然后经过特殊加工处理得到了适配Android或者Typec的 功能。加工处理的话是不是需要两个方法来生成出两种不同的接口,在这里Adapter还需要实现IChangeType接口。
public class ClassAdapter extends Iphone implements IChangeType{
@Override
public void changeAndroid() {
getInfo();
System.out.println("经过加工处理······");
System.out.println("我现在是安卓接口");
}
@Override
public void changeTypeC() {
getInfo();
System.out.println("经过加工处理······");
System.out.println("我现在是typec接口");
}
}
然后再创建客户端去用
public class Client {
public static void main(String[] args) {
ClassAdapter adapter = new ClassAdapter();
adapter.changeAndroid();
}
}
类适配器模式需要继承被适配者,被适配的类方法会在适配器类中暴露出来(Adapter的方法里都需要调用getInfo()方法来拿到被适配的一些东西,如果多来几个适配器,那么使用成本就增加了。)
对象适配器
在上面的基础上稍做修改,不去继承Iphone类(使用组合替代继承),而是持有它的实例。
public class ObjectAdapter implements IChangeType {
private Iphone iphone;
public ObjectAdapter(Iphone iphone) {
this.iphone = iphone;
}
@Override
public void changeAndroid() {
iphone.getInfo();
System.out.println("经过加工处理······");
System.out.println("我现在是安卓接口");
}
@Override
public void changeTypeC() {
iphone.getInfo();
System.out.println("经过加工处理······");
System.out.println("我现在是typec接口");
}
}
public class Client {
public static void main(String[] args) {
ClassAdapter adapter = new ClassAdapter(new Iphone());
adapter.changeAndroid();
}
}
接口适配器模式
当不需要全部实现接口提供的方法时,可以先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(理解成空方法),那么该抽象类的子类可有选择性的覆盖父类的某些方法来实现需求。
再将上面对象适配器类进行改造,把类改为抽象类。
public abstract class AbstractAdapter implements IChangeType{
private Iphone iphone;
public AbstractAdapter(Iphone iphone) {
this.iphone = iphone;
}
@Override
public void changeAndroid() {
iphone.getInfo();
}
@Override
public void changeTypeC() {
iphone.getInfo();
}
}
实现两个方法的时候,方法体是没有任何的逻辑处理,(空方法的含义可以表示为没有进行过任何的逻辑处理),里面调用iphone.getInfo()目的是拿到原先Iphone接口它本身的东西,有了原材料才可以对它进行加工处理,只不过处理过程不在这里实现。
public class Client {
public static void main(String[] args) {
AbstractAdapter abstractAdapter = new AbstractAdapter(new Iphone()) {
@Override
public void changeAndroid() {
super.changeAndroid();
System.out.println("经过加工处理······");
System.out.println("我现在是安卓接口");
}
};
abstractAdapter.changeAndroid();
}
}
像这样的话真正有用的功能是苹果转安卓,虽然可以通过abstractAdapter.changeTypeC();语句调用转Typec功能,但是我们并没有真正写了此功能的逻辑处理,所以即使用了也没有效果。
注意,需要在AbstractAdapter抽象类上重写所有的接口方法,如果不实现,那么会在客户端类Client被迫强制实现所有方法,也就与我们的初衷不一样。
|