Class Adapter概述

Class Adapter - 图1

玩具代码案例 - 电源插座

目标接口的调用者

Usa3PinSocket

当前插座只能使用IUsa3PinPlug接口,不支持IChina2PinPlug接口,我们的目标是让Usa3PinSocket的play方法同样能支持IChina2PinPlug接口。

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.socket;
  2. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
  3. public class Usa3PinSocket {
  4. public void play(IUsa3PinPlug usa3PinPlug) {
  5. usa3PinPlug.runUsa3Pin();
  6. }
  7. }

适配与被适配的类型

IChina2PinPlug

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api;
  2. public interface IChina2PinPlug {
  3. public void runChina2Pin();
  4. }

China2PinPlug

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl;
  2. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
  3. public class China2PinPlug implements IChina2PinPlug {
  4. @Override
  5. public void runChina2Pin() {
  6. System.out.println("I am china 2 pin plug, running");
  7. }
  8. }

IUsa3PinPlug

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api;
  2. public interface IUsa3PinPlug {
  3. public void runUsa3Pin();
  4. }

Usa3PinPlug

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl;
  2. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
  3. public class Usa3PinPlug implements IUsa3PinPlug {
  4. @Override
  5. public void runUsa3Pin() {
  6. System.out.println("I am usa 3 pin plug, running");
  7. }
  8. }

类适配器类型

China2PinPlugToUsa3PinPlugAdapter

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.adapter;
  2. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
  3. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.impl.China2PinPlug;
  4. public class China2PinPlugToUsa3PinPlugAdapter extends China2PinPlug implements IUsa3PinPlug {
  5. @Override
  6. public void runUsa3Pin() {
  7. this.runChina2Pin();
  8. }
  9. }

不基于类适配器模式的实现

重构目标接口的调用者

如果是第三方类我们可能不能修改这些代码

  1. package online.javabook.gof.structural.patterns1.adapter.classadapter.plug.app.bad;
  2. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
  3. import online.javabook.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
  4. public class RefactorUsa3PinSocket {
  5. public void play(IUsa3PinPlug usa2PinPlug) {
  6. usa2PinPlug.runUsa3Pin();
  7. }
  8. // add new api
  9. public void play(IChina2PinPlug china2PinPlug) {
  10. china2PinPlug.runChina2Pin();
  11. }
  12. }

Main

  1. package org.gof.structural.patterns1.adapter.classadapter.app.bad;
  2. import org.gof.structural.patterns1.adapter.classadapter.plug.api.IChina2PinPlug;
  3. import org.gof.structural.patterns1.adapter.classadapter.plug.api.IUsa3PinPlug;
  4. import org.gof.structural.patterns1.adapter.classadapter.plug.impl.China2PinPlug;
  5. import org.gof.structural.patterns1.adapter.classadapter.plug.impl.Usa3PinPlug;
  6. import org.gof.structural.patterns1.adapter.classadapter.socket.Usa3PinSocket;
  7. public class Main {
  8. public static void main(String[] args) {
  9. // 当前实现需要破坏已有类型的实现,如果该类型是第三方库可能无法直接修改
  10. RefactorUsa3PinSocket refactorUsa3PinSocket = new RefactorUsa3PinSocket();
  11. IUsa3PinPlug usa3PinPlug = new Usa3PinPlug();
  12. refactorUsa3PinSocket.play(usa3PinPlug);
  13. // run on new api
  14. IChina2PinPlug china2PinPlug = new China2PinPlug();
  15. refactorUsa3PinSocket.play(china2PinPlug);
  16. }
  17. }

基于类适配器模式的实现

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