【设计模式】适配器模式

549 阅读2分钟

模式介绍

在面向开发过程当中,有时候也会存在两个接口之间不兼容的情况,我们引入一个“适配器”的角色,来协调者两种不兼容的情况。这种设计方案就叫做适配器模式。

适配器模式:即定义一个包装类,用于包装不兼容接口的对象

包装类 = 适配器(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));
}

image.png

优缺点

优点

  1. (开闭原则)同一个适配器可以把适配者类和它的子类都适配到目标接口;可以为不同的目标接口实现不同的适配器,而不需要修改待适配类。
  2. (解耦性)将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
  3. (更好的扩展性)在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
  4. (透明、简单)客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单 & 更直接
  5. (更好的复用性)系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。

缺点

  1. 过多的使用适配器,会让系统非常零乱,不易整体进行把握
  2. 由于 JAVA 单一继承原则,所以只能适配一个适配者类,而且目标类必须是抽象类。