设计模式之适配器模式

简介

适配器模式(Adapter Pattern):将一个类的接口变换客户端所期待的另一个接口,从而是原本因接口不匹配而无法一起工作的两个类能够在一起工作,通俗的来说就是连接两个不兼容接口之前的桥梁

优点:

  1. 可以让两个没有任何关系的类在一起工作;
  2. 增加了类的透明性;
  3. 提高了类的复用度;
  4. 灵活性非常好。

缺点:

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

类图

类适配器类图:

对象适配器类图:

Target:目标角色;该角色定义把其他类装换为何种接口,也就是我们期望的接口。
Adaptee:源角色
Adapter:适配器角色;该模式的核心。

例:我们有两个播放器,一个只能播放MP3格式的文件,另一个可以播放MP4和AVI的格式。现在,我们希望播放MP3格式的也能播放其他格式,这里就轮到适配器模式出场了。类图如下:

java实现

首先创建两个播放器接口及其实现类:

创建MP4以及AVI的播放器:

    public interface MediaPlayerMA {
        void playMP4(String filename);
        void playAVI(String filename);
    }
public class AVIPlay implements MediaPlayerMA {
        @Override
        public void playMP4(String filename) {

        }

        @Override
        public void playAVI(String filename) {
            System.out.println("play avi :"+filename);
        }
    }
    public class MP4Play implements MediaPlayerMA {
        @Override
        public void playMP4(String filename) {
            System.out.println("play mp4 :"+filename);
        }

        @Override
        public void playAVI(String filename) {

        }
    }

创建MP3的播放器

    public interface MediaPlayMP3 {
        void play(String playType,String filename);
    }


    public class MP3Play implements MediaPlayMP3 {

        @Override
        public void play(String playType, String filename) {
            if (playType.equalsIgnoreCase("mp3")) {
                System.out.println("play avi :" + filename);
            } else if (playType.equalsIgnoreCase("avi") || playType.equalsIgnoreCase("mp4")) {
                //使用扩展的播放
                MediaPlayerAdapter adapter = new MediaPlayerAdapter(playType);
                adapter.play(playType, filename);
            }else {
                System.out.println("don't play :" + filename);
            }
        }
    }

重点:适配器类;这里使用的是对象适配器

    public class MediaPlayerAdapter implements MediaPlayMP3 {
        private MediaPlayerMA mediaPlayerMA;
        //构造函数初始化适配器
         public MediaPlayerAdapter(String playType){
            if(playType.equalsIgnoreCase("avi")){
                mediaPlayerMA = new AVIPlay();
            }else if(playType.equalsIgnoreCase("mp4")){
                mediaPlayerMA = new MP4Play();
            }
        }
        @Override
        public void play(String playType, String filename) {
             //判断应该使用哪种播放器
            if(playType.equalsIgnoreCase("avi")){
                mediaPlayerMA.playAVI(filename);
            }else if(playType.equalsIgnoreCase("mp4")){
                mediaPlayerMA.playMP4(filename);
            }
        }
    }

场景类

    public class Client {
        public static void main(String[] args){
            MediaPlayMP3 mediaPlayMP3 = new MP3Play();
            mediaPlayMP3.play("avi","fs.avi");
            mediaPlayMP3.play("MP3","qwe.mp3");
            mediaPlayMP3.play("mp4","weewe.mp4");
            mediaPlayMP3.play("gif","weewe.gif");
        }
    }

对象适配器与类适配器之间的区别:

类适配器是类间继承,对象适配器是对象的合成关系,也可以说是关联关系。二者在实际开发中都会经常用到,由于对象适配器是通过类间的关联关系进行耦合,因此在设计时就可以做到比较灵活,比如修补源角色的隐形缺陷,关联其他对象等,而类适配器就只能通过复写源角色方法进行扩展,在实际项目中,对象适配器使用的场景相对较多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值