一,定义
适配器模式:将一个类的接口转换成客户希望的另外一个接口,adapter模式使得原本又有接口不兼容而不能一起工作的哪些类可以一起工作。
简单的说,就是需要的东西就在面前,但却不能使用,而短时间内无法改造他,于是我们就想办法适配它。
在GoF的设计模式中,对适配器模式讲了两种类型,类适配器模式和对象适配器模式。由于类适配器模式通过多重继承对一个接口与另外一个接口进行匹配,而C#,VB.NET,JAVA等语言不支持多重继承,也就是一个类只有一个父类,所以这里我们主要讲的是对象适配模式。
二,示例
NBA教练向球员布置战术,而姚明刚进入NBA英文不太好,听不太懂战术,这个时候需要一个翻译适配器。
public abstract class Player {
protected String name;
public Player(String name){
this.name = name;
}
public abstract void attack();//进攻
public abstract void defense();//防守
}
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 + ",防守!");
}
}
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 + ",防守!");
}
}
public class ForeignCenter {
private String name;
public ForeignCenter(String name){
this.name = name;
}
public void yAttack(){
System.out.println("外籍球员:" + name + ",进攻!");
}
public void yDefense(){
System.out.println("外籍球员:" + name + ",防守!");
}
}
public class TranslatorAdapter extends Player {
private ForeignCenter foreignCenter;
public TranslatorAdapter(String name) {
super(name);
foreignCenter = new ForeignCenter(name);
}
@Override
public void attack() {
foreignCenter.yAttack();
}
@Override
public void defense() {
foreignCenter.yDefense();
}
}
//test main
//适配器模式
public static void adapterModel(){
Player b = new Forwards("巴蒂尔");
b.attack();
Player m = new Center("卡佩拉");
m.defense();
Player y = new TranslatorAdapter("姚明");
y.defense();
}
输入结果:
前锋:巴蒂尔,进攻!
中锋:卡佩拉,防守!
外籍球员:姚明,防守!
三,总结
1,当系统数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配,适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
2,当两个类所做的事情相同或相似,但是具有不同的接口,就可以考虑使用适配器模式。
3,适配器模式有点亡羊补牢的意思,也是无奈之举。如果在设计初级阶段就就把结构设计的统一规范。就可以避免适配。
4,当我们在开发的时候遇到第三方开发组件,而这个组件的接口和我们自己系统的接口不同的时候,我们完全没有必要为了迎合第三方而改动自己的接口。这个时候适配器模式就派上用场了。
参考:《大话设计模式》