动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
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,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.toLowerCase 方法.
.Java 程序中的多线程(三).
.在Java编程语言中实现UDP协议编程.
.总是要改写tostring().
.Java编程讨论:关于什么叫面向接.
.JBuilder4入门(上).
.认识JDBC 2.0中的高级数据类型.
.可引导的DVD安装光盘SAID简介.
.高手教您使用MIDP底层用户接口AP.
.如何将JAVA生成可执行文件?.
.Java 有用论.
.使用Java访问网络资源.
.RCPII:扩展通用工作台补充—小的.
.Java语言的一些关键特性.
.J2ME编程开发平台中几个重要概念.
.SCSA Exam Questions 06/10/02.
.在Struts中使用Tiles框架.
.Java Script与Java Applet的综合.
.使用Java Swing创建一个XML编辑器.
.在目录中查找类位于哪个jar包中.

为什么extends是有害的(二)

发表日期:2008-1-5 |



  有一天,有人也许运行这个代码并且注重到Stack没有运行的如想象的那么快,并且能够在重负荷下使用。你能够重写Stack,以至于它不用ArrayList并且继续提高Stack的效率。这是新的倾向的和有意义的版本:
  [/代码]
  class Stack
  {
     private int stack_pointer = -1;
     private Object[] stack = new Object[1000];
  
     public void push( Object article )
  {
       assert stack_pointer < stack.length;
      
       stack[ ++stack_pointer ] = article;
     }
  
     public Object pop()
     {
        assert stack_pointer >= 0;
        return stack[ stack_pointer-- ];
      }
    
      public void push_many( Object[] articles )
      {
        assert ( stack_pointer + articles.length ) < stack.length;
      
        System.arraycopy( articles, 0, stack, stack_pointer + 1, articles.length );
        Stack_pointer += articles.length;
      }
  }
  [/代码]
  
  注重到push_many不再多次调用push()—它做块传输。新的Stack运行正常;事实上,比前一个版本更好。不幸的是,派生类Monitorable_stack不再运行,因为假如push_many()被调用,它不正确的跟踪堆栈的使用(push()的派生类版本不再通过继续的push_many()方法调用,所以push_many()不再更新high_water_mark)。Stack是一个脆弱的类。与关闭它一样,事实上不可能通过小心来消灭这些类型的错误。
  
  注重假如你用接口继续,你就没有这个问题,因为你没有继续对你有害的函数。假如Stack是接口,由Simple_stack和Monitorable_stack实现,那么代码就是更加健壮的。
  
  我提供了一个基于接口的方法在Listing 0.1。这个解决方法和继续实现的方法一样的灵活:你能够用Stack抽象术语来写代码而不必担心你事实上在操作那种具体的堆栈。因为两个实现必须提供公共接口的所有东西,它很难使事情变糟。我仍然有和写基类的代码一样的只写一次,因为我用封装而不是继续。在底层,我不得不通过封装类中的琐碎的访问器方法来访问缺省的实现。(例如,Monitorable_Stack.push(…)(在41行)不得不调用在Simple_stack等价的方法).程序员埋怨写所有这些行,但是写这非凡行代码同消除重要的潜在bug是非常小的成本。
  
  [/代码]
  Listing 0.1. 用接口消除脆弱基类
  
    1 import Java.util.*;
    2
    3 interface Stack
    4 {
    5   void push( Object o );
    6   Object pop();
    7   void push_many( Object[] source );
    8 }
    9
   10 class Simple_stack implements Stack
   11 {  private int stack_pointer = -1;
   12   private Object[] stack = new Object[1000];
   13
   14   public void push( Object o )
   15   {  assert stack_pointer < stack.length;
   16
   17     stack[ ++stack_pointer ] = o;
   18   }
   19
   20   public Object pop()
   21   {  assert stack_pointer >= 0;
   22
   23     return stack[ stack_pointer-- ];
   24   }
   25
   26   public void push_many( Object[] source )
   27   {  assert (stack_pointer + source.length) < stack.length;
   28
   29     System.arraycopy(source,0,stack,stack_pointer+1,source.length);
   30     stack_pointer += source.length;
   31   }
   32 }
   33
   34
   35 class Monitorable_Stack implements Stack
   36 {
   37   private int high_water_mark = 0;
   38   private int current_size;
   39   Simple_stack stack = new Simple_stack();
   40
   41   public void push( Object o )
   42   {  if( ++current_size > high_water_mark )
   43       high_water_mark = current_size;
   44     stack.push(o);
   45   }
   46  
   47   public Object pop()
   48   {  --current_size;
   49     return stack.pop();
   50   }
   51
   52   public void push_many( Object[] source )
   53   {
   54     if( current_size + source.length > high_water_mark )
   55       high_water_mark = current_size + source.length;
   56
   57     stack.push_many( source );
   58   }
   59
   60   public int maximum_size()
   61   {  return high_water_mark;
   62   }
   63 }
   64
  [/代码]
  
  没有提到基于框架编程,那使对于脆弱的基类的讨论是不完整的。诸如Microsoft Foundation Classes(MFC)的基类已经成为建立类库的流行途径。尽管MFC本身正在神圣的隐退,但是MFC的基口已经是根深蒂固,而这无关于Microsoft在那终止,程序员会一直认为Microsoft的方法是最好的方法。
  
  一个基于框架的系统典型的使用半成品的类的构成库开始,这些类不做任何需要做的事,而是依靠于派生类来提供需要的功能。在Java中,一个好的例子就是组件的paint()方法,它是一个有效的占位者;一个派生类必须提供真正的版本。
  
  你能够适度的多国一些东西,但是一个基于定制的派生类的完整的类框架是非常脆弱的。基类是太脆弱了。当我们用MFC编程时,每次Microsoft公布新版本时,我不得不重写我的应用。这些代码将经常编译,但是由于一些基类的改变,它们不能运行。
  
  所有提供的Java包工作的非常好。为了使它们运行,你不需要扩展任何东西。这个已经提供的结构比派生类的框架结构更好。它轻易维护和使用,并且假如Sun Microsystems提供的类改变了它的实现,也不会使你的代码处在危险中。
  
  总结脆弱基类
  一般,最好避开具体基础类和extends关系,而用接口和implements关系。我的处理规则是,在我的至少80%的代码中完全用接口来完成。例如,我从不用对HashMap的引用;我用对Map接口的引用。(我对interface这个字不是严格的。当你看怎样用接口的时候,InputStream是一个好的接口,尽管它在Java中是作为抽象类来实现的。)
  
  你增加的越抽象,就越灵活。在今天的商业环境下,需求随着程序开发而改变,灵活就是最主要的。而且灵敏编程中的大多数只有代码使用抽象来写才会很好的运行。
  
  假如你近距离的检查四人帮的模式,你将看到这些模式中的很多是提供方法消除实现继续,而最好用接口继续,并且大多数模式的共有特征是用接口继续。这个重要事实是我们开始时提到的:模式是发现而不是发明。模式的出现是当你发现写得很好,易维护的运行代码时。它讲的是这些写得好的,易维护的代码根本的避开了实现继续。
上一篇:为什么extends是有害的(一) 人气:512
下一篇:引用 造型 protected和private的困惑 人气:500
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-10 企业网站智能管理系统(TZIMS) v6
2008-10-10 拓文asp.net网站内容管理系统 v6
2008-10-10 动网论坛PHP版 v2.0++ Build 081
2008-10-10 免费时代CMS v5.0
2008-10-10 wodig第四季中文DIGG社区 v4.1 b
2008-10-10 老Y文章管理系统 v2.2 bulid 081
2008-10-10 魔法盒动感相册 ASP+SQL版 v2.0
2008-10-10 Asoft签到管理系统 v3.0 Pack1
2008-10-10 哥特人音乐网潮流留言本 v1.1
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成