先假设一个场景,老王和小王在小霸王上玩魂斗罗,旁边还有围观的小伙伴,
首先,玩的是魂斗罗
1、在启动游戏前,先建立魂斗罗接口
/**
* 魂斗罗的接口
*/
interface Contra {
String playContra();
}
2、魂斗罗功能实现类
/**
* 魂斗罗实现类,模拟功能
*/
class ContraImpl implements Contra {
@Override
public String playContra() {
return "魂斗罗,LOADING...";
}
}
3、创建小霸王的接口
/**
* 创建小霸王的接口
*/
interface GamePlayer {
String playGame(Contra contra);
}
4、实现小霸王的功能
/**
* 实现小霸王的功能
*/
class GamePlayermpl implements GamePlayer {
@Override
public String playGame(Contra contra) {
assert contra != null;
return contra.playContra();
}
}
5、最后,游戏载入
不知不觉从早上玩到了下午,这时,围观的小伙伴说看腻了,要老王换游戏,然后从口袋里掏出了超级玛丽,老王迫不及待的插入超级玛丽的游戏带
6、超级玛丽的接口
/**
* 超级玛丽的接口
*/
interface SuperMarie {
String playSuperMarie();
}
7、新建超级玛丽的功能实现类
/**
* 超级玛丽的功能实现
*/
class SuperMarieImpl implements SuperMarie {
@Override
public String playSuperMarie() {
return "超级玛丽,LOADING...";
}
}
小霸王突然提示游戏不识别,这下把老王犯愁了,这时拿出超级玛丽游戏带的童鞋说上次他玩的时候把游戏机的适配模式调了一下,但是很麻烦,小王这时灵光一闪,要不给游戏带做个适配得了,一会还要换游戏,大家都同意这个想法,于是
8、新建超级玛丽适配类
/**
* 超级玛丽适配类
*/
class GameAdapter implements Contra {
private SuperMarie superMarie;
public GameAdapter(SuperMarie superMarie) {
this.superMarie = superMarie;
}
@Override
public String playContra() {
return superMarie.playSuperMarie();
}
}
9、结果
最后老王和小王还有围观的小伙伴开开心心的玩了起来。
附加:主方法如下:
public class AdapterTest {
public static void main(String[] args) {
// 小霸王玩魂斗罗
GamePlayer gamePlayer = new GamePlayermpl();
System.out.println(gamePlayer.playGame(new ContraImpl()));
// 小霸王通过适配器玩超级玛丽
System.out.println(gamePlayer.playGame(new GameAdapter(new SuperMarieImpl())));
}
}
总结:
这种模式适合的情况:
老的代码无法改动,新的代码需要适应老的接口,那么采用该设计模式可以减少代码耦合度,这也体现出了面向接口编程的优势。
缺陷:1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。