zoukankan      html  css  js  c++  java
  • 设计模式(八):适配器模式

    一、概述

      适配器模式将一个类的接口,转换为客户期望的另一个接口。适配器让原本不兼容的类可以合作无间

    二、解决问题

      从模式的定义中,我们看到适配器模式就是用来转换接口,解决不兼容问题的。想想我们现实生活中的适配器,最常用的就是手机充电器了,也叫做电源适配器,它把家用交流强电转换为手机用的直流弱电。其中交流电就是被适配者,充电器是适配器,手机是用电客户。

    三、结构类图

      

    四、成员角色

      客户(Client):只能调用目标接口功能,不能直接使用被适配器,但可以通过适配器的接口转换间接使用被适配器。

      目标接口(Target):客户看到的接口,适配器必须实现该接口才能被客户使用。

      适配器(Adapter):适配器把被适配者接口转换为目标接口,提供给客户使用。

      被适配者(Adaptee):被适配者接口与目标接口不兼容,需要适配器转换成目标接口子类,才能被客户使用。

    五、应用实例

      下面用鸟叫和鸟飞的例子解析适配器模式,鹦鹉会叫也会飞,但鹅就只会叫不会飞,而且鹅也不是鸟类,我们要创建一个适配器,把鹅转换成鸟。

      第一步、创建鸟接口,对应角色目标接口

    package adapter.pattern;
    
    //鸟接口
    public interface Bird {
    	//鸟叫
    	public void chirp();
    	//飞
    	public void fly();
    }
    

      第二步、创建鹦鹉类

    package adapter.pattern;
    
    //鹦鹉类实现鸟接口
    public class Parrot implements Bird{
    
    	public void chirp() {
    		System.out.println("呜呜呜");		
    	}
    
    	public void fly() {
    		System.out.println("我能飞很远很远");		
    	}
    
    }
    

      第三步、创建鹅类,对应角色被适配者

    package adapter.pattern;
    
    //鹅类,不是鸟
    public class Goose {
    	//鹅会叫但不会飞,没有飞的方法
    	public void chirp(){
    		System.out.println("嘎嘎嘎");
    	}
    }
    

      第四步、创建适配器

    package adapter.pattern;
    
    //适配器,把鹅类适配为鸟
    public class GooseAdapter implements Bird{
    	//组合鹅类
    	Goose goose;
    	public GooseAdapter(Goose goose){
    		this.goose = goose;
    	}
    	
    	public void chirp() {
    		if(goose != null){
    			//调用鸟叫的时候委托鹅叫
    			goose.chirp();
    		}
    	}
    
    	public void fly() {
    		//不支持该操作,可以抛出该异常,客户可以知道详情
    		throw new UnsupportedOperationException();
    	}
    
    }
    

      第五步、测试适配器

    package adapter.pattern;
    
    public class AdapterTest {
    	public static void main(String[] args){
    		System.out.println("-----鹦鹉会叫也会飞-----");
    		Bird parrot = new Parrot();
    		parrot.chirp();
    		parrot.fly();
    		
    		System.out.println("-----鹅会叫但不会飞-----");
    		Goose goose = new Goose();
    		Bird gooseAdapter = new GooseAdapter(goose);
    		gooseAdapter.chirp();
    		gooseAdapter.fly();
    		
    		
    	}
    }
    

      运行结果:

      适配器在java中的例子,我们知道ArrayList类实现了迭代器(Iterator),但不支持枚举(Enumeration),下面我们就来实现ArrayList的枚举操作。

    package adapter.pattern;
    
    import java.util.ArrayList;
    import java.util.Enumeration;
    
    public class ItertorEnumeration implements Enumeration{
    	//组合被适配者
    	private ArrayList<String> list;
    	//集合的计数器,判断指针指向集合的位置
    	private int index = 0;
    	public ItertorEnumeration(ArrayList<String> list){
    		this.list = list;
    	}
    	public boolean hasMoreElements() {
    		if(list != null && list.size() > index){
    			return true;
    		}
    		return false;
    	}
    
    	public Object nextElement() {
    		String content = list.get(index);
    		index++;
    		return content;
    	}
    }
    

      

    六、优点和缺点

      1、优点

      (1)、转换接口,适配器让不兼容的接口变成兼容。

      (2)、让客户和实现的接口解耦。有了适配器,客户端每次调用不兼容的接口时,不用修改自己的代码,只要调用适合的适配器就可以了。

      (3)、使用了对象组合设计原则。以组合的方式包装被适配者,被适配者的任何子类都可以搭配着同一个适配器使用。

      (4)、体现了“开闭”原则。适配器模式把客户和接口绑定起来,而不是和具体实现绑定,我们可以使用多个配适器来转换多个后台类,也可以很容易地增加新的适配器。

      2、缺点

      (1)、每个被适配者都需要一个适配器,当适配器过多时会增加系统复杂度,降低运行时的性能。

      (2)、实现一个适配器可能需要下一番功夫,增加开发的难度。

    七、使用场景

      1、当要使用的两个类所做的事情相同或者相似,但是具有不同的接口时考虑使用配适器模式。

      2、当需要统一客户端调用接口的代码,而所调用的接口具有不兼容问题时使用适配器模式。这样客户端只有调用一个接口就行了,这样可以更简单、更直接、更紧凑。

    八、总结

      1、适配器有对象适配器和类适配器,类适配器需要用到多重继承。

      2、适配器就是转换接口达到我们的需要。

  • 相关阅读:
    量子计算机算法与应用研究论文(转载务必注明出处)
    [置顶] html学习笔记,锚点,超链接,table布局,表头,h,sub,blockquote,ul,li,ol.dl,加入收藏,打印,弹出窗口
    [置顶] 第一天初试linux
    [置顶] Datalist嵌套datalist,页面传值,加密,数据绑定
    [置顶] asp.net(c#)中相对路径(虚拟路径)和物理磁盘路径的转换
    [置顶] c#对于文件的操作
    [置顶] 读取pdf并且在web页面中显示
    [置顶] gridview中嵌套gridview(并实现子gridview的数据绑定),页面传值,加密,数据绑定
    git的使用学习笔记--项目版本操作
    git的使用学习笔记---合并分支
  • 原文地址:https://www.cnblogs.com/jenkinschan/p/5746005.html
Copyright © 2011-2022 走看看