童年的回忆,现在还有人玩吗?
正如上图,下面的蓝色方块是源接口(Source),而新出现的红色方块就是新接口。我们的目标就是像图中一样,让源接口和新接口完美对接!
但是,如果是如下场景呢?
同样,蓝色的方块是源接口(Source),而新出来的红色方块就是新接口,但是很明显,红色方块与蓝色方块区域无法完成完美对接,那如何让两个接口无缝的贴合呢?如图,我们只需要添加一个黄线区域的形状即可。
黄线区域,其实就是今天的重点 —— 适配器
适配器
系统对接,是现实开发中不可避免的一项操作,而不同的系统之间,数据模型有些许差异也是无法避免的。那这种情况下,如何完成友好的对接呢?
改变现有的数据模型?可以,但不现实,因为这种操作极有可能会影响到系统的稳定性,极不推荐!
适配器模式就是为此而生的。适配器模式就是通过一个适配器类,将一个类接口转换为期望的另一种接口,使得两种或多种原本不兼容的接口之间可以基于适配器类完美运行。
首先,先创建一个最基本的适配器实例
-
定义待适配类:
package com.ambrose.adapterpattern.classadapterpattern; public class Source { public void runOnChrome(){ System.out.println("Chrome 浏览器完美运行"); } }
-
定义适配器接口
package com.ambrose.adapterpattern.classadapterpattern; public interface Targetable { void runOnChrome(); void runOnEdge(); void runOnFirefox(); }
-
定义适配器类,继承待适配类,并实现适配器接口
package com.ambrose.adapterpattern.classadapterpattern; public class Adapter extends Source implements Targetable { @Override public void runOnEdge() { System.out.println("Edge 浏览器完美运行"); } @Override public void runOnFirefox() { System.out.println("Firefox 浏览器完美运行"); } }
-
运行测试:
package com.ambrose.adapterpattern.classadapterpattern; import org.junit.Test; public class TestAdapterPattern { @Test public void adapterPattern(){ Targetable target = new Adapter(); target.runOnChrome(); target.runOnEdge(); target.runOnFirefox(); } }
-
运行结果
代码很简单,实际上,设计模式只是提供一种思路而已,实际应用时根据情景不同,需要进行不同的扩展使用。
接下来,尝试如下修改一下适配器
-
定义待适配类:
package com.ambrose.adapterpattern.interfaceadapterpattern; public class Source { public void runOnChrome(){ System.out.println("Chrome 浏览器完美运行"); } }
-
定义适配器接口
package com.ambrose.adapterpattern.interfaceadapterpattern; public interface Targetable { void runOnChrome(); void runOnEdge(); void runOnFirefox(); }
-
定义适配器类,实现适配器接口,通过带参构造方法,将待适配类作为参数传递给适配器
package com.ambrose.adapterpattern.interfaceadapterpattern; public class Adapter implements Targetable { private Source source; public Adapter(Source source){ this.source = source; } @Override public void runOnChrome() { source.runOnChrome(); } @Override public void runOnEdge() { System.out.println("Edge 浏览器完美运行"); } @Override public void runOnFirefox() { System.out.println("Firefox 浏览器完美运行"); } }
-
运行测试
package com.ambrose.adapterpattern.interfaceadapterpattern; import org.junit.Test; public class TestAdapterPattern { @Test public void adapterPattern(){ Targetable target = new Adapter(new Source()); target.runOnChrome(); target.runOnEdge(); target.runOnFirefox(); } }
-
运行结果
继续,这次,我们使用公用的抽象类实现适配器接口,这样,待适配类就只需要继承这个抽象类并复写其中的方法就可以了,使用更加灵活
-
定义适配器接口
package com.ambrose.adapterpattern.objectadapterpattern; public interface Targetable { void runOnChrome(); void runOnEdge(); void runOnFirefox(); }
-
定义公用的适配器类,实现适配器接口
package com.ambrose.adapterpattern.objectadapterpattern; public abstract class Adapter implements Targetable { @Override public void runOnChrome() { } @Override public void runOnEdge() { } @Override public void runOnFirefox() { } }
-
定义待适配类,按需求实现适配器
package com.ambrose.adapterpattern.objectadapterpattern; public class Source1 extends Adapter { @Override public void runOnChrome(){ System.out.println("Chrome 浏览器完美运行"); } }
package com.ambrose.adapterpattern.objectadapterpattern; public abstract class Adapter implements Targetable { @Override public void runOnChrome() { System.out.println("Chrome 浏览器完美运行"); } @Override public void runOnEdge() { System.out.println("Edge 浏览器完美运行"); } @Override public void runOnFirefox() { System.out.println("Firefox 浏览器完美运行"); } }
-
运行测试
package com.ambrose.adapterpattern.objectadapterpattern; import org.junit.Test; public class TestAdapterPattern { @Test public void adapterPattern(){ Adapter source1 = new Source1(); Adapter source2 = new Source2(); source1.runOnChrome(); source2.runOnEdge(); source2.runOnChrome(); source2.runOnFirefox(); } }
-
运行结果