设计模式之适配器模式

来源:互联网 发布:舰娘国服 知乎 编辑:程序博客网 时间:2024/06/05 19:59

简介

适配器模式(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");        }    }

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

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

原创粉丝点击