当前位置:首页>>软件教程>>新闻内容  
我学习使用java的一点体会(下)
作者:xuyongshuo 发布时间:2003-10-22 11:53:26 | 【字体:
     本文的上一篇发表之后,承蒙各位网友关注,发表了很多评论,我感觉很多人对我写得文章有误解,大概是我表述不清楚的原因吧。这篇文章是对上一篇的补充,以一个示例阐述了解collection框架的重要性。

      我在半年以前写过一个函数printAll(Vector vector),具体代码如下

import java.util.*;

public class UtilTool
{
 public static void printAll ( Vector vector )
 {
  System.out.println( "the Collection is vector" );
  System.out.println( vector.getClass().toString() );
  Iterator iterator = vector.iterator();
  while ( iterator.hasNext() )
  {
   System.out.println(iterator.next().toString());
  }
 }

public static void main( String[] arg )
 {
 Vector vector = new Vector();
  vector.add( new Integer(1));
  vector.add( new Integer(2));
  vector.add( new Integer(3));
  UtilTool.printAll(vector);
}

}

      printAll这个函数设计的很不好——不够通用,假如,还想打印HashSet类型的数据,你就必须重载printAll函数,代码如下

public static void printAll ( HashSet hashSet )
 {
  System.out.println( "the Collection is hashSet" );
  System.out.println( hashSet.getClass().toString() );
  Iterator iterator = hashSet.iterator();
  while ( iterator.hasNext() )
  {
   System.out.println(iterator.next().toString());
  }
 }

      printAll函数的代码重用率低。其实Vector和 HashSet都是Collection的实现,可以将printAll的参数类型改为Collection,而不必重载。代码如下

public static void printAll ( Collection collection )
 {
  System.out.println( "the Collection is collection" );
  System.out.println( collection.getClass().toString() );
  Iterator iterator = collection.iterator();
  while ( iterator.hasNext() )
  {
   System.out.println(iterator.next().toString());
  }
 }
      这样就可以删除printAll(Vector vector)和printAll(HashSet hashSet)函数了。

      在设计函数时,应优先使用接口,而不是类。当然必须了解Vector 是Collection的实现。

      如果对Collection的继承关系不清楚,很容易滥用重载,以下代码是一个有问题的代码(摘自Effective Java Programming Language Guide)

public class CollectionClassifier{

    public static String classify(Set s){

        return "Set";

    }

    public static String classify(List l){

        return "List";

    }

    public static String classify(Collection c){

        return "Unknow Collection";

    }

    public static void main( String[] args )

        Collection[] tests = new Collection[]{

            new HashSet(),

            new ArrayList(),

            new HashMap().values()

       }

       for(int i=0;i<tests.length;i++)

        System.out.println(classify(test[i]));

     }

}

程序输出的是三次"Unknown Collection",而不是你期望的打印"Set","List"以及"Unknown Collection"。这个程序错误的根源是对Collection层次结构不熟悉,而滥用重载导致。

这篇文章仍然是对《我学习使用java的一点体会(上)》的补充。

      我使用java开发一年多,使用的应该还算熟练,最近在阅读《设计模式》和《Effective Java》时,又重新学了一下java的基本类库,对编程思想有了新的认识。java的基本类库是由专家设计的,理解基本类库一方面可以增加自己的开发效率,另外一方面可以学学专家的设计思路。在java的基本类库中,使用了很多的设计模式,在很多方面提供扩展机制,方便的支持设计模式。可以说java的基础类库,将面向对象设计的Open-Close principle (Software entities should be open for extension,but closed for modification)发挥到了极致。

      在java的基础类库中,有些类设计的是为了给java开发者提供工具,直接让开发者使用的,有些类是专门为继承而设计的。对于第一种类型的类,使用集成开发工具很容易就能上手使用,而对于第二种类型的类,不主动去学它的API,很难掌握它的使用。我举一个例子。java 2 提供了对Proxy模式的支持,在以下示例中,演示了如何使用代理模式(摘自《java与模式》)。主要体会java.lang.reflect.InvocationHandler的用法

package com.javapatterns.proxy.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import java.util.Vector;
import java.util.List;

public class VectorProxy implements InvocationHandler
{
    private Object proxyobj;

    /** @link dependency */
    /*#Proxy lnkProxy;*/

    public VectorProxy(Object obj)
    {
        proxyobj = obj;
    }

 public static Object factory(Object obj)
    {
  Class cls = obj.getClass();

        return Proxy.newProxyInstance( cls.getClassLoader(),
            cls.getInterfaces(),
            new VectorProxy(obj) );
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
  System.out.println("before calling " + method);

        if (args != null)
        {
   for (int i=0; i<args.length; i++)
            {
                System.out.println(args[i] + "");
            }
  }

        Object o = method.invoke(proxyobj, args);

  System.out.println("after calling " + method);

        return o;
    }

    public static void main(String[] args)
    {
  List v = null;

        v = (List) factory(new Vector(10));

        v.add("New");
        v.add("York");
    }
}

      现在应该说一说设计模式的学习了。设计模式是一个高度抽象的概念,每一种模式都是被抽象化了的解决某一问题的成功经验,理解设计模式需要洞察力,因而学习设计模式前,最好有一定的经验,不然很难体会设计模式的精髓。

      写设计模式方面的文章对我来说困难重重,首先由于经验、水平的限制,对设计模式的理解还没有达到那个高度,其次设计模式文章很多,从简单介绍,到深入讨论都有,很难再有新的视角讨论。我今天就简单介绍一下我读过的两本设计模式的书,从我对这两本书的理解来介绍一下设计模式。

      设计模式方面的书、资料很多,我读过两本,《设计模式》和《java与模式》,下面分别介绍。

     《设计模式》就是常提及的Gof写的那本,是使用模式化方法研究的开创性著作《Design Patterns Elements of Reusable Object-Oriented Software》的中译本。无论如何这本书都称得上是经典,值得收藏,可以隔一段时间拿出来品味一番。全书共6章,第一章引言,介绍了关于设计模式的基本概念,以及如何阅读这本书。第二章介绍了一个应用了多个设计模式的实例。第三章讨论了5个创建型模式,第四章讨论了7个结构型模式,第五章讨论了11个行为模式。第六章是结论。本书提及的23个设计模式,也是模式中的经典,在新创建的设计模式中,很大部分是这23个模式中的变体。但这本书晦涩难懂也同样出名:

  1. 这本书介绍设计模式的对象描述语言,不是我们现在通用的UML,学习时,需要理解这种对象描述语言。
  2. 这本书示例实现语言是smalltalk和C++,学习这本书时要熟悉这两种语言,而C++本身就是一个非常难的语言。

我认为这本书不适合初学设计模式的人,尤其对于java开发人员。

      《java与模式》是对《设计模式》在java这方面做的简单演绎。全书共55章,前两章介绍一些基础知识,包括UML的基本知识,接下来9章介绍面向对象的编程原则,剩余44章,讨论了26个设计模式,18个主题。这18个主题是设计模式在应用中的一些示例,有些是作者的经验,有些是广泛应用的成功示例。

       《java与模式》是针对java语言的,因而示例都是用java实现的。本书提供大量的简单示例,简单的示例易于理解,便于以后使用模式时模仿。而在主题部分讨论的问题又很深刻,体现了作者对软件设计的深刻理解,是作者对设计模式的一个演绎。虽然这门书相对简单,我也是读了3遍之后,才体会出这本书的味道。以下是我阅读这本书的一点心得,我阅读了三遍,就将每一遍我理解了什么说一说。

  1. 第一次阅读:本书的前两章是基础的概念,自然要先了解;而面向对象的原则部分,需要一定的体会之后才能深刻理解,因而第一次读时,能理解多少就理解多少,不必深究;对于设计模式的阅读,至少要熟悉每个模式的uml图以及这个模式的示例代码;主题是第一次阅读的重点,这些主题是应用设计模式的范例,应该主要理解。
  2. 第二次阅读,要明白面向对象的原则说的是什么;重点研究每一个设计模式,理解适用范围,理解优缺点,以及模式和模式的比较,在每个设计模式中如何体现面向对象的设计原则。
  3. 第三次阅读,重点是体会面向对象的原则。

      设计模式的学习不是一个简单的过程,需要反复学习,不断实践。

      前面的系列文章,只是我个人的体会,文章有些教条,仅希望能给还在java门外的人一点意见。学习、应用java的方向,我推荐看一下《谈java的学习方向?》,这篇文章写的不错(见http://www.csdn.net/develop/Read_Article.asp?Id=21393),我学习、应用java的经历和这篇文章介绍的大同小异,所推荐的书籍和资料我也大部分都读过了(差别是我没有读Oreilly公司的书,java 入门我读的是《java编程思想》和《the Complete Reference Java 2》两本java的经典教材,另外我也没有仔细研究过Specification)。如果将自己定位于j2ee方向,那么作者推荐的资料无疑相当不错,同时也比较全面。但我觉得也有一点缺憾:应该在某一个阶段学习一下设计模式和重构,毕竟设计模式和重构是面向对象开发的两本经典,而java是一个纯粹的面向对象的语言,在这里我只想再推荐几本书。

  1.    《java编程思想》是一本经典的java入门教程,在介绍语言的同时,也介绍了面向对象编程的一些思想。这本书是我学习java看的第一本书,我直到现在还经常翻开这本书,从中仍能找到一些以前没有深刻理解的内容,值得去品味。
  2. 《the Complete Reference Java 2》既是一本java的入门书籍,又是java的参考书籍,现在coding时,我仍然要经常参考这本书。
  3. 《java与模式》是向java开发人员介绍设计模式的书,在阅读这本书时,让我去回味以前做过得项目,体会以前做过的项目设计的成功与失败的地方,同时也促使我重新去阅读《java编程思想》和《the Complete Reference Java 2》两本书,阅读3遍之后,加深了对oop的理解。
  4. 《重构——改善既有代码的设计》,曾经有一个让我非常佩服的项目经理,指点我说一个项目结束后,将这个项目的源代码,重新阅读、清理、总结一下,是提高编程水平的一个手段,而我在以后的工作中,经常清理自己以及别人的一些垃圾代码,确实对编程水平的提高有很大的好处。而《重构》这本书,讲解了70多种清理、重构代码的方法,依照重构的方法去做,既能提高代码质量,又能提高编程水平,也是体会设计模式的一种手段。

       到此,我对java的体会系列文章就结束了。感谢各位网友对我写文章的关注。


文章来源:CSDN
·我学习使用java的一点体会(上)
 放生
 愚爱
 够爱
 触电
 白狐
 葬爱
 光荣
 画心
 火花
 稻香
 小酒窝
 下雨天
 右手边
 安静了
 魔杰座
 你不像她
 边做边爱
 擦肩而过
 我的答铃
 怀念过去
 等一分钟
 放手去爱
 冰河时代
 你的承诺
 自由飞翔
 原谅我一次
 吻的太逼真
 左眼皮跳跳
 做你的爱人
 一定要爱你
 飞向别人的床
 爱上别人的人
 感动天感动地
 心在跳情在烧
 玫瑰花的葬礼
 有没有人告诉你
 即使知道要见面
 爱上你是一个错
 最后一次的温柔
 爱上你是我的错
 怎么会狠心伤害我
 不是因为寂寞才想
 亲爱的那不是爱情
 难道爱一个人有错
 寂寞的时候说爱我