设计模式(六) 适配器模式(Adapter)

开发当中我们经常遇到这样的情况:有一些功能自己开发需要花费巨大的成本,但是现存的可供使用的第三方库还不太成熟,我们可以暂时使用这些库。但是,一旦需要修改依赖库的时候,源码也需要大规模地修改,有没有什么方法能够最大限度地降低修改的幅度呢?这时候我们可以考虑使用adapter模式。

一、定义

适配器模式是一种结构型模式。它的目的是使一个类的接口转换成客户希望的另一种接口,适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。

二、结构

适配器模式有两种类型

1.对象适配器模式

在这种模式中,适配器类包含适配对象的实例,这样适配器类就可以调用适配对象的方法了。

2.类适配模式

这种类型的适配器通过多重继承或者实现多个现存的和期望实现(兼容)的类/接口。对于java这种不支持多重继承的语言,一般将待适配的对象声明为Interface。

参数说明:

Target : Client使用的现存的类/接口

Adaptee : 待适配的类/接口

Adapter : 实现Target与Adaptee适配的类

三、适用性

  • 想使用一个已经存在的类,但是它的接口不符合你的需求

四、举例

最后让我们来看一个例子,假设我们有个MediaPlayer的Interface,包含play()抽象方法,AudioPlayer实现了MediaPlayer方法,默认play()的是mp3的格式。还有一个AdvancedMediaPlayer的接口,包含playAvi()和playMp4()两个抽象方法,AviPlayer和Mp4Player实现了AdvancedMediaPlayer。现在如果想让AudioPlayer也能支持mp4和avi两种格式的播放,应该怎么办?这里我们可以使用对象适配模型,创建一个MediaAdapter的类,在其中包含一个AdvancedMediaPlayer的类实例,这样就可以调用它的子类方法了。然后给AudioPlayer增添一个MediaPlayer的实例,判断一下输入音乐格式,做出不同的操作就行了。

下面贴代码:

MediaPlayer:

package designpattern.adapter;

public interface MediaPlayer {
	public void play(String audioType, String fileName);
}

AdvancedMediaPlayer:

package designpattern.adapter;

public interface AdvancedMediaPlayer {
	public void playAvi(String fileName);
	public void playMp4(String fileName);
}

AviPlayer:

package designpattern.adapter;

public class AviPlayer implements AdvancedMediaPlayer {

	@Override
	public void playAvi(String fileName) {
		// TODO Auto-generated method stub
		System.out.println("Playing avi , file name is "+fileName);

	}

	@Override
	public void playMp4(String fileName) {
		// TODO Auto-generated method stub

	}

}

Mp4Player:

package designpattern.adapter;

public class Mp4Player implements AdvancedMediaPlayer {

	@Override
	public void playAvi(String fileName) {
		// TODO Auto-generated method stub

	}

	@Override
	public void playMp4(String fileName) {
		// TODO Auto-generated method stub
		System.out.println("Playing mp4, file name is"+fileName);

	}

}

MediaAdapter:

package designpattern.adapter;

public class MediaAdapter implements MediaPlayer {

	private AdvancedMediaPlayer advancedMediaPlayer;

	public MediaAdapter(String audioType){
		if(audioType.equalsIgnoreCase("mp4")){
			advancedMediaPlayer = new Mp4Player();
		}else if(audioType.equalsIgnoreCase("avi")){
			advancedMediaPlayer = new AviPlayer();
		}else{
			throw new IllegalArgumentException("unrecognized AdvancedMediaPlayer type");
		}
	}

	@Override
	public void play(String audioType, String fileName) {
		// TODO Auto-generated method stub
		if(audioType.equalsIgnoreCase("avi")){
			advancedMediaPlayer.playAvi(fileName);
		}else if(audioType.equalsIgnoreCase("mp4")){
			advancedMediaPlayer.playMp4(fileName);
		}else{
			throw new IllegalArgumentException("unrecognized audio type for advancedMediaPlayer");
		}
	}

}

AudioAdapter:

package designpattern.adapter;

public class AudioPlayer implements MediaPlayer {

	private MediaAdapter mediaAdapter;

	@Override
	public void play(String audioType, String fileName) {

		if (audioType.equalsIgnoreCase("mp3")) {
			System.out.println("Playing mp3, file name is " + fileName);
		} else if (audioType.equalsIgnoreCase("mp4")
				|| audioType.equalsIgnoreCase("avi")) {
			mediaAdapter = new MediaAdapter(audioType);
			mediaAdapter.play(audioType, fileName);
		}else{
			System.out.println("unrecognized audio format");
		}

	}

}

测试类,MediaDemo:

package designpattern.adapter;

public class MediaDemo {
	public static void main(String[] args) {
		MediaPlayer player = new AudioPlayer();
		player.play("mp3","1.mp3");
		player.play("mp4","2.mp4");
		player.play("avi","3.avi");
		player.play("mpg","4.mpg");
	}
}

控制台输出:

Playing mp3, file name is 1.mp3
Playing mp4, file name is2.mp4
Playing avi , file name is 3.avi
unrecognized audio format

参考文献:

1.维基百科:Adapter Pattern

2.design_pattern adapter_pattern

3.java最优良的adapter模式,适配器模式

时间: 2024-10-13 12:04:50

设计模式(六) 适配器模式(Adapter)的相关文章

设计模式之适配器模式(Adapter Pattern)

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 1. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 模式中的角色 2.1 目标接口(Target):客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口. 2.2 需要适配的类(Adaptee):需要适配的类或适配者类. 2.3 适配器(Adapter):通过包装一个需要适配的对象,把

Java设计模式之适配器模式(Adapter Pattern)

Adapter Pattern的作用是在不改变功能的前提下转换接口.Adapter分为两类,一类是Object Adapter, 另一类是Class Adapter.由于Class Adapter的实现需要用到多继承,而Java不支持多继承,所以这里只关注Object Adapter. 在JDK1.5之前是没有 java.util.Iterator 接口的,java.util.Enumeration 接口起着 Iterator 的作用.那么如果我们需要维护一些年代比较久远的代码,可能就会面临着没

如何让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

如何让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 概念相关 定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而 使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 简单点说: 两个彼此间没有太大关联的类,想进行交互完成某些事情,如果 直接去修改各自的接口,就显得有些繁琐了,可以加个中间类, 用它来协调两类之间的关系,完成相关业务.这种玩法就叫适配器模式! 两种适配器模式: 根据适配器类与适配者类的关系不同,适配器模式可分为 类适配器 和 对

设计模式之适配器模式(Adapter)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

二十四种设计模式:适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 示例有一个Message实体类,某个类对它的操作有Insert()和Get()方法.现在需要把这个类转到另一个接口,分别对应Add()和Select()方法. MessageModel using System; using System.Collections.Generic; using System.Text; name

JavaScript设计模式 Item9 --适配器模式Adapter

适配器模式(转换器面模式),一般是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况.适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作.速成包装器(wrapper). 适配器的别名是包装器(wrapper),这是一个相对简单的模式.在程序开发中有许多这样的场景:当我们试图

Java设计模式之适配器模式(Adapter)

转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.      (太官方了,不太好理解, 其实就是要用到两个不相关的类/接口,但是又没有源代码,或者不想修改源代码,而增加一个类来完成合并使用的目的) 2.实现这个目的有两个方法,继承或者组合 2.1.使用继承(就是所谓的类适配器模式) 2.2.使用组合(所谓的对象适配器模式)

设计模式之适配器模式 adapter 适配器模式分类概念角色详解 类适配器 对象适配器 接口适配器 双向适配器

现实世界中的适配器模型 先来看下来几个图片,截图自淘宝 上图为港版的插头与港版的插座 上图为插座适配器卖家的描述图 上图为适配后的结果 现实世界中适配器模式 角色分类 这就是适配器模式在电源插座上的应用 我们看下在插座适配器中的几个重要角色 可以看得出来,大陆和港版插座面板,都是作为电源的角色,他们的功能是相似的或者说相近的 插头要使用插座,进而接通电流 现实世界到代码的转换 电源插座代码示例 港版插座面板 package adapter; /**目标角色 Target 接口 * 香港地区使用的

【设计模式】—— 适配器模式Adapter

前言:[模式总览]——————————by xingoo 模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一种现有的接口编程另一种可用的接口. 模式结构 [类的适配器] Target 目标接口 Adaptee 现有的类 Adapter 中间转换的类,即实现了目标接口,又继承了现有的类. 1 package com.xingoo.test1; 2 interface Target{ 3 public voi

设计模式之适配器模式 Adapter

从现在开始,将转入设计模式中的结构型模式 定义与角色 工作场景 代码实现 /** * 被适配的类--相当于键盘 * @author bzhx * 2017年3月10日 */ public class Adaptee { public void request(){ System.out.println("可以完成客户请求的需要的功能"); } } Adaptee类 public interface Target { void handleReq(); } Target 接口 /** *