Java设计模式-适配器模式

Posted xstxjs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java设计模式-适配器模式相关的知识,希望对你有一定的参考价值。

适配器模式(Adapter Pattern)是一种常见的设计模式,它主要用于在不改变现有系统结构的情况下,将一个类的接口转换成客户端所期望的另一个接口。在本文中,我们将介绍适配器模式的基本概念、实现方法以及优缺点,并探讨适配器模式在Java编程语言中的具体应用。

简介

适配器模式是一种结构型设计模式,它主要通过将一个类的接口转换成客户端所期望的另一个接口,来解决接口不兼容的问题。适配器模式一般包括三个角色:目标(Target)、适配器(Adapter)和被适配者(Adaptee)。其中,目标角色是客户端所期望的接口,适配器角色是将被适配者的接口转换成目标接口的类,被适配者角色是需要被适配的类。

适配器模式与其他设计模式的区别在于,它主要是用于接口转换,而其他模式则主要用于解决其他问题,如工厂模式用于对象创建、单例模式用于对象的唯一性等等。

实现

下面我们通过一个具体的例子来演示如何使用Java编程语言实现适配器模式。假设我们有一个音乐播放器程序,其中包括一个播放MP3音乐的接口MusicPlayer和一个播放CD音乐的接口CdPlayer,而我们想要将CdPlayer适配成MusicPlayer接口,这时就可以使用适配器模式。

首先,我们定义目标接口MusicPlayer:

public interface MusicPlayer 
    public void play(String fileName);

然后,我们定义被适配者接口CdPlayer:

public interface CdPlayer 
    public void playCd(String cdName);

接下来,我们实现一个适配器类CdPlayerAdapter,它实现了目标接口MusicPlayer,并将被适配者接口CdPlayer的playCd方法转换成了目标接口MusicPlayer的play方法。

public class CdPlayerAdapter implements MusicPlayer 
    private CdPlayer cdPlayer;
    
    public CdPlayerAdapter(CdPlayer cdPlayer) 
        this.cdPlayer = cdPlayer;
    
    
    @Override
    public void play(String fileName) 
        cdPlayer.playCd(fileName);
    

最后,我们可以使用适配器类CdPlayerAdapter来播放CD音乐了。

public class Main 
    public static void main(String[] args) 
        CdPlayer cdPlayer = new CdPlayerImpl();
        MusicPlayer musicPlayer = new CdPlayerAdapter(cdPlayer);
        musicPlayer.play("CD_NAME");
    

优缺点

优点:

  1. 增加了类的透明性和复用性。由于适配器模式将目标类和被适配类解耦,使得这些类可以独立地进行变化和复用。
  2. 提高了系统的灵活性。由于适配器模式可以动态地将不兼容的接口转换成兼容的接口,从而使得系统更加灵活。
  3. 可以让客户端调用简单。由于适配器模式将客户端与被适配者分离,客户端只需要面对目标接口,而不需要面对被适配者接口,因此客户端的代码变得简单明了。

缺点:

  1. 增加了系统的复杂性。由于适配器模式需要增加一个适配器类来进行接口转换,因此系统的结构变得更加复杂。
  2. 可能会降低系统的性能。由于适配器模式需要进行额外的接口转换操作,因此可能会降低系统的性能。

运用场景

适配器模式通常适用于以下几种场景:

  1. 系统需要使用一些现有的类,但这些类的接口不符合系统的要求。
  2. 两个或多个独立的系统需要进行协作,但它们的接口不兼容。
  3. 需要在不修改现有代码的情况下,增加或修改一些功能。

在Java编程语言中,适配器模式广泛应用于各种接口的适配,例如数据源适配、日志适配、UI组件适配等等。

总结

适配器模式是一种常见的设计模式,它主要用于解决接口不兼容的问题。在Java编程语言中,适配器模式可以通过实现一个适配器类来进行接口转换,从而增加了类的透明性和复用性,提高了系统的灵活性,并让客户端调用更加简单。然而,适配器模式也存在一些缺点,如增加系统的复杂性和可能会降低系统的性能。适配器模式通常适用于系统需要使用现有类、多个系统需要协作、需要增加或修改功能等场景。

Java描述设计模式(07):适配器模式

本文源码:GitHub·点这里 || GitEE·点这里

一、适配器模式简介

1、基础概念

适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式有类适配器模式和对象适配器模式,以及缺省(接口)适配器,三种不同的形式。

2、生活场景

基于适配器模式,把220V的电压,转换为需要的110V电压。

public class C01_InScene 
    public static void main(String[] args) 
        CurrentAdapter adapter = new CurrentAdapter() ;
        System.out.println(adapter.get110VCurrent()) ;
    

// 220V电流
class Current220V 
    public int get220VCurrent ()
        return 220 ;
    

// 110V电流接口
interface Current110V 
    int get110VCurrent () ;

// 电流适配器
class CurrentAdapter extends Current220V implements Current110V 
    // 电流转换方法
    @Override
    public int get110VCurrent() 
        int high = get220VCurrent() ;
        int low = high/2 ;
        return low ;
    

二、类适配器

1、模式简介

类的适配器模式把适配的类的API转换成为目标类的API。
技术图片

2、核心角色

  • 目标(Target)角色

这就是所期待得到的接口。

  • 源(Adapee)角色:

现在需要适配的接口。

  • 适配器(Adaper)角色

适配器类是本模式的核心。适配器把源接口转换成目标接口。

3、源码实现

interface Target 
    void sampleOperation1();
    void sampleOperation2();

class Adaptee 
    public void sampleOperation1()
        System.out.println("Adaptee.sampleOperation1()");
    

class Adapter extends Adaptee implements Target

    @Override
    public void sampleOperation2() 
        System.out.println("Adapter.sampleOperation2()");
    

三、对象适配器

1、模式简介

与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

技术图片

2、源码实现

interface Target1 
    void sampleOperation1();
    void sampleOperation2();

class Adaptee1 
    public void sampleOperation1()
        System.out.println("Adaptee.sampleOperation1()");
    

class Adapter1 implements Target1 
    private Adaptee1 adaptee ;
    public Adapter1 (Adaptee1 adaptee)
        this.adaptee = adaptee;
    

    public void sampleOperation1() 
        this.adaptee.sampleOperation1();
    

    @Override
    public void sampleOperation2() 
        System.out.println("Adapter.sampleOperation2()");
    

四、接口适配器

1、模式简介

缺省(接口)适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。

技术图片

2、源代码实现

public class C04_AdapterInte 
    public static void main(String[] args) 
        ServiceAdapter adapter = new ServiceAdapter()
            @Override
            public int serviceOperation2() 
                return 22 ;
            
        ;
        System.out.println(adapter.serviceOperation2());
    

interface AbstractService 
    void serviceOperation1();
    int serviceOperation2();
    String serviceOperation3();

class ServiceAdapter implements AbstractService
    @Override
    public void serviceOperation1() 

    
    @Override
    public int serviceOperation2() 
        return 0;
    
    @Override
    public String serviceOperation3() 
        return null;
    

五、Spring框架应用

1、应用场景描述

在SpringMvc执行控制执行请求的时候,有这样一个流程

1)前段控制器DispatcherServlet调用处理器适配器去执行Handler(也就是Controller);
2)处理器适配器去执行Handler,给适配器返回ModelAndView ;
3)处理器适配器向前端控制器返回ModelAndView ;

2、流程分析

  • 核心接口和实现

Controller和HandlerAdapter两核心接口。
技术图片
技术图片

  • HandlerAdapter

适配器接口,使Handler有对应的适配器实现类,适配器代替Handler(控制层Controller)执行相应的方法。

public interface HandlerAdapter 
    // 判断类型是否匹配
    boolean supports(Object var1);
    // 执行方法,返回ModelAndView
    ModelAndView handle(HttpServletRequest var1, 
                        HttpServletResponse var2, Object var3) 
                        throws Exception;

supports()方法传入处理器,判断适配器是否支持,如果支持则返回支持的适配器实现类。

  • DispatchServlert

抽取源码中体现流程的几个步骤。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception 
    HandlerExecutionChain mappedHandler = null;
    mappedHandler = this.getHandler(processedRequest);
    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    mappedHandler.applyPostHandle(processedRequest, response, mv);
  • SimpleControllerHandlerAdapter

最后看下supports和handle两个方法的具体实现。

public class SimpleControllerHandlerAdapter implements HandlerAdapter 
    public SimpleControllerHandlerAdapter() 
    
    public boolean supports(Object handler) 
        return handler instanceof Controller;
    
    public ModelAndView handle(HttpServletRequest request, 
                               HttpServletResponse response, Object handler) 
                               throws Exception 
        return ((Controller)handler).handleRequest(request, response);
    

六、适配器优缺点

1、优点分析

更好的复用性,系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。更好的扩展性。

2、缺点分析

过多的使用适配器,会让系统非常零乱,不易整体进行把控。

七、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

技术图片

以上是关于Java设计模式-适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

Java设计模式-适配器模式

Java与设计模式-适配器模式

Java设计模式——适配器模式

Java描述设计模式(07):适配器模式

Java设计模式(02--适配器模式)

Java设计模式之适配器模式