Java的每一种设计模式都有对应的一种开发情景。一般客户端就是需要调用我们代码的对象,实际开发中客户端可能与你的代码是单独开发的。在这种情况下,会发现现有的类虽然提供了客户端需要的服务,却被定义为不同的方法名,这是,我们就需要运用适配器模式。
适配器模式的意图在于,使用不同接口的类所提供的服务为客户端提供它所期望的接口
类的适配器
代码结构
情景分析
假设现在客户端类 RocketSim 提供了接口,同时我们有类 PhysicalRocket提供的方法类似客户端的功能行为。这是我们可以创建客户端的子类OozinozRocket,同时实现Rocketsim接口。在匹配的时候我们会发现PhysicalRocket拥有客户端需要的信息,但是它的方法并不完全匹配客户端接口声明的功能,所以我们还需要对子类OozinozRocket进行编写。
代码实现
public class OozinozRocket extends PhySicalRocket implements RocketSim{
// 客户端需要一个计时器
private double time;
public OoinozRocket(double burnArea,double burnRate,double fuelMass,double totalMass){
// 直接调用父类的构造器来完成初始化
super(burnArea,burnRate,fuelMass,totalMass);
}
public double getMass(){
// 通过父类方法来给客户端提供信息
return getMass(double b);
}
public double getThrust(){
// 通过父类方法来给客户端提供信息
return getThtust(double b);
}
public void setSimTime(double time){
// 现有类没有类似方法 所以我们需要自己编写方法
this.time = time;
}
}
总结
客户端通过接口提出需要的功能,虽然现有类有方法来满足客户端功能,但方法名却不相同。另外客户端提出的一部分功能我们现有类没法提供。通过适配器模式,我们首先继承现有类并实现客户端接口的方法来满足客户端需求,在此之上编写现有类没有的方法。
对象的适配器
情景分析
在类的适配器中,新的适配类实现了需要的接口,并继承自现有的类。当你需要适配的一组方法并非被定义在接口中,这种方式就不凑效了。此时就可以创建一个对象适配器,他使用的是代理而非继承,设计图如下。
图中的NEWclass类是适配器的一个例子。该类的实例同时也是RequiredClass类的实例。换言之,NewClass类满足了客户端的需要。NewClass类通过使用ExistingClass实例对象,将ExistingClass类适配为符合客户端的需要。
代码结构
代码实现
public class OozinozSkyRocket extends SkyRocket{
private PhysicalRocket rocket;
public OozinozSkyRocket(PhysicalRocket r){
super{
// 通过构造器 完成初始化
r.getMass(0),
r.getThrust(0),
r.getBurnTime());
// 获取类的实例,通过它的方法来提供信息
rocket = r;
}
public double getMass(){
return rocket.getMass(simTime);
}
public double getThrust(){
return rocket.getThrust(simTime);
}
}
类和对象的比较
相比于通过实现接口,运用了对象适配器的类存在一些风险,因为它没有将方法标记为final,使得我们不能防止子类去重写它们。没有接口规范,对象适配器的稳定性很大程度取决与功能类的变化,由于功能类的变化,可能在允许是对象适配器出现编译是无法检测的问题。