【结构型】- 适配器模式

  适配器模式的定义:将一个类的接口转换成客户希望的另一个接口。适配器让那些接口不兼容的类可以一起工作。

  适配器模式可以分为:类适配器模式、对象适配器模式、接口适配器模式。

  针对前两种适配器模式,下面以播放器为例。老版的播放器(Player)只支持mp4格式的视频文件,而新版的播放器(AdvancedPlayer)在支持mp4的基础上还支持rmvb、avi等格式。实现目标:在不改变老版播放器接口文件的前提下,实现老版的播放器也能支持播放rmvb、avi等格式的视频文件。

类适配器模式

老版播放器

package com.design.pattern.adapter;

public interface Player {

    void play(String audioType, String audioName);
}

老版播放器的实现类

package com.design.pattern.adapter;

public class PlayerImpl implements Player {

    @Override
    public void play(String audioType, String audioName) {
        if("mp4".equalsIgnoreCase(audioType)) {
            System.out.println("【旧版播放器】开始播放mp4格式的视频:"+audioName);
        } else {
            System.out.println("【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:"+audioName);
        }
    }
}

新版播放器接口

package com.design.pattern.adapter;

public interface AdvancedPlayer {

    void playRmvb(String audioName);
    void playAvi(String audioName);
}

新版播放器实现类

package com.design.pattern.adapter;

public class AdvancedPlayerImpl implements AdvancedPlayer {

    @Override
    public void playRmvb(String audioName) {
        System.out.println("【新版播放器】开始播放rmvb格式的视频:"+audioName);
    }

    @Override
    public void playAvi(String audioName) {
        System.out.println("【新版播放器】开始播放avi格式的视频:"+audioName);
    }
}

适配器类

package com.design.pattern.adapter;

// 实现步骤一:实现旧版播放器接口Player,同时继承新版播放器的具体实现。
public class PlayerAdapter extends AdvancedPlayerImpl implements Player {

    @Override
    public void play(String audioType, String audioName) {
        // 实现步骤二:复写播放器的播放方法
        if("rmvb".equalsIgnoreCase(audioType)) {
            super.playRmvb(audioName);
        } else if("avi".equalsIgnoreCase(audioType)) {
            super.playAvi(audioName);
        } else {
            System.out.println("【适配器】开始播放mp4格式的视频:"+audioName);
        }
    }
}

测试类

package com.design.pattern.adapter;

public class Ctest01 {

    public static void main(String[] args) {
        // 旧式的播放器只支持播放mp4格式的视频文件
        Player mp4Player = new PlayerImpl();
        mp4Player.play("mp4", "适配器模式.mp4");
        mp4Player.play("rmvb", "适配器模式.rmvb");
        mp4Player.play("avi", "适配器模式.avi");
        System.out.println("-----------------------------------");
        // 使用[类适配器]后,可以兼容rmvb,avi格式的视频文件
        Player adapterPlayer = new PlayerAdapter();
        adapterPlayer.play("mp4", "适配器模式.mp4");
        adapterPlayer.play("rmvb", "适配器模式.rmvb");
        adapterPlayer.play("avi", "适配器模式.avi");
    }

}

测试结果:

【旧版播放器】开始播放mp4格式的视频:适配器模式.mp4
【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.rmvb
【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.avi
-----------------------------------
【适配器】开始播放mp4格式的视频:适配器模式.mp4
【新版播放器】开始播放rmvb格式的视频:适配器模式.rmvb
【新版播放器】开始播放avi格式的视频:适配器模式.avi

 对象适配器模式

原理:通过组合来实现适配器功能。

对象适配器类

package com.design.pattern.adapter.obj;

import com.design.pattern.adapter.AdvancedPlayer;
import com.design.pattern.adapter.Player;

public class PlayerAdapter implements Player {

    private AdvancedPlayer advancedPlayer;

    public PlayerAdapter(AdvancedPlayer advancedPlayer) {
        this.advancedPlayer = advancedPlayer;
    }

    @Override
    public void play(String audioType, String audioName) {
        if ("mp4".equalsIgnoreCase(audioType)) {
            System.out.println("【适配器】开始播放mp4格式的视频:"+audioName);
        } else if ("avi".equalsIgnoreCase(audioType)) {
            advancedPlayer.playAvi(audioName);
        } else if ("rmvb".equalsIgnoreCase(audioType)) {
            advancedPlayer.playRmvb(audioName);
        }
    }
}

测试类

package com.design.pattern.adapter.obj;

import com.design.pattern.adapter.AdvancedPlayer;
import com.design.pattern.adapter.AdvancedPlayerImpl;
import com.design.pattern.adapter.Player;
import com.design.pattern.adapter.PlayerImpl;

public class Ctest01 {

    public static void main(String[] args) {
        // 旧式的播放器只支持播放mp4格式的视频文件
        Player mp4Player = new PlayerImpl();
        mp4Player.play("mp4", "适配器模式.mp4");
        mp4Player.play("rmvb", "适配器模式.rmvb");
        mp4Player.play("avi", "适配器模式.avi");
        System.out.println("-----------------------------------");
        // 使用[对象适配器]后,可以兼容rmvb,avi格式的视频文件
        AdvancedPlayer advancedPlayer = new AdvancedPlayerImpl();
        Player adapterPlayer = new PlayerAdapter(advancedPlayer);
        adapterPlayer.play("mp4", "适配器模式.mp4");
        adapterPlayer.play("rmvb", "适配器模式.rmvb");
        adapterPlayer.play("avi", "适配器模式.avi");
    }

}

测试结果如下:

【旧版播放器】开始播放mp4格式的视频:适配器模式.mp4
【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.rmvb
【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.avi
-----------------------------------
【适配器】开始播放mp4格式的视频:适配器模式.mp4
【新版播放器】开始播放rmvb格式的视频:适配器模式.rmvb
【新版播放器】开始播放avi格式的视频:适配器模式.avi

接口适配器模式

原理:通过抽象类来实现适配,这种适配稍别于上面所述的适配。

  当存在这样一个接口,其中定义了N多的方法,而我们现在却只想使用其中的一个到几个方法,如果我们直接实现接口,那么我们要对所有的方法进行实现,哪怕我们仅仅是对不需要的方法进行置空(只写一对大括号,不做具体方法实现)也会导致这个类变得臃肿,调用也不方便,这时我们可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空,那么我们在创建抽象类的继承类,而且重写我们需要使用的那几个方法即可。

猜你喜欢

转载自www.cnblogs.com/517cn/p/10878448.html