注:示例来自《大话设计模式》
假如现有如下场景 篮球比赛 教练叫暂停时给后卫 中锋 前锋分配进攻和防守任务 简单代码实现如下
球员类
package Test17;
//篮球运动员
public abstract class Player {
protected String name;
public Player(String name)
{
this.name = name;
}
public abstract void Attack();
public abstract void Defense();
}
前锋 中锋 后卫类
package Test17;
//前锋
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 Test17;
//中锋
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 Test17;
//后卫
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 Test17;
public class Program {
public static void main(String[] args) {
Player b = new Forwards("巴蒂尔");
b.Attack();
Player m = new Guards("麦克格雷迪");
m.Attack();
Player ym = new Center("外籍中锋");
ym.Attack();
ym.Defense();
}
}
假如外籍中锋不会英语 听不懂教练说的英语进攻 防守 我们需要有翻译者类来适配 接下来我们使用适配器模式进行重构 代码如下
外籍中锋类
package Test17;
//外籍中锋
public class ForeignCenter {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void 进攻()
{
System.out.println("外籍中锋 "+name+" 进攻");
}
public void 防守()
{
System.out.println("外籍中锋 "+name+" 防守");
}
}
翻译者类
package Test17;
//翻译者
public class Translator extends Player {
private ForeignCenter wjzf = new ForeignCenter();
public Translator(String name) {
super(name);
wjzf.setName(name);
}
@Override
public void Attack()
{
wjzf.进攻();
}
@Override
public void Defense()
{
wjzf.防守();
}
}
客户端代码
package Test17;
public class Program {
public static void main(String[] args) {
Player b = new Forwards("巴蒂尔");
b.Attack();
Player m = new Guards("麦克格雷迪");
m.Attack();
//Player ym = new Center("外籍中锋");
Player ym = new Translator("外籍中锋");
ym.Attack();
ym.Defense();
}
}
适配器模式 将一个类的接口转换成客户希望的另外一个接口 适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
在软件开发中 也就是系统的数据和行为都正确 但接口不符时 我们应该考虑用适配器 目的是使控制范围之外的一个原有对象与某个接口匹配 适配器模式主要应用于希望复用一些现存的类 但是接口又与复用环境要求不一致的情况
在想使用一个已经存在的类 但如果它的接口 也就是它的方法和你的要求不相同时 就应该考虑用适配器模式
两个类所做的事情相同或相似 但是具有不同的接口时要使用它 这样客户代码统一调用同一接口就行了 可以更简单 更直接 更紧凑
在双方都不太容易修改的时候再使用适配器模式适配
缺点 对于对象适配器来说 更换适配器的实现过程比较复杂