Class Adapter概述
玩具代码案例 - 电源插座
目标接口的调用者
Usa3PinSocket
当前插座只能使用IUsa3PinPlug接口,不支持IChina2PinPlug接口,我们的目标是让Usa3PinSocket的play方法同样能支持IChina2PinPlug接口。
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.socket;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
public class Usa3PinSocket {
public void play(IUsa3PinPlug usa3PinPlug) {
usa3PinPlug.runUsa3Pin();
}
}
适配与被适配的类型
IChina2PinPlug
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api;
public interface IChina2PinPlug {
public void runChina2Pin();
}
China2PinPlug
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
public class China2PinPlug implements IChina2PinPlug {
@Override
public void runChina2Pin() {
System.out.println("I am china 2 pin plug, running");
}
}
IUsa3PinPlug
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api;
public interface IUsa3PinPlug {
public void runUsa3Pin();
}
Usa3PinPlug
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
public class Usa3PinPlug implements IUsa3PinPlug {
@Override
public void runUsa3Pin() {
System.out.println("I am usa 3 pin plug, running");
}
}
类适配器类型
China2PinPlugToUsa3PinPlugAdapter
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.adapter;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl.China2PinPlug;
public class China2PinPlugToUsa3PinPlugAdapter extends China2PinPlug implements IUsa3PinPlug {
@Override
public void runUsa3Pin() {
this.runChina2Pin();
}
}
不基于类适配器模式的实现
重构目标接口的调用者
如果是第三方类我们可能不能修改这些代码
package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.app.bad;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
public class RefactorUsa3PinSocket {
public void play(IUsa3PinPlug usa2PinPlug) {
usa2PinPlug.runUsa3Pin();
}
// add new api
public void play(IChina2PinPlug china2PinPlug) {
china2PinPlug.runChina2Pin();
}
}
Main
package org.gof.structural.patterns1.adapter.classadapter.app.bad;
import org.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.plug.impl.China2PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.plug.impl.Usa3PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.socket.Usa3PinSocket;
public class Main {
public static void main(String[] args) {
// 当前实现需要破坏已有类型的实现,如果该类型是第三方库可能无法直接修改
RefactorUsa3PinSocket refactorUsa3PinSocket = new RefactorUsa3PinSocket();
IUsa3PinPlug usa3PinPlug = new Usa3PinPlug();
refactorUsa3PinSocket.play(usa3PinPlug);
// run on new api
IChina2PinPlug china2PinPlug = new China2PinPlug();
refactorUsa3PinSocket.play(china2PinPlug);
}
}
基于类适配器模式的实现
Main
package org.gof.structural.patterns1.adapter.classadapter.app.good;
import org.gof.structural.patterns1.adapter.classadapter.plug.adapter.China2PinPlugToUsa3PinPlugAdapter;
import org.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.plug.impl.Usa3PinPlug;
import org.gof.structural.patterns1.adapter.classadapter.socket.Usa3PinSocket;
public class Main {
public static void main(String[] args) {
Usa3PinSocket usa3PinSocket = new Usa3PinSocket();
IUsa3PinPlug usa3PinPlug = new Usa3PinPlug();
usa3PinSocket.play(usa3PinPlug);
// 使用类适配器
IUsa3PinPlug adapter = new China2PinPlugToUsa3PinPlugAdapter();
usa3PinSocket.play(adapter);
}
}
Console
I am usa 2 pin plug, running
I am china 2 pin plug, running