java 设计模式-缺省适配器模式

本文转载地址:http://www.cnblogs.com/iyangyuan/archive/2013/03/11/2954808.html

在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现。

今天小菜提到的“抽象接口”,就是用来解决这个问题的。

为了不误导读者,先说明一下,什么是“抽象接口”。

所谓“抽象接口”,即在提供接口的同时,提供一个抽象类,用抽象类实现该接口(实际上这是缺省适配模式)。

下面小菜举个例子,让读者体会这样做的好处。

代码写的不咋地,为了防止读者看不懂,先上一张类图:

具体代码:

  ITestInterface.java

1 /*
2     假设有一个顶层接口
3 */
4 public interface ITestInterface{
5     void method1();
6     int method2();
7     boolean method3();
8 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */
 4
 5 public abstract class TestAbstract implements ITestInterface{
 6     //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现
 7     public abstract void method1();
 8     public abstract int method2();
 9
10     //一些独特的方法可以在抽象类中默认实现
11     public boolean method3(){
12         return true;
13     }
14 }

  

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass1 extends TestAbstract{
 6
 7     //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 1;
14     }
15
16     //接口中的method3方法对于TestClass1无关紧要,因此不做重写。
17 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass2 extends TestAbstract{
 6
 7     //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 2;
14     }
15
16     //method3方法对于TestClass2来说至关重要,因此必须重写。
17     public boolean method3(){
18         return false;
19     }
20
21 }

代码精讲:

    从以上例子可以看出,最高层的接口被一个抽象类实现,在抽象类中,我们把关键的method1、method2方法定义成抽象方法,强制子类去实现,而“独特”的method3方法在抽象类中做一个默认实现。

    等到TestClass1、TestClass2继承TestAbstract抽象类时,优势就体现出来了,TestClass1、TestClass2必须实现method1、method2,但如果用不到method3,可以直接无视。

    通过接口和抽象类的结合,避免了在实现接口的子类中出现大量的“无意义”实现,这个“无意义”实现,被缓冲到了抽象类中,完美展现了代码复用(可以把抽象类理解成接口和实现类之间的缓冲)。

    需要指出的是,我们既可以选择继承抽象类,也可以选择实现接口,并不是说一定要继承抽象类,看情况而定,这里是两种选择,两个机会。

写到这,或许读者觉得文章已经结束了,其实没有。。。

这样做的好处不仅仅是这一点,细细品味,假如我们向接口中增加了一个方法。。。

具体代码:

  温馨提示:不要被代码吓到,其实这些代码和上边的差不多,只不过加了个方法而已。

  ITestInterface.java

 1 /*
 2     假设有一个顶层接口
 3 */
 4 public interface ITestInterface{
 5     void method1();
 6     int method2();
 7     boolean method3();
 8     //接口中新增加了方法
 9     String method4();
10 }

  TestAbstract.java

 1 /*
 2     抽象类abstract实现了ITestInterface顶层接口
 3 */
 4
 5 public abstract class TestAbstract implements ITestInterface{
 6     //找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现
 7     public abstract void method1();
 8     public abstract int method2();
 9
10     //一些独特的方法可以在抽象类中默认实现
11     public boolean method3(){
12         return true;
13     }
14
15     //抽象类中提供一个默认实现,这样就可以避免"惊动"所有子类
16     public String method4(){
17         return "";
18     }
19 }

  TestClass1.java

 1 /*
 2     普通类TestClass1继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass1 extends TestAbstract{
 6
 7     //TestClass1必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass1必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 1;
14     }
15
16     //接口中的method3方法对于TestClass1无关紧要,因此不做重写。
17
18     //新增的方法对于TestClass1来说至关重要,因此必须重写
19     public String method4(){
20         return "Class1";
21     }
22
23 }

  TestClass2.java

 1 /*
 2     普通类TestClass2继承了TestAbstract抽象类
 3 */
 4
 5 public class TestClass2 extends TestAbstract{
 6
 7     //TestClass2必须实现抽象的method1方法,该方法最早是接口中定义的
 8     public void method1(){
 9
10     }
11     //TestClass2必须实现抽象的method2方法,该方法最早是接口中定义的
12     public int method2(){
13         return 2;
14     }
15
16     //method3方法对于TestClass2来说至关重要,因此必须重写。
17     public boolean method3(){
18         return false;
19     }
20
21     //新增的方法对于TestClass2来说无关紧要,无需知道新增method4的存在
22 }

代码精讲:

    这段代码演示了假如项目已经成型,但是需求有变,我们不得不向接口中增加一个新的方法,假如子类直接实现了接口,那么这些子类都要修改,来实现接口新增的方法。

    但本例中的TestClass1、TestClass2子类没有直接实现接口,而是通过继承抽象类间接实现接口,这样好处一下就体现出来了!

    向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。

小菜感慨:

    人类的智慧真伟大!数组和链表结合,产生了高效的哈希表;接口和抽象类结合,产生了优雅的缺省适配模式。大家努力吧!!!

写在后面的话:

    世间没有完美的事物,设计模式也是如此,过多的讨论优缺点没有意义,合适的就是最好的,什么是合适的呢?这才是体现智慧的地方。

时间: 2025-01-31 21:45:13

java 设计模式-缺省适配器模式的相关文章

Java设计模式--缺省适配器模式

我认为这个模式比较常见,还记得我们学习Swing的时候吗,有没有见过很多Adapter?那时候不知道Adapter的意义所在,但至少知道他能够省去我们不需要的实现. 这个社会有N中职业(job),但是每个人(people)只可能从事其中一种或者几种,职业类型设成一个接口,难道每次给人设置职业的时候要全部实现吗?在这里就要有一个缺省适配器,缺省适配器是个抽象类,仅仅implements而不实现.然后客户端直接使用Adapter即可选择需要实现的方法,而不用实现全部. Job package com

设计模式--缺醒适配器模式

http://www.cnblogs.com/xwdreamer/archive/2012/03/29/2424008.html在没有好好地研习面向对象设计的设计模式之前,我对Java接口和Java抽象类的认识还是很模糊,很不可理解. 刚学Java语言时,就很难理解为什么要有接口这个概念,虽说是可以实现所谓的多继承,可一个只有方法名,没有方法体的东西,我实现它又有什么用呢?我从它那什么也得不到,除了一些方法名,我直接在具体类里加入这些方法不就行了吗? 为什么一定要有抽象类这个概念?为什么就不能把

设计模式:缺省适配器模式

原创:http://leihuang.org/2014/12/06/default-adapter/ Structural 模式 如何设计物件之间的静态结构,如何完成物件之间的继承.实 现与依赖关系,这关乎着系统设计出来是否健壮(robust):像是易懂.易维护.易修改.耦合度低等等议题.Structural 模式正如其名,其分类下的模式给出了在不同场合下所适用的各种物件关系结构. Default Adapter 模式 Adapter 模式 Bridge 模式 Composite 模式 Deco

《JAVA设计模式》之适配器模式

<JAVA与模式>之适配器模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 下面是两个非常形象的例子

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

源码均以JDK1.8作为参考 1.定义: 将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 2.解析: Adapter Pattern又称为Wrapper Pattern,提到Adapter Pattern,最先会想到的可能就是电源适配器,例如一台12V的电脑需要改到家用220V交流电源上使用,就需要使用交流电适配器,对电源进行转换. 在Java语言中,就是为了将现有类进行包装或适配来完成既有功能. 通用类图: 类图解析: 2.1.Cl

java设计模式 GOF23 05 适配器模式

一.适配器模式简介 java中一个类想要使用与自己毫不相干的另一个对象时,最简单的方法是使用适配器模式. 下面是简单代码实现: package com.lz.adapter; /* * 被适配对象 */ public class Adaptee { public void request() { System.out.println("提供相关服务."); } } package com.lz.adapter; /* * 实现了适配接口的适配器 */ public class Adap

JAVA设计模式初探之适配器模式

http://blog.csdn.net/jason0539/article/details/22468457 1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 下面是两个非常形象的例子 3. 模式中的角色 3.1 目标接口(Target):客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口. 3.2 需

java 设计模式初探之适配器模式

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

java设计模式-----15、适配器模式

概念: Adapter模式也叫适配器模式,是构造型模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式. 举个例子:我们使用电脑,家里的电源是220V的,而我们的电脑是18V的,这时如果我们直接把电源连接电脑,一定会导致电脑被烧坏,因为电源电压太高了,这时我们就需要一个电源适配器,连接在电源与电脑之间,通过适配器进行一个降压,来保证电脑的正常工作. 增加适配器 用代码实现: 首先如果不使用适配器的话 新建一个220V电源 1 //220V电源 2 public class Pow