设计模式:结构型模式:适配器模式

185 阅读3分钟

适配器模式

  1. 一般用于适配已经存在拥有特殊功能的类,但是不符合我们预期 interface。
  2. 所以可以搞一个 这个特殊功能的子类, 并且 implements 这个 预期 interface。

概述

  1. 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示, 主要的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,其别名为包装器(Wrapper);
  2. 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式。

类适配器 (继承)

  1. 现在我们有一个电脑类,它默认只能接入Usb接口功能的设备。
public interface Usb {
    /**
     * 提供Usb 功能
     */
    void providerUsbSomething();
}

// usb 设备的 具体实现类,提供usb 功能
public class UsbPhone implements Usb {

    @Override
    public void providerUsbSomething() {
        System.out.println("提供 usb 手机的 功能");
    }
}

public class Computer {
    /**
     * 电脑 默认可以接入 Usb功能
     * @param usb
     */
    void input(Usb usb) {
        usb.providerUsbSomething();
    }
}
  1. 现在我们有一个Typec的设备,则无法直接接入到电脑上使用
public interface TypeC {

    /**
     * 提供Typec 功能
     */
    void providerTypecSomething();
}

//  已存在的、具有特殊功能、但不符合我们既有的标准接口的类
//  这个类 也可以是一开始就没有接口,只有一个类
public class TypeCPhone implements TypeC {
    @Override
    public void providerTypecSomething() {
        System.out.println("提供Typec 功能的手机");
    }
}
  1. 我们则需要一个类适配器,来转换成Usb的接口实现类,传递给电脑使用
    • 适配器类 可以继承要被适配的类,并且实现使用方需要的的接口
    • 此例中,adapater类可 继承 Typec的具体实现类,并实现Usb接口
// 电脑需要Usb,适配器 继承 TypeCPhone 实现 Usb 功能
// 内部再调用 Typec提供的功能
public class USBAdapter extends TypeCPhone implements Usb {
    @Override
    public void providerUsbSomething() {
        this.providerTypecSomething();
    }
}

适配器包含三种角色

  1. Target(目标接口):客户端所需要的接口,可以是接口或抽象类,也可以是实体类。(Usb)
  2. Adaptee(需要适配的类):被适配者。 (TypeC的类)
  3. Adapter(适配器):把原接口转化成目标接口的类。

对象适配器 (组合)

  1. 类适配器 需要继承 自被适配的类,产生了耦合度较高的问题,由此,我们常用的适配器模式是对象适配器。
  2. 基本思路和类的适配器模式相同,只是将 Adapter 类做修改。
  3. 不是继承 TypecPhone 类,而是持有 TypecPhone 类的实例,以解决兼容性的问题。
public class USBAdapter implements Usb {
    
    // 原来 需要被适配的对象
    private TypeC typeC;
    
    @Override
    public void providerUsbSomething() {
        typeC.providerTypecSomething();
    }
}

接口适配器, 缺省适配器 (使用最多)

  1. 当一个接口,存在多个方法, 而我们可能只用到其中一个方法,却不想重写所有的方法,
  2. 此时,我们可以构建一个中间的 抽象类,提供空实现。
//Target接口
interface TestInterface {
	
	void testMethod1();
	void testMethod2();
	void testMethod3();
	void testMethod4();
	void testMethod5();
}

//适配器角色, 实现所有接口的方法,提供空实现
abstract class AbsClass implements TestInterface{
	/* (non-Javadoc)
	 * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod1()
	 */
	@Override
	public void testMethod1() {
		
	}
	
	
	@Override
	public void testMethod2() {
		
	}

	/* (non-Javadoc)
	 * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod3()
	 */
	@Override
	public void testMethod3() {
		
	}

	/* (non-Javadoc)
	 * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod4()
	 */
	@Override
	public void testMethod4() {
		
	}

	/* (non-Javadoc)
	 * @see com.powernode.designpattern.day04.part2.interfaceadapter.TestInterface#testMethod5()
	 */
	@Override
	public void testMethod5() {
		
	}
}

//  这样就方便使用了
    public static void main(String[] args) {
    	//在某处需要使用到TestInterface的实现类
    	test(new AbsClass() {
    		
    		@Override
    		public void testMethod3() {
				// TODO Auto-generated method stub
				super.testMethod3();
			}
		});
	}

源码中的适配器模式

  1. InputStreamReader 通过对字节流的适配器, 对象适配器
    • client想使用的是一个可以操作字符的流,所以将字节流采用适配器的模式加强了。
    FileInputStream fileInputStream = new FileInputStream("");
    InputStreamReader reader = new InputStreamReader(fileInputStream);
  1. SpringMVC 中 handlerAdpater