模式介绍
在面向开发过程当中,有时候也会存在两个接口之间不兼容的情况,我们引入一个“适配器”的角色,来协调者两种不兼容的情况。这种设计方案就叫做适配器模式。
适配器模式:即定义一个包装类,用于包装不兼容接口的对象
包装类 = 适配器(Adapter)
被包装对象 = 适配者(Adaptee)
示例(购买商品)
当前服务接受其他服务传递过来的对象,不符合我们落地的规范,进行报文转换。
定义一个目标类TargetMessage(目标报文格式)
import com.design.pattern.adapter.bean.TargetBean;
public interface TargetMessage {
TargetBean transfer();
}
public class TargetBean {
/**
* 学生姓名
*/
private String name;
/**
* 总分
*/
private Integer scores;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScores() {
return scores;
}
public void setScores(Integer scores) {
this.scores = scores;
}
}
定义一个适配者类SourceMessage(源报文格式)
public class SourceMessage {
public SourceBean outputSourceMessage() {
SourceBean source = new SourceBean();
source.setName("张三");
List<Course> courses = new ArrayList<>();
Course course1 = new Course("学科一", 90);
Course course2 = new Course("学科二", 95);
Course course3 = new Course("学科三", 94);
courses.add(course1);
courses.add(course2);
courses.add(course3);
source.setCourse(courses);
return source;
}
}
定义一个适配器类Adapter(将源报文转换成目标报文)
import com.design.pattern.adapter.bean.Course;
import com.design.pattern.adapter.bean.SourceBean;
import com.design.pattern.adapter.bean.TargetBean;
import com.design.pattern.adapter.service.TargetMessage;
import java.util.List;
public class Adapter extends SourceMessage implements TargetMessage {
@Override
public TargetBean transfer() {
TargetBean target = new TargetBean();
SourceBean source = this.outputSourceMessage();
List<Course> courses = source.getCourse();
int scores = courses.stream().mapToInt(Course::getCourseScore).sum();
target.setScores(scores);
target.setName(source.getName());
return target;
}
}
测试
public static void main(String[] args) {
Adapter adapter = new Adapter();
TargetBean target = adapter.transfer();
System.out.println(JSON.toJSONString(target));
}
优缺点
优点
- (开闭原则)同一个适配器可以把适配者类和它的子类都适配到目标接口;可以为不同的目标接口实现不同的适配器,而不需要修改待适配类。
- (解耦性)将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
- (更好的扩展性)在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
- (透明、简单)客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单 & 更直接
- (更好的复用性)系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
缺点
- 过多的使用适配器,会让系统非常零乱,不易整体进行把握
- 由于 JAVA 单一继承原则,所以只能适配一个适配者类,而且目标类必须是抽象类。