1、定义及使用
定义
将一个类的接口转换成客户希望的另外一个接口。
适配器(Adapter)模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
分类
类适配器模式
对象适配器模式
代码实现
球员:
package com.csk.mode.adapter.service;
public abstract class Player {
protected String name;
public Player(String name) {
this.name = name;
}
/**
* 进攻
*/
public abstract void attack();
/**
* 防守
*/
public abstract void defense();
}
前锋:
package com.csk.mode.adapter.service;
public class Forwards extends Player {
public Forwards(String name) {
super(name);
}
@Override
public void attack() {
System.out.println("前锋" + name + "进攻!");
}
@Override
public void defense() {
System.out.println("前锋" + name + "防守!");
}
}
中锋:
package com.csk.mode.adapter.service;
public class Center extends Player {
public Center(String name) {
super(name);
}
@Override
public void attack() {
System.out.println("中锋" + name + "进攻!");
}
@Override
public void defense() {
System.out.println("中锋" + name + "防守!");
}
}
后卫:
package com.csk.mode.adapter.service;
public class Guards extends Player {
public Guards(String name) {
super(name);
}
@Override
public void attack() {
System.out.println("后卫" + name + "进攻!");
}
@Override
public void defense() {
System.out.println("后卫" + name + "防守!");
}
}
翻译者(适配器):
package com.csk.mode.adapter.service;
public class ForeignCenter {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void attack(){
System.out.println("外籍中锋" + name + "进攻!");
}
public void defense(){
System.out.println("外籍中锋" + name + "防守!");
}
}
外籍中锋(被适配者):
package com.csk.mode.adapter.service;
public class Translator extends Player {
private ForeignCenter foreignCenter = new ForeignCenter();
public Translator(String name) {
super(name);
foreignCenter.setName(name);
}
@Override
public void attack() {
foreignCenter.attack();
}
@Override
public void defense() {
foreignCenter.defense();
}
}
执行类:
package com.csk.mode.adapter.controller;
import com.csk.mode.adapter.service.*;
public class AdapterMain {
public static void main(String[] args) {
Player forwards = new Forwards("旭哥");
forwards.attack();
Player center = new Guards("雨哥");
center.attack();
Player guards = new Translator("凯哥");
guards.attack();
}
}
输出结果:
2、角色
目标(Target)
定义一个客户端使用的特定接口。
客户端(Client)
使用目标接口,与和目标接口一致的对象合作。
被适配者(Adaptee)
一个现存需要适配的接口。
适配器(Adapter)
负责将Adaptee的接口转换为Target的接口。适配器是一个具体的类,这是该模式的核心。
3、优缺点
优点:
1、将目标类和适配者类解耦
2、增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性
3、灵活性和扩展性都非常好,符合开闭原则
缺点:
1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2、 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
4、使用场景
1、适用于双方代码都不太容易修改的时候。
2、系统的数据和行为都正确,但是接口不符合时,我们应该优先考虑适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。