java设计模式-适配器模式

1.适配器模式(Adapter)的定义

  • 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
  • 适配器模式分为:适配器模式、对象适配器模式、接口适配器模式

2.适配器模式的主要优缺点

优点:

  • 客户端通过适配器可以透明地调用目标接口。
  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。

缺点:

  • 对类适配器来说,更换适配器的实现过程比较复杂。

3.适配器模式主要角色

  • 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  • 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  • 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

4.适配器模式结构

  • 类适配器模式结构图

  •  对象适配器模式结构图

5.适配器模式的实现

5.1 类适配器模式实现,已播放电影及切换电影为例

  • 创建美剧电影目标接口
package com.lw.designpattern.adapter.classadapter;

/**
 * @Classname AmericanMovieTarget
 * @Description 美剧电影目标接口
 * @Author lw
 * @Date 2019-12-26 12:58
 */
public interface AmericanMovieTarget {

    /**
     * 播放美剧
     * */
    public void playAmericanMovie();

}
  • 创建韩剧适配者接口
package com.lw.designpattern.adapter.classadapter;

/**
 * @Classname KoreanDramasAdaptee
 * @Description 韩剧适配者接口
 * @Author lw
 * @Date 2019-12-26 13:08
 */
public interface KoreanDramasAdaptee {

    /**
     * 播放韩剧
     */
    public void playKoreanDramas();

}
  • 创建韩剧适配者接口实现
package com.lw.designpattern.adapter.classadapter;

/**
 * @Classname KoreanDramasAdapteeImpl
 * @Description 韩剧适配者接口实现
 * @Author lw
 * @Date 2019-12-26 13:03
 */
public class KoreanDramasAdapteeImpl implements KoreanDramasAdaptee {

    @Override
    public void playKoreanDramas(){
        System.out.println("正在播放韩剧。。。。。。");
    }

}
  • 创建电影适配器类
package com.lw.designpattern.adapter.classadapter;

/**
 * @Classname ClassMovieAdapter
 * @Description 电影适配器
 * @Author lw
 * @Date 2019-12-26 13:01
 */
public class ClassMovieAdapter extends KoreanDramasAdapteeImpl implements AmericanMovieTarget {

    @Override
    public void playAmericanMovie() {
        System.out.println("正在播放美剧。。。。。。");
        System.out.println("开始切换。。。。。。");
        playKoreanDramas();
    }

}
  • 单元测试
  /**
     * 适配器模式-类适配器
     */
    @Test
    public void testClassAdapter(){
        AmericanMovieTarget americanMovie = new ClassMovieAdapter();
        americanMovie.playAmericanMovie();
    }

打印结果

5.2 对象适配器模式实现,已播放电影切换电影为例

  • 创建电影适配器类,相对于类适配器模式实现,稍作改动
package com.lw.designpattern.adapter.objectadapter;

import com.lw.designpattern.adapter.classadapter.AmericanMovieTarget;
import com.lw.designpattern.adapter.classadapter.KoreanDramasAdaptee;

/**
 * @Classname ObjectMovieAdapter
 * @Description 电影适配器
 * @Author lw
 * @Date 2019-12-26 13:01
 */
public class ObjectMovieAdapter implements AmericanMovieTarget {

    private KoreanDramasAdaptee koreanDramas;

    public ObjectMovieAdapter(KoreanDramasAdaptee koreanDramas){
        this.koreanDramas = koreanDramas;
    }

    @Override
    public void playAmericanMovie() {
        System.out.println("正在播放美剧。。。。。。");
        System.out.println("开始切换。。。。。。");
        koreanDramas.playKoreanDramas();
    }

}
  • 单元测试
/**
     * 适配器模式-对象适配器
     */
    @Test
    public void testObjectAdapter(){
        AmericanMovieTarget americanMovie = new ObjectMovieAdapter(new KoreanDramasAdapteeImpl());
        americanMovie.playAmericanMovie();
    }

打印结果

5.3接口适配器模式实现,已播放电影切换电影为例

  • 创建电影目标接口类
package com.lw.designpattern.adapter.interfaceadpter;

/**
 * @Classname MovieTarget
 * @Description 电影目标接口
 * @Author lw
 * @Date 2019-12-26 13:18
 */
public interface MovieTarget {

    /**
     * 播放美剧
     * */
    public void playAmericanMovie();

    /**
     * 播放韩剧
     */
    public void playKoreanDramas();

}
  • 创建电影适配者抽象类,实现MovieTarget接口
package com.lw.designpattern.adapter.interfaceadpter;

/**
 * @Classname AbstractMovieAdaptee
 * @Description 电影适配者抽象类
 * @Author lw
 * @Date 2019-12-26 13:19
 */
public abstract class AbstractMovieAdaptee implements MovieTarget {

    @Override
    public void playAmericanMovie() { }

    @Override
    public void playKoreanDramas() { }

}
  • 创建电影适配器类
package com.lw.designpattern.adapter.interfaceadpter;

/**
 * @Classname InterfaceMovieAdapter
 * @Description 电影适配器
 * @Author lw
 * @Date 2019-12-26 13:21
 */
public class InterfaceMovieAdapter extends AbstractMovieAdaptee {

    @Override
    public void playAmericanMovie() {
        System.out.println("正在播放美剧。。。。。。");
    }

    @Override
    public void playKoreanDramas() {
        System.out.println("开始切换。。。。。。");
        System.out.println("正在播放韩剧。。。。。。");
    }

}
  • 单元测试
/**
     * 适配器模式-接口适配器
     */
    @Test
    public void testInterfacaAdapter(){
        InterfaceMovieAdapter koreanDramasAdapter = new InterfaceMovieAdapter();
        koreanDramasAdapter.playAmericanMovie();;
        koreanDramasAdapter.playKoreanDramas();
    }

打印结果

6.适配器模式的应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。
原文地址:https://www.cnblogs.com/lwcode6/p/12101439.html