网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.小议如何在Applet 中显示图象.
.Java趣味“Java网络机器人”.
.Java Socket编程(二).
.给JAVA设计开发新手一些建议和意.
.100行Java代码构建一个线程池.
.Spring Reference Doc.
.全面研读EJB 2.0.
.在Linux下驱动STN彩色LCD.
.使用Manual for UrlRewriteFilte.
.数据类型.
.使用JWSDP完成Web Service在java.
.你可以在oracle中发布java程序吗.
.更改应用程序标题栏图标.
.分布式Observer模式最佳实践.
.javaCC学习笔记.
.getMinutes 方法.
.JDBCTM 指南:入门7 - CallableS.
.监控Proxool连接池的活动连接变化.
.[JAVA100例]047、使用JavaMail发.
.用AspectJ和Spring进行依赖项插入.

为什么Java中继承是有害的

发表日期:2008-1-5



  概述

  大多数好的设计者象躲避瘟疫一样来避免使用实现继续(extends 关系)。实际上80%的代码应该完全用interfaces写,而不是通过extends。“Java设计模式”一书具体阐述了怎样用接口继续代替实现继续。这篇文章描述设计者为什么会这么作。

  Extends是有害的;也许对于Charles Manson这个级别的不是,但是足够糟糕的它应该在任何可能的时候被避开。“JAVA设计模式”一书花了很大的部分讨论用interface继续代替实现继续。

  好的设计者在他的代码中,大部分用interface,而不是具体的基类。本文讨论为什么设计者会这样选择,并且也介绍一些基于interface的编程基础。

接口(Interface)和类(Class)

  一次,我参加一个Java用户组的会议。在会议中,Jams Gosling(Java之父)做发起人讲话。在那令人难忘的Q&A部分,有人问他:“假如你重新构造Java,你想改变什么?”。“我想抛弃classes”他回答。在笑声平息后,它解释说,真正的问题不是由于class本身,而是实现继续(extends 关系)。接口继续(implements关系)是更好的。你应该尽可能的避免实现继续。

失去了灵活性

  为什么你应该避免实现继续呢?第一个问题是明确的使用具体类名将你固定到特定的实现,给底层的改变增加了不必要的困难。

  在当前的灵敏编程方法中,核心是并行的设计和开发的概念。在你具体设计程序前,你开始编程。这个技术不同于传统方法的形式----传统的方式是设计应该在编码开始前完成----但是许多成功的项目已经证实你能够更快速的开发高质量代码,相对于传统的按部就班的方法。但是在并行开发的核心是主张灵活性。你不得不以某一种方式写你的代码以至于最新发现的需求能够尽可能没有痛苦的合并到已有的代码中。

  胜于实现你也许需要的特征,你只需实现你明确需要的特征,而且适度的对变化的包容。假如你没有这种灵活,并行的开发,那简直不可能。

  对于Inteface的编程是灵活结构的核心。为了说明为什么,让我们看一下当使用它们的时候,会发生什么。考虑下面的代码:

f()
{ LinkedList list = new LinkedList();
//...
g( list );
}

g( LinkedList list )
{
list.add( ... );
g2( list )
}



  现在,假设一个对于快速查询的需求被提出,以至于这个LinkedList不能够解决。你需要用HashSet来代替它。在已有代码中,变化不能够局部化,因为你不仅仅需要修改f()也需要修改g()(它带有LinkedList参数),并且还有g()把列表传递给的任何代码。象下面这样重写代码:

f()
{ Collection list = new LinkedList();
//...
g( list );
}

g( Collection list )
{
list.add( ... );
g2( list )
}



  这样修改Linked list成hash,可能只是简单的用new HashSet()代替new LinkedList()。就这样。没有其他的需要修改的地方。

  作为另一个例子,比较下面两段代码:

f()
{ Collection c = new HashSet();
//...
g( c );
}

g( Collection c )
{
for( Iterator i = c.iterator(); i.hasNext() )
do_something_with( i.next() );
}





f2()
{ Collection c = new HashSet();
//...
g2( c.iterator() );
}

g2( Iterator i )
{ while( i.hasNext() )
do_something_with( i.next() );
}



  g2()方法现在能够遍历Collection的派生,就像你能够从Map中得到的键值对。事实上,你能够写iterator,它产生数据,代替遍历一个Collection。你能够写iterator,它从测试的框架或者文件中得到信息。这会有巨大的灵活性。

耦合

  对于实现继续,一个更加要害的问题是耦合---令人烦躁的依靠,就是那种程序的一部分对于另一部分的依靠。全局变量提供经典的例子,证实为什么强耦合会引起麻烦。例如,假如你改变全局变量的类型,那么所有用到这个变量的函数也许都被影响,所以所有这些代码都要被检查,变更和重新测试。而且,所有用到这个变量的函数通过这个变量相互耦合。也就是,假如一个变量值在难以使用的时候被改变,一个函数也许就不正确的影响了另一个函数的行为。这个问题显著的隐藏于多线程的程序。

上一篇:为什么程序员不应调用“sun”包 人气:609
下一篇:位运算符 人气:1685
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐