结构性---适配器模式

模式概述

  • 作用:如果在系统中存在不兼容的接口,可以通过引入一个适配器来使原本因为接口不兼容,而不能在一起工作的两个类能够协同工作。
  • 定义:适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口适配器模式,让那些接口不兼容的类可以一起工作。
  • 因为结构性模式可以描述两种不同的东西:类和类的实例(对象),根据这一点结构型模式可以分为类结构性模式对象结构性模式
  • 类结构型模式:关心类的组合,由多个类可以组合成一个更大的系统,所以在类结构型模式中一般只存在继承关系和实现关系。
  • 对象结构型模式:关心类与对象的组合,通过关联关系在一个类中定义另一个类的实例对象,然后通过该调该对象调用相应的方法。
  • 根据合成复用原则,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。

模式结构

类适配器模式

在这里插入图片描述

  • Target(目标抽象类):定义客户所需要的接口。
  • Adapter(适配器类):通过实现Target接口并继承Adapter类,使二者产生联系。
  • Adaptee(适配者类):适配者是被适配的角色,他定义了一个已经存在的接口,这个接口需要适配,适配者一般是一个具体类,包含了客户希望使用的业务方法。
  • 由于java不支持多重继承,所以没办法实现类适配器模式。

对象适配器模式

在这里插入图片描述

代码实现

需求:给移动的小汽车增加灯光闪烁和声音提示两个功能。

  • 目标抽象类:CarController 汽车控制类。
package com.daq.classAdapter;
/*
 *    汽车控制类:充当抽象目标类
 */
public abstract class CarController {
	public void move() {
		System.out.println("玩具汽车移动");
	}
	
	public abstract void phonate();//发出声音
	public abstract void twinkle();//灯光闪烁
}
  • 适配者: 喇叭类 & 灯光类
package com.daq.classAdapter;

//喇叭类,充当适配者
public class PoliceSound {
	public void alarmSound() {
		System.out.println("发出警笛声音");
	}
}
package com.daq.classAdapter;

//灯光类,充当适配者
public class PoliceLamp {
	public void alarmLamp() {
		System.out.println("灯光闪烁");
	}
}
  • 适配器类
package com.daq.classAdapter;

//适配器
public class PoliceCarAdapter extends CarController {
	private PoliceSound sound; //定义适配者PoliceSound对象
	private PoliceLamp lamp;   //定义适配者PoliceLamp对象
	
	//构造方法
	public PoliceCarAdapter() {
		sound=new PoliceSound();
		lamp=new PoliceLamp();
	}
	
	//发出警笛声
	@Override
	public void phonate() {
		sound.alarmSound(); //调用适配者类PoliceSound的方法
	}
	
	//灯光闪烁
	@Override
	public void twinkle() {
		lamp.alarmLamp();   //调用适配者类PoliceLamp的方法
	}
}
  • 客户端测试类
package com.daq.classAdapter;

//客户端测试类
public class Client {
	public static void main(String[] args) {
		CarController car;
		car=new PoliceCarAdapter();
		car.move();
		car.phonate();
		car.twinkle();
	}
}
  • 如果需要增加其他的喇叭类或者灯光类,可以增加一个新的适配器类,使用新的适配器来适应新的声音类或者灯光类,原代码无需修改。只需要在客户端更换这个新的适配器类即可。

优缺点

优点:

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构。
  • 增加类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者可以在多个不同的系统中复用。

缺点:

  • 对于java,C#这种不支持多重继承的语言,一次最多只能适配一个适配者类。
  • 适配者不可以是最终类,在java中不能是final类,
  • 与类适配器模式相比,在该模式下要在适配器中置换适配者类的某些方法比较麻烦。

应用场景

  • 系统需要使用一些现有的类,而这些类的接口(例如方法名)不符合系统的需要,甚至没有这些类的源代码。
  • 想创建一个可以重复使用的类,用于和彼此之间没有太大关系的类(包括可能在将来引进的类)一起工作。

猜你喜欢

转载自blog.csdn.net/weixin_44861399/article/details/106051933