zoukankan      html  css  js  c++  java
  • 设计模式之缺省适配模式

    0.参考文献

    参考1:http://tkhhappyboy.blog.163.com/blog/static/114185815201112473727410/

    参考2:http://milenfan.iteye.com/blog/756060

    参考3:http://java.chinaitlab.com/model/758440.html

    参考4:http://www.the2ndmoon.net/weblog/?p=212

    1.概述

    缺省适配模式为一个接口提供缺省实现(本例中接口InterfaceA的缺省实现是AbstractClassB),这样的类型可以从这个缺省实现(AbstractClassB)进行扩展(本例中ClassBImplFun1和ClassBImplFun5都是继承AbstractClassB),而不必从原有接口进行扩展。当原接口中定义的方法太多,而其中大部分又不被需要时,这种模式非常实用。由缺省适配器类(AbstractClassB)直接实现接口(InterfaceA),并为所有方法提供缺省的空实现。用户类就只需要继承适配器类,只实现感兴趣的方法就行了。

    1. InterfaceA:目标接口。可能定义有很多方法,但这些方法不一定全都被用户类所需要。
    2. AbstractClassB:缺省适配模式的核心。它实现InterfaceA接口,为所有方法提供空的实现(也就是{}的空实现)。
    3. ClassBImplFun1:用户类,它需要实现InterfaceA接口。但因为InterfaceA方法众多,而ClassBImplFun1中对其中一两个方法(比如这里的Fun1())感兴趣。如果直接实现InterfaceA,就需要提供众多的空方法。所以它继承AbstractClassB,只需要重写它感兴趣的方法即可。既实现了InterfaceA接口,又省去了定义空方法的麻烦。

    模式结构如下图所示:

    结构解释

    上述结构中,InterfaceA中只定义了方法,而AbstractClassB中只对方法进行空实现(就是{})。而在AImpl中对接口中定义的方法进行了具体实现。ClassBImplFun1中对AbstractClassB中的fun1()进行了重写,是具体实现;ClassBImplFun5中对AbstractClassB中的fun5()进行了重写,是具体实现。

    2.代码示例

    InterfaceA

    View Code
    public interface InterfaceA {
    public void fun1();
    public void fun2();
    public void fun3();
    public void fun4();
    public void fun5();
    }

    AbstractClassB

    View Code
    /**
    * 如果 AbstractClassB是抽象类,那么可以不用实现接口InterfaceA中的方法
    * 但是如果AbstractClassB不是抽象类,即去掉关键字abstract, 那么就必须事先接口InterfaceA中的所有方法
    */
    public abstract class AbstractClassB implements InterfaceA {
    /**
    * 在AbstractClassB中完成了对InterfaceA接口的空实现,也叫平庸实现。
    */
    @Override
    public void fun1() {
    // TODO Auto-generated method stub
    }

    @Override
    public void fun2() {
    // TODO Auto-generated method stub
    }

    @Override
    public void fun3() {
    // TODO Auto-generated method stub
    }

    @Override
    public void fun4() {
    // TODO Auto-generated method stub
    }

    @Override
    public void fun5() {
    // TODO Auto-generated method stub
    }
    }

    ClassBImplFun1

    View Code
    public class ClassBImplFun1 extends AbstractClassB {

    @Override
    public void fun1() {
    // TODO Auto-generated method stub
    System.out.println("ClassBImplFun1调用fun1()");
    }
    }

    ClassBImplFun5

    View Code
    public class ClassBImplFun5 extends AbstractClassB {

    @Override
    public void fun5() {
    // TODO Auto-generated method stub
    System.out.println("ClassBImplFun5调用fun5()");
    }
    }

    AImpl

    View Code
    public class AImpl implements InterfaceA {

    @Override
    public void fun1() {
    // TODO Auto-generated method stub
    System.out.println("AImpl调用fun1()");
    }

    @Override
    public void fun2() {
    // TODO Auto-generated method stub
    System.out.println("AImpl调用fun2()");
    }

    @Override
    public void fun3() {
    // TODO Auto-generated method stub
    System.out.println("AImpl调用fun3()");
    }

    @Override
    public void fun4() {
    // TODO Auto-generated method stub
    System.out.println("AImpl调用fun4()");
    }

    @Override
    public void fun5() {
    // TODO Auto-generated method stub
    System.out.println("AImpl调用fun5()");
    }

    }

    main

    View Code
    public class Main {

    /**
    *
    @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    AbstractClassB acb1=new ClassBImplFun1();
    acb1.fun1();
    //acb1.fun6();
    AbstractClassB acb5=new ClassBImplFun5();
    acb5.fun5();
    }
    }

    上述程序的运行结果是:

    ClassBImplFun1调用fun1()
    ClassBImplFun5调用fun5()

    3.再谈Java 接口和抽象类区别

    在前面的博客:Java 接口和抽象类区别中已经提到了抽象类与接口的区别,下面我们来举例说明他们之间的最大区别。
    假如ClassBImplFun1中又需要新的方法fun6(),我们如果修改接口InterfaceA,在其中添加fun6()的定义,那么需要修改的地方就有AbstractClassB和AImpl这两个类,并且还得在ClassBImplFun1中给出fun6()的具体实现,这种改动是我们不希望出现的。一个非常好的方法就是在AbstractClassB中给出fun6()的具体实现,在ClassBImplFun1中就能直接调用这个方法。
    具体代码:
    AbstractClassB中添加如下方法:
    View Code
    public void fun6()
    {
    System.out.println("AbstractClassB调用fun6()");
    };
    新的Main类如下:
    View Code
    public class Main {

    /**
    *
    @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    AbstractClassB acb1=new ClassBImplFun1();
    acb1.fun1();
    acb1.fun6();
    AbstractClassB acb5=new ClassBImplFun5();
    acb5.fun5();
    }
    }
    运行结果:

    ClassBImplFun1调用fun1()
    AbstractClassB调用fun6()
    ClassBImplFun5调用fun5()

    ps:2012-4-11

    上述示例代码的类图如下图所示:

  • 相关阅读:
    java中的成员变量、静态变量与局部变量
    java中static关键字的作用
    java中super关键字的作用
    java中this关键字的作用
    Java创建对象的4种方式
    IO体系、集合体系、多线程、jdbc
    二分搜索树
    二叉树搜索(二分查找法)
    索引堆
    原地堆排序
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2424008.html
Copyright © 2011-2022 走看看