适配器模式
适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类一起工作。[DP]
简单地说,适配器就是解决需要的东西都在面前,但却不能使用,而短时间又无法改造它,于是就需要适配它。
系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
适配器模式(Adapter)结构图
图片.pngTarget类,这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口
public class Target {
public void request(){
print("普通请求");
}
}
Adaptee类,需要适配的类
public class Adaptee {
public void specialRequest(){
print("特殊请求");
}
}
Adapter类,通过在内部包装一个Adaptee对象,把源接口转换成目标接口
public class Adapter extends Target {
/**
* 建立一个私有的Adaptee对象
*/
private Adaptee adaptee = new Adaptee();
/**
* 表面上调用request()方法变成实际调用specialRequest()
*/
@Override
public void request() {
adaptee.specialRequest();
}
}
测试代码
public class Test {
public static void main(String[] args){
Target target = new Adapter();
target.request();
}
}
何时使用适配器模式
使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。两个类所做的事情相同或相似,但是具有不同的接口,双方都不太容易修改时要使用适配器模式。客户代码可以统一调用同一接口,可以等简单、直接、紧凑。
篮球翻译适配器
情境:模拟火箭队比赛,教练叫暂停时给后卫、中锋、前锋分配进攻和防守任务的代码
球员类
public abstract class Player {
private String name;
public Player(String name){
this.name = name;
}
/**
* 进攻方法
*/
public abstract void attack();
/**
* 防守方法
*/
public abstract void defense();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
中锋、前锋、后卫
public class Center extends Player {
public Center(String name) {
super(name);
}
@Override
public void attack() {
print("中锋"+this.getName()+"进攻");
}
@Override
public void defense() {
print("中锋"+this.getName()+"防守");
}
}
public class Forward extends Player {
public Forward(String name) {
super(name);
}
@Override
public void attack() {
print("前锋"+this.getName()+"进攻");
}
@Override
public void defense() {
print("前锋"+this.getName()+"防守");
}
}
public class Guards extends Player {
public Guards(String name) {
super(name);
}
@Override
public void attack() {
print("后卫"+this.getName()+"进攻");
}
@Override
public void defense() {
print("后卫"+this.getName()+"防守");
}
}
说中文的中锋(需要适配的类)
public class ChineseCenter {
private String name;
public void 进攻(){
print("中文中锋"+this.getName()+"进攻");
}
public void 防守(){
print("中文中锋"+this.getName()+"防守");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
翻译者类(适配器)
public class Translator extends Player {
private ChineseCenter chineseCenter = new ChineseCenter();
public Translator(String name) {
super(name);
chineseCenter.setName(name);
}
@Override
public void attack() {
chineseCenter.进攻();
}
@Override
public void defense() {
chineseCenter.防守();
}
}
测试代码
public class Test {
public static void main(String[] args){
Player b = new Forward("巴蒂尔");
b.attack();
Player m = new Guards("麦迪");
m.attack();
Player ym = new Translator("姚明");
ym.attack();
ym.defense();
}
}
运行结果
图片.png
网友评论