Java2下Applet数字签名具体实现方法

Java2下Applet数字签名具体实现方法 北京 阿费 自从Java技术开始应用以来,人们对Java平台的安全性以及由于部署Java技术所引发的安全问题给予了极大的关注。特别是在1998年11月Java2发布后,Java的安全体系结构发生了根本的改进,对于终端用户而言,它可以保护文件和私人数据不被恶意的程序或病毒感染和破坏,鉴别代码提供者的身份。对于开发者而言,通过使用API方法,能够将安全性功能集成到应用程序中,因为API的体系结构能够定义和集成对特定的资源的使用权限、加密、安全性管理、策略管理,并提供了一些类来管理公钥/密钥对及信任用户群的公钥证书。同时系统管理员、开发者和用户可以使用它提供的工具管理钥匙库,在JAR文件中生成数字签名、签名的完整性检测、创建和修改策略文件。按照Java设计者的观点,Java安全包括2个方面的内容,首先将Java作为一种安全的平台提供给用户,在此平台上,可安全地运行Java程序;其次提供用Java编程语言实现的安全工具和服务,它使得诸如企业界这样一些对安全非常敏感的领域也可应用Java技术。本文将就这二个方面介绍Java2的安全性新特性以及该新特性下的Applet数字签名的具体实现方法。   Java2采用了如图1所示的新的安全体系结构,并基于这种安全体系结构提供了很多新特? 1.1 密纹访问控制   这种能力从一开始就在JDK中存在。但要使用它,应用程序的编写者不得不做大量的编程工作 <淘宝热门商品:
 

¥:21.0 

【华佗天然居】天然花草茶花茶中草药中药材

花草茶之瘦腿茶:迷迭香+柠檬草+马鞭草30包21元包快递美容减肥茶

 

288.00 元 

【19shop 超值正品】英国TOPMAN经典修


来源:程序员网

小小豆叮

关于EJB返回值的解决方案

相信很多人都有如此之困惑,得此解决方法不敢独享,公之于众,以利后来人。 声明:此方法的至于彭璐大侠,彭大侠可能不常上网,这麽好的方法也不告诉我等之小虾米,只好代劳了,彭大侠的email不便公开,应该是金蝶的人吧。 好了,不废话了,有两种方法: 1、用vector:

/** 
> * Finds all EJBeans with a balance greater than a given amount. 
> * Returns an Enumeration of found EJBean primary keys. 
> * 
> * @param balanceGreaterThan double Test Amount 
> * @return Enumeration EJBean Primary Keys 
> * @exception javax.ejb.EJBException 
> * if there is a communications or systems failure 
> */ 
> public Enumeration ejbFindBigAccounts(double balanceGreaterThan) { 
> log("ejbFindBigAccounts (balance > " + balanceGreaterThan + ")"); 
> Connection con = null; 
> PreparedStatement ps = null; 
> 
> try { 
> con = getConnection(); 
> ps = con.prepareStatement("select id from ejbAccounts where bal > ?"); 
> ps.setDouble(1, balanceGreaterThan); 
> ps.executeQuery(); 
> ResultSet rs = ps.getResultSet(); 
> Vector v = new Vector(); 
> String pk; 
> while (rs.next()) { 
> pk = rs.getString(1); 
> v.addElement(pk); 
> } 
> return v.elements(); 
> } catch (SQLException sqe) { 
> log("SQLException: " + sqe); 
> throw new EJBException (sqe); 
> } finally { 
> cleanup(con, ps); 
> } 
> } 
结论:不爽,不方便。 2、RowSet RowSet tutorial chapter : http://developer.java.sun.com/developer/Books/JDBCTutorial/chapter5.html rowset是个interface,需要有东西去实现它,sun的规范中给了三个class:cachedrowset,jdbcrowset,webrowset, 如果去查jdk1.4 doc和j2skee1.2,有rowset,却没有那三个class,一般的开发工具(至少我的wsad)中也是这样, 所以需要下jdbc2.0 opt-pack: http://developer.java.sun.com/developer/earlyAccess/crs/ 下下来了再怎么办呢? 装呗! 怎么装呢? setup呀! 没有呀? 啊,没setup呀,sun干什么吃的,连setup都不做个,也太懒了吧。 ///////////////////////////////// 哎,我们确实是都被ms惯坏了,看到只有jar,没setup就没辙了,大家好好想想,java最大的特性是什么,就是它的类库 可以自由扩充呀,现在明白该怎么做了吧: 1、解包,得到rowset.jar,放在哪随您的意,别丢了就行。 2、在您的开发工具中增加一个路径,如:ROWSET_PATH对应:d:jdk1.4jre owset.jar(和1的路径对应就行)。 3、右键您的工程文件,出现:property(大多数工具应该都有吧),加上rowset_path。 4、在您的源文件中:import sun.jdbc.rowset.*; OK,搞定!下面就看您的了。(当然也可以把rowset压到jre里去) 应该说rowset(其实主要是CachedRowSet)真的是个好东西,和ms ado的resultset和borland的tclientset非常相似, 最大的好处是Cache功能! 好了,看例子吧:

/////////////server端///////////// 
package example4; 

import java.sql.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import javax.naming.*; 
import javax.ejb.*; 

public class CoffeesBean implements SessionBean { 

   private SessionContext sc = null; 
   private Context ctx = null; 
   private DataSource ds = null; 
    
   public CoffeesBean () {} 
    
   public void ejbCreate() throws CreateException { 

       try { 
           ctx = new InitialContext(); 
           ds = (DataSource)ctx.lookup("jdbc/CoffeesDB"); 
       } 
       catch (Exception e) { 
           System.out.println(e.getMessage()); 
           throw new CreateException(); 
       } 
   } 

   public RowSet getCoffees() throws SQLException { 
        
       Connection con = null; 
ResultSet rs; 
       CachedRowSet crs; 

       try { 
           con = ds.getConnection("webCustomer", "webPassword"); 
           Statement stmt = con.createStatement(); 
           rs = stmt.executeQuery("select * from coffees"); 
            
           crs = new CachedRowSet(); 
           crs.populate(rs); 
           // the writer needs this because JDBC drivers 
           // don't provide this meta-data. 
           crs.setTableName("coffees"); 
            
           rs.close(); 
           stmt.close(); 
       } finally { 
           if (con != null) 
               con.close(); 
       } 
       return rset; 
   } 
    
   public updateCoffees(RowSet rs) throws SQLException { 

       Connection con = null; 

       try { 
           CachedRowSet crs = (CachedRowSet)rs; 
           con = ds.getConnection("webCustomer", "webPassword"); 
           // moves the changes back to the database 
           crs.acceptChanges(con); 
       } finally { 
           if (con != null) 
               con.close(); 
       } 
   } 

   // 
   // Methods inherited from SessionBean 
   // 
    
   public void setSessionContext(SessionContext sc) { 
       this.sc = sc; 
   } 
    
   public void ejbRemove() {} 
   public void ejbPassivate() {} 
   public void ejbActivate() {} 

    
} 


//////////////////client端////////////// 
package example4; 

import java.sql.*; 
import javax.sql.*; 
import sun.jdbc.rowset.*; 
import javax.naming.*; 
import javax.ejb.*; 
import javax.rmi.*; 

class CoffeesClient { 

   public static void main(String[] args) { 

       try { 
           // init the bean 
           Context ctx = new InitialContext(); 
           Object obj = ctx.lookup("ejb/Coffees"); 
           CoffeesHome coffeesHome = (CoffeesHome) 
               PortableRemoteObject.narrow(obj, CoffeesHome.class); 
           Coffees coffees = coffeesHome.create(); 
            
           // get the rowset from the bean 
           CachedRowSet rset = (CachedRowSet)coffees.getCoffees(); 

           // find the Columbian coffee 
           while (rset.next()) { 
               String coffeeName = rset.getString("COF_NAME"); 
               if (coffeeName.equalsIgnoreCase(new String("Columbian"))) { 
                   // columbian coffee has gone up 10% 
                   rset.updateFloat("PRICE", 
                                    (float)(rset.getFloat("PRICE") * 1.10)); 
                   rset.updateRow(); 
               } 
           } 

           // finally send the updated back to the bean... 
           System.out.println("Calling update method"); 
           coffees.updateCoffees((RowSet)rset); 
       } 
       catch (Exception e) { 
           System.out.println(e.getMessage()); 
       } 
   } 
} 
例子很简单就不多讲了。 cheers. Robin Any question mailto:myvrml@263.net <淘宝热门商品:
 

16.0元  

【珠三角商盟】联合利众●减肥瘦身●丰胸美乳●私处保养●美容

 

保健品/滋补品 

淑芳阁_苗条姿_最有效的减肥瘦身与丰胸专卖店


来源:程序员网

小小豆叮

WAP缩略语集萃(eclipse整理!

3G - The Third Generation (Wireless Network / Technology) A AE - Authenticating Entity AIN - Advanced Intelligent Network AMPS - Advanced Mobile Phone System (analogue) ANSI - American National Standards Institute AP - Application Programming Interface AUC - Authentication Centre B BNF - Backus-Naur Form C CAN - Customer Access Network CCF - Call Control Function CCITT - Consultative Committee on International Telegraphy and Telephony CCAF - Call Control Agent Function CCS7 - Common Channel Signaling No.7 CDMA - CER - Call Event Record CIC - Carrier Access Code CID - Customer Identifier CLI - Calling Line Identification CLIP - Calling Line Identification Presentation CLIR - Calling Line Identification Restriction CNM - Customer Network Management CPE - Customer Premises Equipment CPI - Calling Person Identification CSD - Circuit Switched Data CSS - Customer Support System (Systems) CTIA - Cellular Telecommunications Industry Association CTI - Computer Telephony Integration D DECT - Digital Enhanced Cordless Telephony DTMF - Dual Tone Multi Frequency DCS1800 - Digital Cellular (1800Mhz) E ECMA - European Computer Manufacturer Association EDGE - Enhanced ETR - ETSI Technical Report ETSI - European Telecommunications Standards Institute F FMC - Fixed Mobile Convergence FMI - Fixed Mobile Integration FNN - Full National Number FCC - Federal Communications Commission G GoS - Grade of Service GPS - Global Positioning System GPRS - General Packet Radio Service GSM - Global System for Mobiles H HTML - HyperText Markup Language [[]HTML4] HTTP - HyperText Transfer Protocol [[]RFC2068] HLR - Home Location Register HDML - Handheld Device Markup Language(是phone.com的专利明语言,在WAP正式出现后逐渐淡出) I IANA - Internet Assigned Number Authority IMSI - International Mobile Subscriber Identity INAP - Intelligent Network Application Part IN - Intelligent Network IP - Intelligent Peripheral ISUP - ISDN Signaling User Part (signaling) ITU - International Telecommunications Union IVR - Interactive Voice Response IWU - Interworking Unit L LSB - Least Significant Bits M MAP - Mobile Application Part MML - Man Machine Language MoU - Memorandum of Understanding MSB - Most Significant Bits MSC - Mobile Switching Centre MTBF - Mean Time Between Failure MTBR - Mean Time Before Repair N NE - Network Element NMT - Nordic Mobile Telephone System NSN - National Significant Number NTP - Network Termination Point O OMS - Operations and Maintenance System OSS - Operational Support System P PABX - Private Automatic Branch Exchange PACTS - Public Access Cordless Telecommunication Service PBX - Private Branch Exchange PCN - Personal Communications Network PCS - Personal Communication Service PDA - Personal Digital Assistant PHS - Personal Handyphone System PIN - Personal Identification Number PLMN - Public Land Mobile Network PMTS - Public Mobile Telephone System PN - Personal Number POI - Point of Interconnect POTS - Plain Old Telephone Service PSTN - Public Switched Telephone Network PSTS - Public Switched Telephone Service PTO - Public Telecommunication Operator Q QEAN - Quick Entry Access Number QoS - Quality of Service R RFC - Request For Comments S SCE - Service Creation Environment SCF - Service Control Function SCP - Service Control Point SDF - Services Data Function SDK - Software Development Kit SDP - Services Data Point SIM - Subscriber Identity Module SIO - Services In Operation SMC - Security Management Centre SMF - Service Management Function SMS - Service Management System SMTP - Simple Mail Transfer Protocol SN - Service Node SQL - Structured Query Language SRF - Specialized Resource Function SSF - Service Switching Function SSP - Service Switching Point STD - Subscriber Trunk Dialling STP - Signaling Transfer Point T TCAP - Transaction Capability Application Part TMN - Telecommunications Management Network U UCS - Universal Multiple-Octet Coded Character Set UI - User Interface UMTS - Universal UPT - Universal Personal Telecommunication URL - Uniform Resource Locator [[]RFC2396] UTF - UCS Transformation Format V VAS - Value Added Service VLR - Visitor Location Register VMB - Voicemail Box VMP - Voicemail Platform W W3C - World Wide Web Consortium WAE - Wireless Application Environment WAP - Wireless Application Protocol WWW - World Wide Web WTA - Wireless Telephony Applications WTP - Wireless Transport Protocol WBMP - Wireless BitMaP WML - Wireless Markup Language WSP - Wireless Session Protocol WTAI - Wireless Telephony Applications Interface <淘宝热门商品:
 

17.80 元  

居家家--18个月上四皇冠,家居类信用最高卖家

简家 四皇冠信用 鲸鱼USB暖手鼠标垫D4063 冬天上网必备

 

 

徽商联盟】皇冠信誉店 联盟化妆品の屋


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例三)

实例三、计算 订单 的 总价格(如何取出正文的值)。 问题:请计算 orders.xml 所示的总价格 orders.xml 的源文件。 <订单> <商品 数量="21"> <名称>袜子 <单价>3.24 <商品 数量="1"> <名称>贝斯 <单价>4200.00 <商品 数量="5"> <名称>域名 <单价>60.50 <商品 数量="2"> <名称>书 <单价>99.00 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。 import org.xml.sax.*; import javax.xml.parsers.*; import java.util.Vector; /** * Title: XML Study, Sample 3 * Description: Count the Order Sum. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class CountSum extends org.xml.sax.helpers.DefaultHandler { private double totalPrice = 0.00; private StringBuffer content = new StringBuffer(); private Vector numberV = new Vector(); private Vector priceV = new Vector(); private double totalSum = 0.00; public CountSum() { } public static void main(String[] args) throws Exception { CountSum cs = new CountSum(); cs.createParser(); } public void createParser() throws Exception{ SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(this); xr.parse("http://localhost/orders.xml"); } // 取得 商品 中属性 数量 的值,并将它放入数组 numberV 中。 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("商品")) { String number = atts.getValue("数量"); numberV.addElement(number); //System.out.println(numberV); } content.setLength(0); } // **** 此方法将遍历 XML 文件,获取 文本 值。 public void characters(char[] ch, int start, int length) throws SAXException { content.append(ch, start, length); //System.out.println(content.toString()); // 打印出来,看看此方法是怎样运行的 } // **** 仅获取元素 单价 中的文本,并将它放入数组 priceV 中。 public void endElement(String uri, String localName, String qName) throws SAXException { if (localName.equals("单价")) { String price = content.toString(); priceV.addElement(price); //System.out.println(priceV); } } // 计算总价格 public void endDocument() throws SAXException { int num; double pr; for (int i=0; i
 

108.00 元  

电视购物热销.夏娃之秀魔力挺,让女人都有杀人"胸"器

 

鲜花速递/蛋糕配送/园艺花艺 

瑞锦记锦缎喜糖袋〓婚礼特制●上等材质●流行韩


来源:程序员网

小小豆叮

轻松玩转Java Web Start

陈臣 (chch1979@263.net) 2002 年 1 月 Java Web Start(以下简称JWS)是SUN提供的一种通过Web来部署和发布Java 程序的新技术,它既可以用来发布Application,也可以用来发布Applet,它获去年全球Java技术最佳创意奖。它仅在第一次运行时下载程序,以后的事情,就全全交给JWS,包括版本的自动更新和维护。这是我们曾经梦寐以求的事情,程序运行在客户端(本地运行,当然有足够的速度),但不用去安装配置客户端,也不用去考虑版本升级后对客户端的维护,这就是JWS提供给我们的好处之一。OK,下面我们就来看看如何玩转JWS,本文仅用发布Application来做说明。 系统环境:Win2000Professional+Tomcat3.2.1+JDK1.3。 一:JWS简介 JWS主要用来通过网络部署你的应用程序,它具有安全、稳定、易维护、易使用的特点。用户访问用JWS部署应用程序的站点,下载发布的应用程序,既可以在线运行,也可以通过JWS的客户端离线运行已下载的应用程序。对同一个应用程序,在第一次运行时下载,以后每次运行时,JWS的客户端会自动去探测是否有版本更新,有更新就自动下载新版本,没有更新就直接运行本地当前版本,所有的麻烦全由JWS去承担。好,下面我们就一步一步来搭建JWS 二:搭建支持JWS的Web站点 第一步:你的Tomcat3.2.1已经正常运转 第二步:找到TomcatHOME/conf下的web.xml文件,在其中添加 application/x-java-jnlp-file 以支持JNLP文件。 三:部署应用程序 第一步:开发你希望发布的应用程序 第二步:把应用程序及所用到的所有资源打成一个或多个jar包 第三步:如果你的应用程序不会用到任何运行这个应用程序的机器的本地资源,那么,你的应用程序就可以部署了。 第四步:如果你的应用程序用到了运行这个应用程序的机器的本地资源,那么,你的应用程序就必须先签名然后才可以发布。 第五步:如何给应用程序签名 1:首先确保你已经完全安装了Java2的环境,有keytool工具,它位于J2SE SDk的bin目录下。这一般不会有问题。 2:到Dos状态下,进入你需发布应用程序的jar包所在的目录,运行下面这句话 keytool -genkey -keystore myKeystore -alias jwstest 它将会提示你输入用户名、密码等,不用理它,按照提示随便输入即可,但一定要记住密码。运行结束它将会在当前路径下创建名为myKeystore的文件。 3:如果你想察看一下刚才生成的myKeystore文件的内容,可以使用下面这句话: keytool -list -keystore myKeystore 显示出来应该类似如下: Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry: jwstest, Tue Nov 23 19:29:32 PST 2001, keyEntry, Certificate fingerprint (Test): C3:A9:CD:F3:D3:AC:4D:3F:3C:5B:AF:9E:CF:0D:46:5C 4:对你需发布应用程序的jar包进行签名,运行下面这句话: jarsigner -keystore myKeystore yourtest.jar jwstest 其中yourtest.jar是你的jar包名,你需要修改它,别的就不必修改了。运行时会提示你输入密码,就是你刚才在生成myKeystore文件时设定的密码。 第六步:部署应用程序的jar包。 1:在Tomcat的webapps中新建目录JWSTest 2:在JWSTest下新建目录apps,META-INF,WEB-INF 3:在apps下新建目录images和lib 4:在META-INF中拷入MANIFEST.MF 5:在WEB-INF中拷入web.xml 6:把已经准备好的jar包拷入lib目录下 四:Jsp页面 第一步:编写用于Web访问的页面index.jsp如下: 第二步:在jsp中添加检测访问的客户端是否已经安装了JWS的客户端的代码,示例如下: 五:JNLP文件 第一步:下面我们来编写JWS的核心配置文件JNLP,有了它,才能将以上各部分联系起来,真正让JWS运转起来。JNLP文件符合标准的XML语法,实质就是一个XML文件。当然,编写它的最好方式是对已写好的JNLP进行改写。JWSTest.jnlp示例如下: spec="1.0+" codebase="http://你的IP:8080/JWSTest/apps" href=" JWSTest.jnlp"> YOUR Name JWS Test 第二步:部分JNLP的关键语法 元素 spec:必须是1.0及以上版本,这里用1.0+,不需修改。 codebase:资源的URL,是JNLP指向各连接的起始处,需自行修改。 Href:JNLP文件相对codebase的存放位置,和JNLP文件的全名,需自行修改。 元素 Title:发布的应用程序简单标题,需自行修改。 Vendor:发行商信息,可以写上你的大名,需自行修改。 Homepage:存放有关应用程序的相关文档的URL,如help文件等,可有可无。 Description:对应用程序的描述,可以有多对,可有可无。 Icon:用户下载你的应用程序后,在JWS里显示的图标的URL,应是gif或jpeg格式。需自行修改。 Offline-allowed:选择项,允许用户离线运行应用程序,一般都会有,不用修改。 元素 选择项,如果没有指明,默认是不允许应用程序访问用户的本地资源,即应用程序是沙箱运行。 如果设定为,则表示允许应用程序访问用户的本地资源。一般都会设定此值。 元素 元素 main-class:应用程序运行启动的主类 :应用程序运行时的参数,可以有多个,每一个参数用一对参数。 至此,你已经完全构建了运转JWS的各部件。 六:完整发布和测试 前面我们已经准备好了需发布的应用程序的jar包,也写好了用来访问的jsp文件和服务器端的核心jnlp文件。 第一步:在JWSTest下新建目录jsp。把index.jsp拷入jsp目录。 第二步:把jnlp文件直接拷入apps目录下。 第三步:在浏览器里输入:http://localhost:8080/JWSTest/jsp/index.jsp 即可访问到jsp页面。页面应出现JWSTest字样。 第四步:点击JWSTest,连接到apps下的JWSTest.jnlp文件,JWS启动,开始下载你发布的应用程序。 第五步:下载完毕,直接运行即可。以后,你也可以直接运行JWS客户端里已下载的应用程序。 不出意外,应恭喜你已经开始享受JWS带来的乐趣了。 七:常见问题 通过上面的讲述,你一定能体会到JWS的易用性。或许事情并没有那么简单,以我的使用经验,还会有许多问题出现,在这里挑几个经常出现的问题,给出相应解决方法,让大家少走弯路,而享受更多的乐趣。 问题一:JWS不能运行,JNLP文件像普通XML文件一样显示在Browser里 解决办法:请修改tomcat里,发布程序的路径中的web.xml。 在其中添加 application/x-java-jnlp-file 以支持JNLP文件。 问题二:不能下载资源或下载资源失败 解决办法:请卸载JWS的客户端,并将注册表里有关JWS的项目都删除,并确保program Files下的Java Web Start目录已被删除,然后,重装JWS。 问题三:下载资源中有未签名文件 解决办法:1:确保所有的jar包及其他资源都进行过签名。 2:确保整个资源中,没有中文的命名。好像签名工具不支持中文命名的文件名,所以未签到名。这可让我郁闷了一下午哦。 3:察看已经签名的jar包中,meta-inf路径下的jwstest.sf(jwstest是你在进行签名时-alias后的命名)文件,他详细的列出了所有已签名的文件,以分析签名失败的原因。 有关参考 详见 http://java.sun.com/products/javawebstart/ 关于作者 陈臣,就职于中关村某软件公司,软件工程师,scjp, 您可通过 chch1979@263.net 与他联系。 <淘宝热门商品:
 

4.00 元  

5钻【成都商盟】竹纤维内裤袜子毛巾超市~~收藏本店就有礼物送哦

特价 100%竹纤维毛巾 京杭丽人儿童毛巾27*48 50克/随机颜色

 

 

专做VIVI昕薇瑞丽韩日女装~


来源:程序员网

小小豆叮

评论:分布式不只是一个概念

新闻内容:      美国高新技术产业最近兴起了一个新行当,这个新行当通常被称做“分布式运算”(distributed computing)或“点对点”(peer to peer)服务供应商,他们的主要任务是把公司职员的个人计算机所闲置的运算能力汇集起来,帮助客户进行复杂的研究工作并节省其购买超级计算机的费用。   也就是说,这类公司把客户复杂的研究问题分割成好几个可以独立运算的部分,然后通过网络把这些分割后的问题分发给下属数千台个人计算机进行处理,这时候每台个人计算机就变成类似Napster网站(提供MP3音乐文档交换服务)的交换系统,等到运算结束后再把个别的结果回传给中心计算机汇总,最后得出问题的答案。   这种构想其实很简单,因为个人计算机就像人脑一样有许多部位的能力尚未开发,所以这些公司的任务就是把这些能力开发出来,加以结合后就能发挥极大的作用,其效率甚至远远超过一台超级计算机。   分布式运算,可能逐渐取代超级计算机   这种构想起源于加州的“寻找外星智能生命协会”。这个协会从1999年5月开始寻找有兴趣参与研究的成员。通过分布式运算方式,该协会把成员个人计算机多余的运算能力结合起来,结果发现其探测外星人电磁波信号的译码能力,竟然远远超过最大型的超级计算机。   尽管目前“分布式运算”的使用仍受到诸多限制,但却有逐渐取代超级计算机的趋势。目前生物技术研究人员已经通过这种方式处理复杂的程序,以寻找基因;经济学家也通过它得出数百万种股市变化可能性的组合。另外,企业也可以使用这项服务测试其网站网页被下载的速度。   仅仅购买一台超级计算机的价格可能就高达1.1亿美元,因而“分布式运算”的客户只需付出购买或者租用超级计算机的一小部分经费,就可以完成其研究目标。这正是“分布式运算”供应商赖以生存的基础,它们可以帮助客户获得超级计算机般的运算能力,客户却不必付出使用超级计算机所需的高昂代价。   洋基集团的研究人员高曼表示:“这是高新技术产业开创的新领域,即借用个人计算机的力量,发挥出超级计算机的效果,再把这样的服务卖给企业。”不过,这样的网络联结可能提供了另一种病毒传播的渠道,但专家们表示在通过复杂的加密程序保护后,这样的风险已大大降低。   在“分布式运算”服务供应商们刚刚露头的时候,他们在吸收愿意提供个人计算机闲置运算能力的成员时不用支付任何成本,因为他们保证这些计算机将用于公益事业。例如United Devices这家公司是将“分布式运算”能力应用于癌症研究。沃壮是United Devices的成员之一,他说:“这是我当初加入这家公司的原因。”   但随着越来越多的公司借此牟利,许多当初持支持公益事业态度加入的成员开始犹豫是否要让自己的计算机成为别人的摇钱树。   United Devices的首席执行官修巴德表示:“当我们接到商业合同时,将会向成员发放酬金。”这家公司每个月都会按照成员个人计算机的贡献程度,向前200位成员发放5-1000美元不等的津贴。   Porivo Technology公司是另一家“分布式运算”服务供应商,该公司从这个月开始实行有偿使用个人计算机闲置能力的作法。这家公司的创办人兼战略发展副总裁何密斯说:“平均每个月每位成员可以领到15-20美元。”目前该公司一个月向客户收取的费用最多高达2万美元,向成员支付的金额最多为每月45美元。   不过United Devices公司表示,在金融风险日益增高的时候,应该尽量避免实施这样的付费制度。修巴德表示:“要公司负担如此大的非固定成本,并不是明智之举。”   然而United Devices的劲敌,为Scripps Institute提供艾滋病研究所需运算能力的Entropia公司,虽然也提供商业服务,但却拒绝向参与成员支付报酬。该公司创办人兼首席技术官安得鲁·陈说:“当成员知道个人计算机是用于有意义的研究后,他们将会十分高兴。”   分布式软件,让软件变得虚无缥缈   分布式概念还为软件的发展激发出了新的灵感。过去20年来,互联网的发明及推广使得数以百万计的计算机能够彼此相连,最近出现的高速网络服务则进一步加强了计算机连结的程度,这使得分布式软件的发展向前跨出了重要的一步。   一些软件设计师将这种发展方向称为远离计算机桌面,让软件变得虚无缥缈。在传统意义上,软件就是一个产品,储存于磁盘或者光盘上,它是用户使用计算机的工具之一。如今,软件公司正致力于通过铜线、光纤及电磁波所构成的高速网络,让软件流动化,也就是说,让软件分布在整个网络上。   这个构想对那些想要甩开传统桌面图形用户界面的软件设计师非常有吸引力。事实上,分布式运算是一个宏大的理想,不论是学术领域还是产业界的龙头公司,几乎都在竞相追逐这一目标。   也许分布式运算的最佳典范就是互联网的网域名称系统,网域名称是一个存在于很多服务器之中的庞大数据库,通过网络的连结,它可以迅速向上网者提供网址上的资料。相比之下,未来十年之内分布式应用软件对于整个社会的影响将不可限量,它的触角可能会伸向能源管理,也可能伸至交通控制系统。   美国加州一家新公司Applied Minds的创办人兼首席计算机设计师席立斯表示:“原则上大家都希望某样东西能够固定在某处,这样一来四面八方的人士都可随意使用。”但是他接着说,“过渡到软件服务是未来不可避免的趋势,没有人愿意花钱买软件,但所有人都希望能够使用软件。”席立斯解释说:“拥有软件反而于己不利,因为你还必须维修、升级,如果你买了一台新的计算机,你必须重新安装软件。”   过去两年来,一批新型公司已开始积极运作,希望能使分布式软件的美梦成真。这些新公司自称为应用软件服务提供商,他们竭力为产业界提供所需的软件,不过随着市场环境的变化,有些公司目前已从市场上消失,但仍有部分公司继续提供服务。   如今国际商用机器(IBM)、微软及太阳等三家计算机产业的领导厂商也准备趟这趟浑水,他们正在研发新软件,为远离桌面的目标奠定基础。   不过新的系统都是以各家公司的商业策略为出发点。例如微软希望通过提供分布式软件服务,来巩固其桌面软件霸主的垄断地位。IBM及太阳则希望打破微软软件的市场龙头地位,他们说服研发人员自行设计出不同于微软的软件,写出一套网络标准的新程序。   然而,分布式运算将会增加软件的复杂性。网络搜寻引擎Google董事长舒密特表示:“事实上分布式运算非常困难,它表面上看起来容易,但实际操作却困难重重,它必需克服各种不同的网络安全及网络系统。” <淘宝热门商品:
 

1.50元  

星钻喜铺◣皇冠信誉◢{100%满意婚庆一站式店铺}特色婚庆用品大全

 

128.00 元  

【广州商盟】*大学生淘宝皇冠第一店-鞋神--三人行出口剩余旗舰店

【大学生皇冠店】new balance纽巴伦378经典款 天蓝


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例一)

基于事件驱动的解析接口 SAX (实例一) SAX vs. DOM DOM是基于树结构的一种接口;SAX是基于事件驱动的解析接口。 有什么区别呢? 1、SAX 可以解析任意大小的文件,而 DOM 解析的文件大小则和硬件有关。DOM 需要将整个文件加载到内存,而 SAX 不需要。 2、因为 SAX 是不把文件加载到内存,所以不能对文档进行随机存取;而 DOM 可以做到。 3、SAX 相对 DOM 来说是简单易用。 4、如果要从文档的简单系列中获取信息,SAX 是最快的方法。 实例一、查查有多少本书? 题目是要查出来下面的 XML 文件 books.xml 里有多少本书。 XXX1 Thinking in Java 60.00 XXX2 Thinking in C++ 56.00 Slepwormzz My Dirty Mind 8.99 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。 import org.xml.sax.*; import javax.xml.parsers.*; import java.io.IOException; /** * Title: XML Study, Sample 1 * Description: Count My books. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class BookCounter extends org.xml.sax.helpers.DefaultHandler{ private int count = 0; // 定义一个计数器 public BookCounter() { } // 主程序 public void countBooks() throws Exception { // 创建一个新的 JAXP 的 SAXParserFactory 实例,并且配置它。在 JAXP 包的例子中可以看到此种方法 SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); // 试一下改为 true XMLReader xr = null; try { SAXParser sp = spf.newSAXParser(); xr = sp.getXMLReader(); } catch (Exception e) { System.err.print(e); System.exit(1); } xr.setContentHandler(this); try { xr.parse("http://localhost/books.xml"); //进行语法分析 } catch (SAXException se) { System.err.println(se.getMessage()); System.exit(1); } catch (IOException ioe) { System.err.println(ioe); System.exit(1); } } // 当每次碰到一个 book 元素的时候,将 计数器 加一。此方法在遇到第一个元素的时候开始执行 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("book")) count++; } // 输出 计数器。此方法在分析文档完成的时候执行 public void endDocument() throws SAXException { System.out.print(count); } public static void main(String[] args) throws Exception { BookCounter bc = new BookCounter(); bc.countBooks(); } } 我们可以看到输出了结果 为 3 试着把 books.xml 文件改成错误的结构,看看 会有什么例外抛出 <淘宝热门商品:
 

¥:9.99 

【黑龙江商盟】棋子儿平价美妆店-烟熏彩妆/假睫毛大全/新娘用品

买十送一全网最低价高级无痕透明根部自然浓密凌乱假睫毛仿真毛发

 

 

【25元或以上商品任意2件包运】【时尚卓尔】-个性随我秀


来源:程序员网

小小豆叮

基于Internet的软件工程策略

作者:Yao Zheng  来源:CoSoft 我有话说……   Internet的发展和应用正在不断超越人们的想象,融入社会生活的各个角落,将对各行各业产生深远的、不可逆转的影响。针对软件产业而言,Internet时代对于软件开发进度提出不断增长的挑战性要求,并产生了许多新思想和新观念,对原有的一些传统软件工程理念带来了冲击,Linux的成功开发实践、开放源码思想的不断普及、大教堂和市集型开发模式的碰撞等都是最直接的体现。显然,如何使得软件企业能够从容面对时代的变迁,把握Internet所带来的机遇和挑战,具有重要意义。   近年来,开放源码思想在国际上越来越受到人们的重视,在这个思想下已经成功开发了一系列著名软件,比如Linux就是其中典型代表。开放源码思想与Internet有着内在的天然联系,通过二者的有机结合能够将许多人的智力集聚到一起,反映了一种新的软件开发思路,本节试图探究其成功经验。   相对传统软件工程而言,开放源码社区似乎没有准备接受或实践现代软件工程过程,但他们的确在开发适用于特定用户团体的软件,这些软件通常是极具价值的、可靠的、被广泛接受的和高可用的。那么,究竟什么样的开发过程正在开放源码社区中被常规应用和实践呢?一项研究表明,有五种软件开发过程在开放源码社区得到广泛应用:   1) 需求分析和说明   2) 受控的版本管理、系统构建和按阶段的增量发布   3) 维护被看作是演进式开发、重新精练细化和重新发行   4) 项目管理   5) 软件技术转移   以上每个过程都与传统软件工程规定体现出不同之处,而且没有哪个过程应被独立构造或凌驾于其他过程之上。更进一步,这些过程相互之间通常是并行开展的,而不象传统软件生命周期模型中那样严格的或部分的按序进行,开放源码软件开发从本质上讲是一种复杂的由社会-技术过程、开发条件和动态产生的开发上下文所组成的网络,以Internet为基础支撑平台,并随着Internet的发展而不断完善。   对于许多开放源码项目而言,开发人员对于是否遵循了某种规定的软件工程方法和过程并不关心,有些项目甚至没有特定的用户和发布截止期限,但是诸如“经常发布”、“简化设计”、“测试”、“编码标准”、“集体参与”等基本原理却被本能地执行着。   对于开放源码软件协同开发原理的经典论述来自开源社区领袖之一的Eric Redmond的《大教堂与市集》一文,在该文中作者形象地将传统的严格管理的软件开发活动比喻为构筑大教堂的行为,而将分布于Internet之上的开放源码社区的协同开发活动则看作是市集行为,作者根据亲身经历系统地论述了市集型开发的基本方法和哲学问题,阐释了开放源码社区成功的内在原因,对于传统软件开发不无借鉴之处,比如“早发布、常发布、听取用户的建议”、“把用户当做协作开发者和Beta测试人员”、“聪明的数据结构和笨拙的代码要比相反的搭配工作的更好”、“最好的设计不是再也没有什么东西可以添加了,而是再也没有什么东西可以去掉”、“好程序员知道该写什么,伟大的程序员知道该重写(和重用)什么”等等。   目前,人们对于基于开放源码的Internet协同开发实践还缺乏深入研究和理解,但是已经得到越来越多的软件工程人士的关注,并取得一定的研究成果。一个软件工程研究小组在过去5年中深入研究了几个大型的开放源码系统的体系结构和进化过程,包括Linux、GCC、VIM、Mozilla和Apache,发现他们与类似的商业系统之间表现出令人感兴趣的不同之处,比如,开放源码软件的体系结构通常是可浏览的以允许开发人员进行交互,对于那些可能阻碍程序理解(因为程序员通常是分布在Internet上各个角落互相独立的工作)的体系结构部分进行特殊声明;从同类的开放源码软件如Web服务器中可以提取其共性的参考体系结构,而在商业软件公司中却难以通过Web服务器体系结构获得几种不同的实现;开放源码软件的体系结构和开发模式是导致其超线性增长的主要因素,并且被尽可能设计的易于移植,其发行版通常不是针对特定平台,而是将各种平台的共性抽象到一个发行版中,通过配置工具来帮助构建系统。   另外,针对如何借鉴开放源码项目的经验用于指导商业软件项目也有相关研究成果,该项研究表明,尽管完全利用开放源码开发模式来代替传统商业软件开发模式目前看来还不太可能,但无疑可以相互借鉴经验教训而获得收益。研究人员认为,一些可供商业软件项目借鉴的开源项目经验包括:   人员组织——开源项目通常由很少的核心成员完成多数开发和升级任务,这一点与商业软件开发类似,但差别在于这些任务是如何在核心小组内分配的。开源项目通常是自发形成,职责的分配是基于对开发人员如何看待他们在项目中的角色的推理而确定,并不是硬性指派产生,这一点无疑对于商业软件的管理具有借鉴意义。   非正式交流——在Internet协同开发活动中非正式交流对于项目成员间的协调极其重要,邮件列表、论坛等是常用工具,无论开发人员在文化、地域和时区方面是否存在差异。商业软件应借鉴这种做法,而不必拘泥于严格的、形式化的交流渠道。   增强的用户支持——许多用户都同意这种观点,即多数商业软件公司在进入售后支持阶段时就可能面临悲惨的失败命运。而开源项目的用户支持工作却有良好成绩,因为大量的用户愿意提供关于开源产品的反馈信息。因此,商业软件项目应增强用户之间、用户与开发者之间的交互,从而获得改进的售后支持以及更有意义的错误报告。   显然,随着人们对于基于开放源码的Internet协同开发模式的不断研究和深入理解,必将对未来的软件工程实践产生极其深远的影响。以下按照传统软件工程领域的常规做法,对于开放源码软件的协同开发活动总结出所谓“最佳实践”,以增进读者的感性认识: (一)技术交流   软件开发人员需要花费大量时间用于相互之间的通讯交流,清晰和高效的技术交流对于维持团队间的同步和允许掌握关键知识的个人在需要时利用其知识都是必需的。开放源码社区的一个基本原则是技术交流应当在公共论坛中进行,邮件列表是开放源码交流的基石。不仅如此,开放源码项目需要在精确交流技术细节和小组决策方面得到支持 (二)版本控制、文档管理和发行   任何软件开发项目都需要版本控制,开放源码项目在这方面更是需要强大灵活的支持,以使得许多并行的开发人员可以同时工作在相互重叠的文件集上。开放源码项目也需要设计文档、技术文档和用户文档方面的标准模板,并需要一个良好组织的Web站点来发行这些文档。但是,开放源码项目的本质要求这些文件可供全世界访问,同时日常管理成本则被最小化,维护工作被分配给整个开发社区中的成员。 (三)质量保证   开放源码软件产品取得令人瞩目的质量水平,这一点在封闭源码开发世界被认为是最困难和最耗费资源的软件开发工作之一。开源软件取得高质量的原因主要包括以下三方面:(1)开发人员是根据自己在相关应用领域的兴趣和知识来自我选择的;(2)开发人员对于项目需求心照不宣,因为他们自己就是软件的用户;(3)技术交流(包括错误报告)是公开进行的。此外,调试工作也由于被分解到许多具有不同知识背景的人手中而更高效。 (四)构建和测试管理   开源项目的开发活动是在许多开发人员中发生的连续和并行的行为,有时某个开发人员的更改可能与其他开发者进行的更改发生冲突,通常情况下版本控制活动能够解决这些冲突,但是有时却不行。那些被开发用来支持软件经常自动构建和测试的工具成为帮助尽早发现这类逻辑冲突的强大工具。 (五)项目管理   任何项目都需要明确的目标、资源配置和进度安排,开源社区采取独特的、灵活的方式来解决这类问题——共享的“TO-DO”列表用于跟踪那些需要完成的任务,个人的“TO-DO”列表帮助开发人员保持进度,里程碑列表则基于用户和开发者的反馈设置了灵活截止期限。 (六)知识管理   知识是区分开发高手和初学者的最具价值的资源,高效地共享知识则是开源社区成功的关键所在。清晰地管理知识可以帮助减少初学者的学习曲线,从而降低潜在贡献者的入门壁垒,同时自动地将专家用于培训他人的负担降至最低限度。 <淘宝热门商品:
 

188.00 元  

地球都踩在脚下

T-MAC8麦迪8代 麦8 08-09赛季麦迪篮球鞋 白黑红 阿迪达斯adidas

 

28.00 元  

保健食品,散装,正装由你选


来源:程序员网

小小豆叮

基于事件驱动的解析接口 SAX (实例二)

基于事件驱动的解析接口 SAX (实例二) 实例二、查查看我的 书架 中有多少本 小说 书(获取元素的属性值) 题目是要查出来下面的 XML 文件 books.xml 里有多少本 小说。 <书架> <书 类别="参考书"> <著者>谭浩强 <书名>学习C <价格>20.00 <书 类别="小说"> <著者>吴承恩 <书名>西游记 <价格>120.56 <书 类别="小说"> <著者>曹雪芹 <书名>红楼梦 <价格>208.99 <书 类别="小说"> <著者>睡虫 <书名>下月出版 <价格>0.00 下面的代码使用了 SUN 的 JAXP 包,请在 http://java.sun.com/xml/download.html 下载。 在 Jbuilder4 中运行正确。请注意将要分析的 xml 文件放在 http://localhost/books.xml 或者更改此 URI import org.xml.sax.*; import javax.xml.parsers.*; /** * Title: XML Study, Sample 2 * Description: Count fictions in my shelf. * Copyright: Copyright (c) 2001 * Company: Isolation Land. * @author Slepworm * @version 1.0 */ public class GetAtts extends org.xml.sax.helpers.DefaultHandler{ private int count = 0; // 定义一个计数器 private boolean isFiction; public GetAtts() { } // 创建一个新的 JAXP 的 SAXParserFactory 实例,并且配置它。 public void createParser() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setValidating(false); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(this); xr.parse("http://localhost/books.xml"); } // 当每次碰到一个 book 元素的时候,将 计数器 加一。此方法在遇到第一个元素的时候开始执行 public void startElement(String namespaceURI, String localName, String rawName, Attributes atts) throws SAXException { if (rawName.equals("书")) { String category = atts.getValue("类别"); ///**** 获取 类别 的值 System.out.println(category); //打印 类别 的值 isFiction = (category != null && category.equals("小说")); //如果 类别 的值为 小说 则将计数器加一。 if (isFiction) count++; } } // 输出 计数器。此方法在分析文档完成的时候执行 public void endDocument() throws SAXException { System.out.print(count); } public static void main(String[] args) throws Exception { BookCounter ga = new GetAtts(); ga.createParser(); } } 输出结果 为 参考书 小说 小说 小说 3 <淘宝热门商品:
 

 

哈喽嘟嘟-柠檬绿茶.心蓝t透0.双生儿香港平价店.

 

 

『女人天生是妖精』店内商品均为现货 拍下后可直接留言修改运费


来源:程序员网

小小豆叮

J2EE项目中开发团队的组建 

J2EE这种应用模型允许不同的开发人员同时进行开发的各个元素。这里阐述一下对不同层次 的设计人员,开发人员的技术要求。对以下几个分类进行描述。 • 设计师组建团队 • 表现逻辑层的团队角色 • 业务逻辑层等团队角色 • 数据库访问层的团队角色 团队的组成可以根据人员的数量和系统的范围大小。例如,不一定所有的角色都要分配,有些人可以担当不能的角色。 ****** 设计师 ****** 在基于组件的应用系统开发中,一个或几个人必须对这个系统的整体需求有全面的了解,比如系统的控制流程,和其他的接口等等。有些公司称这个角色为总工程师,不管怎么叫,这个角色非常重要,他承担协调不同开发小组之间的工作,帮助他们考虑系统这个“大图”。 ******************** 表现逻辑层的团队角色 ******************** 在表现层,用户界面是动态生成的。需要如下开发人员: • Java servlet 开发人员 • JSP 开发人员 • HTML 设计人员 • 美工人员 • 客户端的JavaScript 开发人员 Servlet 开发人员建立表现层的逻辑,而其他人员建立表现的形式。 Java Servlet 开发人员 Servlet处理页和页之间的浏览,会话管理,简单的输入验证。Servlet也将业务逻辑的元素连接起来。 Servlet开发人员必须理解一些相关事宜,HTTP请求,安全,多语言,和一些页面元素如session, cookie,超时等等。J2EE的应用里面,servlet必须用Java来写,Servlet可能会调用JSP, EJB, JDBC等等。因此,servlet开发人员要与应用系统的其他人员紧密合作。 JSP 开发人员 JSP开发人员与servlet开发人员密切合作来定义系统的表现层页面。即使在复杂的开发项目里,JSP和servlet的开发人员也可能是一个人。 然而,如果一个系统中大部分Java在servlet而不是在JSP里,JSP人员就不必对Java非常熟悉。 HTML 设计人员 HTML 设计人员对HTML页面进行优化。例如,他可能要完成以下任务: • 保证在不同的浏览器中所有的页面都能正常显示 • 保证低速的调制解调器访问也不受影响 • 对JSP设计人员的页面进行进一步的优化 美工人员 美工人员创建图片等等。这些图片要能小体积,快速下载。美工与HTML页面人员紧密合作。 客户端的JavaScript 开发人员 使用客户端的JavaScript有很多原因。比如,可以处理简单的输入验证,不必提交给服务器,还可以让用户界面更生动。这个角色和servlet, JSP人员紧密合作。 ******************** 业务逻辑层的团队角色 ******************** 业务逻辑层包含业务规则和业务实体。需要以下人员: • Session bean 开发人员 • Entity bean 开发人员 Session Bean 开发人员 Session beans包含业务处理和业务规则的逻辑。比如,一个session bean 可能设计成计算一个支票的税率。如果一个系统面临处理经常变化的复杂逻辑,而又大量使用session bean,结果是,session bean就需要不断的更新。 Session bean 的开发人员一般是一个领域的专家,理解复杂的,专门领域的逻辑,还有数据验证的规则。这个人员与servlet和entity bean开发人员紧密合作。 Session bean可能需要调用JDBC接口,和其他的EJB。无状态的session bean系统运行的会更好一些。因为,如果计算费率是一个有状态的session bean,系统就必须访问一个保存bean的状态信息的服务器。如果那个服务器恰巧出现问题,整个流程就会受阻。 Entity Bean 开发人员 Entity bean代表永久的对象,如一个数据库中的一条记录。Entity bean开发人员的任务是设计一个面向对象的所有业务数据的组织图。建立面向对象的试图意味着要将数据库中的表(关系型的)映射成entity bean。例如,开发人员需要将客户表,发票表,和订单表转换成相应的客户,发票,和订单对象。 一个entity bean 开发人员与session bean, Servlet开发人员密切合作,保证应用系统提供快速的,灵活的,可扩展的对业务数据的访问。 Entity bean 可能会大量的调用JDBC接口。而entity bean 之间的调用会很少。 ********************** 数据库访问层的团队角色 ********************** 在数据库访问层,开发人员需要建立关系型数据库的ER图,数据字典等等相关文档。所有对数据库的修改,访问等等权限操作都要经过数据库访问层开发人员。这个角色在大部分项目中担当DBA的角色。 团队组建之后,就可以开始设计用户界面。 ************ 设计用户界面 ************ 建议从前到后开始设计应用系统。就是说,先设计用户界面,再设计EJB,这样效率最高。 安博公司已经做了大量的界面设计工作,以后的工作完全可以参照已有的设计。下面提一些常用的建议性问题: • 页面流程是什么? • 每个页面上的命令按钮是什么? • 是否适用frame? • 是否有公司标准的Logo,广告条幅? • 在什么地方需要登录过程? • 多语言的问题? 这些和设计servlet, JSP相关。 <淘宝热门商品:
 

188.00 元  

地球都踩在脚下

T-MAC8麦迪8代 麦8 08-09赛季麦迪篮球鞋 白黑红 阿迪达斯adidas

 

¥:21.00 

【义乌绘美家居】【收藏本店送礼品】


来源:程序员网

小小豆叮

Servlet运行环境所需的软件安装及WAP编程环境设置

(本教程以Windows2000/Jswdk1.01/jdk1.3为例) 1:下载Jswdk1.01(jswdk1_0_1-win.zip 745Kb) 2:下载Jdk1.3(j2sdk1_3_0-win.exe 29.4 MB) 安装完以上两个文后,请在Windows2000上做如下的Path,PathClass设置(尚未设定IIS WAP运行环境的,可参照WAP86的"WAP建站指南"): (1):右击“我的电脑”--“属性”---“高级”--“环境变量” (2):在“系统变量”框中“新建....” 变量名 “path” 变量值 “d:\jdk1.3路径\bin” (3) “确定”后然后再“新建....” 变量名 “classpath” 变量值 “d:\jdk1.3\lib\tools.jar;D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\lib\servlet.jar;D:\xing\servlet \swdk1_0_1-win\jswdk-1.0.1\webserver.jar” 启动服务:执行jswdk-1.0.1目录下的startserver.bat 注:安装路径视你的安装情况而定,请自行修改之,下同! 3、 测试是否安装设置成功: 在IE中键入:“http://localhost:8080”如果成功,你将看到如下页面: 4、 增加一个测试用的虚拟目录(testwml): (1)、 打开jswdk-1.0.1目录下的webserver.xml,并在 和之间加入: “” (2)、 在“D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\”下建立 “WEB-INF\servlets\”目录。 (这样,当在WAP模拟器中键入:http://localhost:8080/testwml/servlet/wap86test Jswdk就会自动在testwml目录下的WEB-INF\servlets\中去找wap86test.class) (3)、 重新启动服务:执行jswdk-1.0.1目录下的stopserver.bat 然后再执行startserver.bat [b]用servlet生成WML[/b] 1.源程序 wap86test.java: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class wap86test extends HttpServlet { public void service (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/vnd.wap.wml"); PrintWriter out = response.getWriter(); out.println(""); out.println("out.println(" \"http://www.wapforum.org/DTD/wml_1.1.xml\">"); out.println(""); out.println(""); out.println(" "); out.println("Date and Time Service "); out.println("Date is: "+ new java.util.Date()); out.println(" "); out.println(""); out.println(""); } } 2:编译源程序 “开始”--“运行...” ---键入“javac D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\testwml\WEB-INF\servlets\wap86test.java” 此时你以看到在"D:\xing\servlet\swdk1_0_1-win\jswdk-1.0.1\testwml\WEB-INF\servlets\"目录下会多出一个wap86test.class 文件!   如果你想看到更多的编译信息,请在MS-DOS窗口中输入以上命令. 3:大功告成! <淘宝热门商品:
 

68.00 元 

超人气神奇魔水 柔嫩细滑肌肤一喷即成

 

185.00 元  

累计销售1000多件 G-STAR 雪纺短款夹克


来源:程序员网

小小豆叮

一个文件上传JavaBean



package com.upload; 

import java.io.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.ServletInputStream; 
import javax.servlet.ServletException; 

public class upload{ 
private static String newline = "
"; 
private String uploadDirectory = "."; 
private String ContentType = ""; 
private String CharacterEncoding = ""; 

private String getFileName(String s){ 
int i = s.lastIndexOf(""); 
if(i < 0 // i >= s.length() - 1){ 
i = s.lastIndexOf("/"); 
if(i < 0 // i >= s.length() - 1) 
return s; 
} 
return s.substring(i + 1); 
} 

public void setUploadDirectory(String s){ 
uploadDirectory = s; 
} 

public void setContentType(String s){ 
ContentType = s; 
int j; 
if((j = ContentType.indexOf("boundary=")) != -1){ 
ContentType = ContentType.substring(j + 9); 
ContentType = "--" + ContentType; 
} 
} 

public void setCharacterEncoding(String s){ 
CharacterEncoding = s; 
} 

public void uploadFile( HttpServletRequest req) throws ServletException, IOException{ 
setCharacterEncoding(req.getCharacterEncoding()); 
setContentType(req.getContentType()); 
uploadFile(req.getInputStream()); 
} 

public void uploadFile( ServletInputStream servletinputstream) throws ServletException, IOException{ 

String s5 = null; 
String filename = null; 
byte Linebyte[] = new byte[4096]; 
byte outLinebyte[] = new byte[4096]; 
int ai[] = new int[1]; 
int ai1[] = new int[1]; 

String line; 
//得到文件名 
while((line = readLine(Linebyte, ai, servletinputstream, CharacterEncoding)) != null){ 
int i = line.indexOf("filename="); 
if(i >= 0){ 
line = line.substring(i + 10); 
if((i = line.indexOf(""")) > 0) 
line = line.substring(0, i); 
break; 
} 
} 

filename = line; 

if(filename != null && !filename.equals(""")){ 
filename = getFileName(filename); 

String sContentType = readLine(Linebyte, ai, servletinputstream, CharacterEncoding); 
if(sContentType.indexOf("Content-Type") >= 0) 
readLine(Linebyte, ai, servletinputstream, CharacterEncoding); 

//File(String parent, String child) 
//Creates a new File instance from a parent pathname string 
//and a child pathname string. 
File file = new File(uploadDirectory, filename); 

//FileOutputStream(File file) 
//Creates a file output stream to write to the file represented 
//by the specified File object. 
FileOutputStream fileoutputstream = new FileOutputStream(file); 

while((sContentType = readLine(Linebyte, ai, servletinputstream, CharacterEncoding)) != null){ 
if(sContentType.indexOf(ContentType) == 0 && Linebyte[0] == 45) 
break; 

if(s5 != null){ 
//write(byte[] b, int off, int len) 
//Writes len bytes from the specified byte array starting 
//at offset off to this file output stream. 
fileoutputstream.write(outLinebyte, 0, ai1[0]); 
fileoutputstream.flush(); 
} 
s5 = readLine(outLinebyte, ai1, servletinputstream, CharacterEncoding); 
if(s5 == null // s5.indexOf(ContentType) == 0 && outLinebyte[0] == 45) 
break; 
fileoutputstream.write(Linebyte, 0, ai[0]); 
fileoutputstream.flush(); 
} 

byte byte0; 
if(newline.length() == 1) 
byte0 = 2; 
else 
byte0 = 1; 
if(s5 != null && outLinebyte[0] != 45 && ai1[0] > newline.length() * byte0) 
fileoutputstream.write(outLinebyte, 0, ai1[0] - newline.length() * byte0); 
if(sContentType != null && Linebyte[0] != 45 && ai[0] > newline.length() * byte0) 
fileoutputstream.write(Linebyte, 0, ai[0] - newline.length() * byte0); 

fileoutputstream.close(); 
} 
} 

private String readLine(byte Linebyte[], int ai[], 
ServletInputStream servletinputstream, 
String CharacterEncoding){ 
try{ 
//readLine(byte[] buffer, int offset, int length) 
//Reads a line from the POST data. 
ai[0] = servletinputstream.readLine(Linebyte, 0, Linebyte.length); 
if(ai[0] == -1) 
return null; 
}catch(IOException _ex){ 
return null; 
} 
try{ 
if(CharacterEncoding == null){ 
//用缺省的编码方式把给定的byte数组转换为字符串 
//String(byte[] bytes, int offset, int length) 
return new String(Linebyte, 0, ai[0]); 
}else{ 
//用给定的编码方式把给定的byte数组转换为字符串 
//String(byte[] bytes, int offset, int length, String enc) 
return new String(Linebyte, 0, ai[0], CharacterEncoding); 
} 
}catch(Exception _ex){ 
return null; 
} 
} 
/* 
public int readLine(byte[] buffer, 
int offset, 
int length) throws java.io.IOException 
从POST来的数据中读一行 
参数: 
buffer - buffer to hold the line data 
offset - offset into the buffer to start 
length - maximum number of bytes to read. 
Returns: 
number of bytes read or -1 on the end of line. 
*/ 
} 

<淘宝热门商品:
 

2.35 元  

露连泉百货超级市场

阿尔卑斯喜缘喜糖 全市最低价

 

128.00 元  

【广州商盟】*大学生淘宝皇冠第一店-鞋神--三人行出口剩余旗舰店

【大学生皇冠店】new balance纽巴伦378经典款 天蓝


来源:程序员网

小小豆叮

信息系统建模方法

周中元 我有话说……    大型信息系统通常十分复杂,很难直接对它进行分析设计,人们经常借助模型来设计分析系统。模型是现实世界中的某些事物的一种抽象表示。抽象的含义是抽取事物的本质特性,忽略事物的其他次要因素。因此,模型既反映事物的原型,又不等于该原型。模型是理解、分析、开发或改造事物原型的一种常用手段。例如,建造大楼前常先做大楼的模型,以便在大楼动工前就能使人们对未来的大楼有一个十分清晰的感性认识,显然,大楼模型还可以用来改进大楼的设计方案。   在信息系统中,模型是开发过程中的一个不可缺少的工具。信息系统包括数据处理、事务管理和决策支持。实质上,信息系统可以看成是由一系列有序的模型构成的,这些有序模型通常为:功能模型、信息模型、数据模型、控制模型和决策模型,所谓有序是指这些模型上分别在系统的不同开发阶段、不同开发层次上建立的。 信息建模方法介绍   模型的表示形式可以是数学公式、缩小的物理装置、图表文字说明,也可以是专用的形式化语言。模型建立的思路有两种:自顶向下、逐步求精和自底向上、综合集成。   模型的目标即模型研究的目的,知识是指现实系统的知识和模型构造知识,数据是指系统的原始信息,这三方面构成了建模过程的输入。模型构造是具体的建模技术的运用过程。可信性分析是指分析所建模型能否满足系统目标。   信息系统模型的表现形式与普通系统模型是有区别的。描述信息系统模型最常见的方法是形式化描述和图示化描述。形式化描述方法非常精确、严谨,易于系统以后的实现,但难以掌握和理解,模型可读性差,往往只有专业人员才会使用,因而难于推广。图示化方法直观、自然,易于描述系统的层次结构、功能组成,且简单易学,通常还有工具软件支持,因而成为信息系统的主要描述工具,但这种方法的精确性和严谨性不够。   信息系统的建模方法可以分为:面向过程的建模、面向数据的建模、面向信息的建模、面向决策的建模和面向对象的建模五种。   面向过程的建模方法是把过程看作系统模型的基本部分,数据是随着过程而产生的。最有影响的面向过程的设计方法是Yourdon设计法。   面向数据的建模方法把模型的输入输出看成是最为重要的,因此,首先定义的是数据结构,而过程模块是从数据结构中导出的,即功能跟随数据。最有影响的面向数据的设计方法是Jackson设计法。   面向信息的建模方法与面向数据建模方法的区别就是信息和数据的区别。信息和数据都是信息系统中最基本的术语,数据是指记载下来的事实,是客观实体属性的值,而信息是构成一定含义的一组数据。面向信息建模方法是从整个系统的逻辑数据模型开始的,通过一个全局信息需求视图来说明系统中所有基本数据实体及其相互关系,然后,在此基础上逐步构造整个模型,信息模型记录系统运作所需的信息实体,如:人员,地点,事物,观念等,为分析现行系统提供信息的图形化表示。数据建模的目的是设计和实现满足系统信息需求的数据库结构,即数据建模支持系统设计。   决策支持系统由数据库、模型库和各自的管理系统组成。决策支持系统模型需要反映的问题是系统的决策制订原则和机理、系统的组织机构和人员配置。通过对决策系统的建模,企业的领导可以对企业有一个细致的了解,从而发现其中问题。如组织结构臃肿,职权划分不清,权力范围不合理等,据此进行相应的改革。比较成熟的决策支持系统建模方法有Petri网和GRAI法。   面向对象的分析方法是利用面向对象的信息建模概念,如实体、关系、属性等,同时运用封装、继承、多态等机制来构造模拟现实系统的方法。传统的结构化设计方法的基本点是面向过程,系统被分解成若干个过程。而面向对象的方法是采用构造模型的观点,在系统的开发过程中,各个步骤的共同的目标是建造一个问题域的模型。在面向对象的设计中,初始元素是对象,然后将具有共同特征的对象归纳成类,组织类之间的等级关系,构造类库。在应用时,在类库中选择相应的类。 IDEF方法族介绍   IDEF的含义是集成计算机辅助制造(Integrated Computer-AidedManufacturing,ICAM)DEFinition。最初的IDEF方法是在美国空军ICAM项目建立的,最初开发3种方法:功能建模(IDEF0)、信息建模(IDEF1)、动态建模(IDEF2),后来,随着信息系统的相继开发,又开发出了下列IDEF族方法:数据建模(IDEF1X)、过程描述获取方法(IDEF3)、面向对象的设计(OO设计)方法(IDEF4)、使用C++语言的OO设计方法(IDEF4C++)、实体描述获取方法(IDEF5)、设计理论(rationale)获取方法(IDEF6)、人-系统交互设计方法(IDEF8)、业务约束发现方法(IDEF9)、网络设计方法(IDEF14)等。根据用途,可以把IDEF族方法分成两类:   第一类IDEF方法的作用是沟通系统集成人员之间的信息交流。主要有:IDEF0、IDEF1、IDEF3、IDEF5。IDEF0通过对功能的分解、功能之间关系的分类(如按照输入、输出、控制和机制分类)来描述系统功能。IDEF1用来描述企业运作过程中的重要信息。IDEF3支持系统用户视图的结构化描述。IDEF5用来采集事实和获取知识。   第二类IDEF方法的重点是系统开发过程中的设计部分。目前有两种IDEF设计方法:IDEF1X和IDEF4。IDEF1X可以辅助语义数据模型的设计。IDEF4可以产生面向对象实现方法所需的高质量的设计产品。   下面简单介绍几种主要IDEF族方法。 IDEF1信息建模方法   IDEF1方法的作用是在需求分析时对所建系统的信息资源进行分析和交流。IDEF1通常用来:(1)确定组织中当前管理的是什么信息,(2)对需求分析过程中发现的问题确定哪些是由于缺乏合适的信息引起的,(3)指定在TO-BE实施中,哪些信息需要管理。   从IDEF1的角度看信息系统,它不但包括自动化系统的成分,也包括非自动化的成分,如人员,文件柜,电话等等。与数据库设计方法不同,IDEF1是分析以下问题的一种方法:   企业信息的采集、存储和管理;   信息的管理规则;   企业内信息之间的逻辑关系;   缺乏良好的信息管理导致的问题。   IDEF1使用简单的图形约定来表达复杂的规则集合。这些规则有助于建模者区分(1)现实世界的对象,(2)现实世界对象之间的物理或抽象的联系,(3)现实世界对象的信息管理,(4)用来表示信息的需求、应用和管理的数据结构。IDEF1的目标之一就是为信息分析提供一个结构化的、规程化的方法。IDEF1可以减少建模过程中的不完整性、不精确性、不一致性和不准确性。   IDEF1是描述企业信息需求的一个有效方法。IDEF1建模奠定了数据库设计基础,给出了信息结构定义,提供了反映基本信息需求的需求说明。IDEF1使用规程化的、结构化的技术以找出一个组织所使用的信息和业务规则。IDEF1要求信息用户积极参与,使用户认真思考信息如何使用和管理。最后,信息模型在企业的整个生命周期均有用的。 IDEF3过程描述获取方法   IDEF3为收集和记录过程提供了一种机制。IDEF3以自然的方式记录状态和事件之间的优先和因果关系,办法是为表达一个系统、过程或组织如何工作的知识提供一种结构化的方法。IDEF3可以:   记录在调研过程中产生的原始数据;   确定信息资源在企业的主要业务流程中的作用;   记录决策过程,特别是关于制造、工程和维修的产   品定义数据的决策过程;   管理数据配置和更改控制策略定义;   进行系统设计和分析;   提供模拟模型。   IDEF3描述现有系统或建议系统的行为方面内容。IDEF3作为描述系统直觉知识的工具,获取的过程知识是结构化的。IDEF3还记录了所有时间性的信息,包括与企业处理过程相关的优先和因果关系。IDEF3描述的结果是为分析和设计模型提供一个结构化的知识库。与构造预测性的数据模型的模拟语言(如SIMAN,SLAM,GPSS,WITNESS)不同,IDEF3构造一个结构化的描述。这些描述获取关于系统实际运作什么或将要做什么,同时提供该系统的不同用户的视图表示。   IDEF3有两种描述方式:过程流和对象状态转变网络。IDEF3过程流描述过程以及过程之间的关系网络,描述"如何做"的知识,如描述一个部位在制造过程中发生的情况。这些过程间的关系是在整个业务流程中产生的,描述的目的是说明事物是如何运作的。 IDEF4面向对象设计方法   在美国空军Armstrong实验室倡导下开发的IDEF4方法可以应用于使用面向对象技术的应用中。IDEF4是由专业的面向对象的设计人员和编程人员开发的,选择IDEF4方法的最重要的原因是它把面向对象的设计看作是大系统开发框架的一部分,而不是把面向对象的设计和分析相隔离。IDEF4强调在面向对象的设计过程中的图形化语法,使用图形化语法和图示有助于对重要的设计事件进行集中和交流。   IDEF4与其他对象设计方法有明显的区别,最主要的是它支持"最小委托(leastcommitment)"策略,支持在类继承、对象组成、功能分解和多态方面的设计评估。   IDEF4把面向对象的设计活动划分成离散的、可管理的大块。每个子活动由一个强调设计决策的图形化语法支持。IDEF4方法很容易让设计者在设计类继承、类组成、功能分解和多态之间作平衡。IDEF4更是一个图形化的语法,它为运用和发展面向对象的设计提供了一个一致的框架,而这一设计最终是由类不变数据清单和方法集约定描述的。   一个IDEF4模型由两个子模型组成:类子模型和方法子模型。两个子模型通过一个调度映射连接。这两个结构描述设计模型中的所有信息。   类子模型由下列类型的图示组成:(1)定义类继承关系的继承图示;(2)定义类组合的类型图示;(3)定义方法调用规约的规约图示;(4)描述对象例示流程的例示图示,这些例示流程有助于设计者对设计进行核查。   方法子模型由下列两个图示类组成:(1)按照行为相似性区分方法类型的方法分类学图示和(2)为功能分解,说明方法的客户和提供者的客户图示。 IDEF5实体论(Ontology)描述获取方法   实体论历史上起源于形而上学这一哲学分支,主要研究客观世界的本质。传统的实体论研究目的是将客观世界进行分割以发现其基本组成成分。自然科学提供了关于实体论研究的一个极好范例。例如,原子物理学将现实世界的物质作了最基本的分类(如质子、电子、中子),生物科学将地球上各种生物进行分类描述。   IDEF5方法是一种具有扎实的理论和实践基础的方法,用于实现实体的建立、修改和维护。该方法所提供的标准化的过程,直观自然的表现能力,高质量的结果,有助于降低开发的成本。   实体分析由三个过程来实现,即用于描述某领域特定对象和过程的词汇集,开发该词汇集中基本术语的定义,刻画术语间的逻辑联系。   实体由三部分组成,它们是某一领域使用的术语集、术语使用规则、推论。在每个领域有很多自然现象,人们用对象(概念的或物理的)、状态和联系加以区别,不同的语言对这些现象有不同的表达方式。在实体论中,"关系"是对客观世界中的联系进行确定的描述,"术语"是对客观世界对象或状态进行确定的描述。   在构造实体时,试图将这些描述进行归类,建立某特定领域的表达模型(比如数据字典)。构造一个实体需要以下三步工作:(1)将术语分类,(2)寻找术语的约束关系,(3)建立模型,该模型能将给定的描述语句变成"恰当"的表达。所谓"恰当"具有两方面的含义,首先,在通常情况下输入一种描述语句可能会产生大量的输出语句,而实体模型只生成在上下文中有用的子集;其次,生成的描述语句表达实际的情况。我们称该模型包含被认可的推理。也可以说模型刻画了对象的行为和该领域的联系。由此看来,实体与数据字典非常相似,所不同的是实体同时包括了语法和领域的行为模型。 <淘宝热门商品:
 

86.00 元  

艾尔微品牌店//九阳豆浆机//女士精品-三钻100%真人拍摄

Disney Mickey 迪斯尼米奇多色手动机芯机械中性手表

 

¥:29.00 

‖ 淘时尚 ‖入托名字条‖布质可烫可缝‖姓名贴‖

‖四钻‖棉质耐洗‖全彩色免缝姓名条 熨烫入托名字条 迪斯尼


来源:程序员网

小小豆叮

面向对象软件的测试

-------------------------------------------------------------------------------- 一 引言(Introduction)   用户使用低质量的软件,在运行过程中会产生各种各样的问题,可能带来不同程度的严重后果,轻者影响系统的正常工作,重者造成事故,损失生命财产。软件测试是保证软件质量的最重要的手段。什么是软件测试?1983年IEEE定义为:使用人工或自动手段来运行或测定某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差别。   现代的软件开发工程是将整个软件开发过程明确的划分为几个阶段,将复杂问题具体按阶段加以解决。这样,在软件的整个开发过程中,可以对每一阶段提出若干明确的监控点,作为各阶段目标实现的检验标准,从而提高开发过程的可见度和保证开发过程的正确性。经验证明,软件的质量不仅是体现在程序的正确性上,它和编码以前所做的需求分析,软件设计密切相关。软件使用中出现的错误,不一定是编程人员在编码阶段引入的,很可能在程序设计,甚而需求分析时就埋下了祸因。这时,对错误的纠正往往不能通过可能会诱发更多错误的简单的修修补补,而必须追溯到软件开发的最初阶段。这无疑增大了软件的开发费用。因此,为了保证软件的质量,我们应该着眼于整个软件生存期,特别是着眼于编码以前的各开发阶段的工作。这样,软件测试的概念和实施范围必须扩充,应该包括在整个开发各阶段的复查、评估和检测。由此,广义的软件测试实际是由确认、验证、测试三个方面组成(注:本文对后面用广义测试概念处不另加标识):   确认:是评估将要开发的软件产品是否是正确无误、可行和有价值的。比如,将要开发的软件是否会满足用户提出的要求,是否能在将来的实际使用环境中正确稳定的运行,是否存在隐患等。这里包含了对用户需求满足程度的评价。确认意味着确保一个待开发软件是正确无误的,是对软件开发构想的检测。   验证:是检测软件开发的每个阶段、每个步骤的结果是否正确无误,是否与软件开发各阶段的要求或期望的结果相一致。验证意味着确保软件是会正确无误的实现软件的需求,开发过程是沿着正确的方向在进行。   测试:与狭隘的测试概念统一。通常是经过单元测试、集成测试、系统测试三个环节。   在整个软件生存期,确认、验证、测试分别有其侧重的阶段。确认主要体现在计划阶段、需求分析阶段、也会出现在测试阶段;验证主要体现在设计阶段和编码阶段;测试主要体现在编码阶段和测试阶段。事实上,确认、验证、测试是相辅相成的。确认无疑会产生验证和测试的标准,而验证和测试通常又会帮助完成一些确认,特别是在系统测试阶段。   面向对象技术是一种全新的软件开发技术,正逐渐代替被广泛使用的面向过程开发方法,被看成是解决软件危机的新兴技术。面向对象技术产生更好的系统结构,更规范的编程风格,极大的优化了数据使用的安全性,提高了程序代码的重用,一些人就此认为面向对象技术开发出的程序无需进行测试。应该看到,尽管面向对象技术的基本思想保证了软件应该有更高的质量,但实际情况却并非如此,因为无论采用什么样的编程技术,编程人员的错误都是不可避免的,而且由于面向对象技术开发的软件代码重用率高,更需要严格测试,避免错误的繁衍。因此,软件测试并没有面向对象编程的兴起而丧失掉它的重要性。   从1982年在美国北卡罗来纳大学召开首次软件测试的正式技术会议至今,软件测试理论迅速发展,并相应出现了各种软件测试方法,使软件测试技术得到极大的提高。然而,一度实践证明行之有效的软件测试对面向对象技术开发的软件多少显得有些力不从心。尤其是面向对象技术所独有的多态,继承,封装等新特点,产生了传统语言设计所不存在的错误可能性,或者使得传统软件测试中的重点不再显得突出,或者使原来测试经验认为和实践证明的次要方面成为了主要问题。例如:   在传统的面向过程程序中,对于函数   y=Function(x);   你只需要考虑一个函数(Function())的行为特点,而在面向对象程序中,你不得不同时考虑基类函数(Base::Function())的行为和继承类函数(Derived::Function())的行为。   面向对象程序的结构不再是传统的功能模块结构,作为一个整体,原有集成测试所要求的逐步将开发的模块搭建在一起进行测试的方法已成为不可能。而且,面向对象软件抛弃了传统的开发模式,对每个开发阶段都有不同以往的要求和结果,已经不可能用功能细化的观点来检测面向对象分析和设计的结果。因此,传统的测试模型对面向对象软件已经不再适用。针对面向对象软件的开发特点,应该有一种新的测试模型。 二 面向对象测试模型(Object-Orient Test Model)   面向对象的开发模型突破了传统的瀑布模型,将开发分为面向对象分析(OOA),面向对象设计(OOD),和面向对象编程(OOP)三个阶段。分析阶段产生整个问题空间的抽象描述,在此基础上,进一步归纳出适用于面向对象编程语言的类和类结构,最后形成代码。由于面向对象的特点,采用这种开发模型能有效的将分析设计的文本或图表代码化,不断适应用户需求的变动。针对这种开发模型,结合传统的测试步骤的划分,本文建议一种整个软件开发过程中不断测试的测试模型,使开发阶段的测试与编码完成后的单元测试、集成测试、系统测试成为一个整体。测试模型如下图所示:                    0                      面向对象编程        OOA Test:面向对象分析的测试      OOD Test:面向对象设计的测试        OOP Test:面向对象编程的测试      OO Unit Test:面向对象单元测试        OO Integrate Test:面向对象集成测试  OO System Test:面向对象系统测试   OOA Test和OOD Test 是对分析结果和设计结果的测试,主要是对分析设计产生的文本进行,是软件开发前期的关键性测试。OOP Test主要针对编程风格和程序代码实现进行测试,其主要的测试内容在面向对象单元测试和面向对象集成测试中体现。面向对象单元测试是对程序内部具体单一的功能模块的测试,如果程序是用C++语言实现,主要就是对类成员函数的测试。面向对象单元测试是进行面向对象集成测试的基础。面向对象集成测试主要对系统内部的相互服务进行测试,如成员函数间的相互作用,类间的消息传递等。面向对象集成测试不但要基于面向对象单元测试,更要参见OOD或OOD Test结果(详见后叙述)。面向对象系统测试是基于面向对象集成测试的最后阶段的测试,主要以用户需求为测试标准,需要借鉴OOA或OOA Test结果。   尽管上述各阶段的测试构成一相互作用的整体,但其测试的主体、方向和方法各有不同,且为叙述的方便,本文接下来将从OOA,OOD,OOP,单元测试,集成测试,系统测试六个方面分别介绍对面向对象软件的测试。 三 面向对象分析的测试(OOA Test)   传统的面向过程分析是一个功能分解的过程,是把一个系统看成可以分解的功能的集合。这种传统的功能分解分析法的着眼点在于一个系统需要什么样的信息处理方法和过程,以过程的抽象来对待系统的需要。而面向对象分析(OOA)是"把E-R图和语义网络模型,即信息造型中的概念,与面向对象程序设计语言中的重要概念结合在一起而形成的分析方法",最后通常是得到问题空间的图表的形式描述。   OOA直接映射问题空间,全面的将问题空间中实现功能的现实抽象化。将问题空间中的实例抽象为对象(不同于C++中的对象概念),用对象的结构反映问题空间的复杂实例和复杂关系,用属性和服务表示实例的特性和行为。对一个系统而言,与传统分析方法产生的结果相反,行为是相对稳定的,结构是相对不稳定的,这更充分反映了现实的特性。OOA的结果是为后面阶段类的选定和实现,类层次结构的组织和实现提供平台。因此,OOA对问题空间分析抽象的不完整,最终会影响软件的功能实现,导致软件开发后期大量可避免的修补工作;而一些冗余的对象或结构会影响类的选定、程序的整体结构或增加程序员不必要的工作量。因此,本文对OOA的测试重点在其完整性和冗余性。   尽管OOA的测试是一个不可分割的系统过程,为叙述的方便,对OOA阶段的测试划分为以下五个方面:   ☆ 对认定的对象的测试   ☆ 对认定的结构的测试   ☆ 对认定的主题的测试   ☆ 对定义的属性和实例关联的测试   ☆ 对定义的服务和消息关联的测试      1 对认定的对象的测试:   OOA中认定的对象是对问题空间中的结构,其他系统,设备,被记忆的事件,系统涉及的人员等实际实例的抽象(参见[2])。对它的测试可以从如下方面考虑:   1.1 认定的对象是否全面,是否问题空间中所有涉及到的实例都反映在认定的抽象对象中。   1.2 认定的对象是否具有多个属性。只有一个属性的对象通常应看成其他对象的属性,而不是抽象为独立的对象。   1.3 对认定为同一对象的实例是否有共同的,区别于其他实例的共同属性。   1.4 对认定为同一对象的实例是否提供或需要相同的服务,如果服务随着不同的实例而变化,认定的对象就需要分解或利用继承性来分类表示。   1.5 如果系统没有必要始终保持对象代表的实例的信息,提供或者得到关于它的服务,认定的对象也无必要。   1.6 认定的对象的名称应该尽量准确,适用。   2 对认定的结构的测试   在Coad方法中,认定的结构指的是多种对象的组织方式,用来反映问题空间中的复杂实例和复杂关系。认定的结构分为两种:分类结构和组装结构。分类结构体现了问题空间中实例的一般与特殊的关系,组装结构体现了问题空间中实例整体与局部的关系。   2.1 对认定的分类结构的测试可从如下方面着手:     2.1.1 对于结构中的一种对象,尤其是处于高层的对象,是否在问题空间中含有不同于下一层对象的特殊可能性,即是否能派生出下一层对象。     2.1.2 对于结构中的一种对象,尤其是处于同一低层的对象,是否能抽象出在现实中有意义的更一般的上层对象。     2.1.3 对所有认定的对象,是否能在问题空间内向上层抽象出在现实中有意义的对象     2.1.4 高层的对象的特性是否完全体现下层的共性     2.1.5 低层的对象是否有高层特性基础上的特殊性   2.2 对认定的组装结构的测试从如下方面入手:     2.2.1 整体(对象)和部件(对象)的组装关系是否符合现实的关系。     2.2.2 整体(对象)的部件(对象)是否在考虑的问题空间中有实际应用。     2.2.3 整体(对象)中是否遗漏了反映在问题空间中有用的部件(对象)。     2.2.4 部件(对象)是否能够在问题空间中组装新的有现实意义的整体(对象)。   3 对认定的主题的测试   主题是在对象和结构的基础上更高一层的抽象,是为了提供OOA分析结果的可见性,如同文章对各部分内容的概要。对主题层的测试应该考虑以下方面:   3.1 贯彻George Miller 的"7+2"原则,如果主题个数超过7个,就要求对有较密切属性和服务的主题进行归并。   3.2 主题所反映的一组对象和结构是否具有相同和相近的属性和服务。   3.3 认定的主题是否是对象和结构更高层的抽象,是否便于理解OOA结果的概貌(尤其是对非技术人员的OOA 结果读者)。   3.4 主题间的消息联系(抽象)是否代表了主题所反映的对象和结构之间的所有关联。   4 对定义的属性和实例关联的测试   属性是用来描述对象或结构所反映的实例的特性。而实例关联是反映实例集合间的映射关系。对属性和实例关联的测试从如下方面考虑:   4.1 定义的属性是否对相应的对象和分类结构的每个现实实例都适用。   4.2 定义的属性在现实世界是否与这种实例关系密切。   4.3 定义的属性在问题空间是否与这种实例关系密切。   4.4 定义的属性是否能够不依赖于其他属性被独立理解。   4.5 定义的属性在分类结构中的位置是否恰当,低层对象的共有属性是否在上层对象属性体现。   4.6 在问题空间中每个对象的属性是否定义完整。   4.7 定义的实例关联是否符合现实。   4.8 在问题空间中实例关联是否定义完整,特别需要注意1-多和多-多的实例关联。   5 对定义的服务和消息关联的测试   定义的服务,就是定义的每一种对象和结构在问题空间所要求的行为。由于问题空中实例间必要的通信,在OOA 中相应需要定义消息关联(详细内容参见[3])。对定义的服务和消息关联的测试从如下方面进行:   5.1 对象和结构在问题空间的不同状态是否定义了相应的服务。   5.2 对象或结构所需要的服务是否都定义了相应的消息关联。   5.3 定义的消息关联所指引的服务提供是否正确。   5.4 沿着消息关联执行的线程是否合理,是否符合现实过程。   5.5 定义的服务是否重复,是否定义了能够得到的服务。 四 面向对象设计的测试(OOD Test)   通常的结构化的设计方法,用的"是面向作业的设计方法,它把系统分解以后,提出一组作业,这些作业是以过程实现系统的基础构造,把问题域的分析转化为求解域的设计,分析的结果是设计阶段的输入"。   而面向对象设计(OOD)采用"造型的观点",以OOA为基础归纳出类,并建立类结构或进一步构造成类库,实现分析结果对问题空间的抽象。OOD 归纳的类,可以是对象简单的延续,可以是不同对象的相同或相似的服务。由此可见,OOD不是在OOA上的另一思维方式的大动干戈,而是OOA的进一步细化和更高层的抽象。所以,OOD与OOA 的界限通常是难以严格区分的。OOD确定类和类结构不仅是满足当前需求分析的要求,更重要的是通过重新组合或加以适当的补充,能方便实现功能的重用和扩增,以不断适应用户的要求。因此,对OOD的测试,本文建议针对功能的实现和重用以及对OOA结果的拓展,从如下三方面考虑:   ☆ 对认定的类的测试   ☆ 对构造的类层次结构的测试   ☆ 对类库的支持的测试   1 对认定的类的测试   OOD认定的类可以是OOA中认定的对象,也可以是对象所需要的服务的抽象,对象所具有的属性的抽象。认定的类原则上应该尽量基础性,这样才便于维护和重用。测试认定的类:   1.1 是否含盖了OOA中所有认定的对象。   1.2 是否能体现OOA中定义的属性。   1.3 是否能实现OOA中定义的服务。   1.4 是否对应着一个含义明确的数据抽象。   1.5 是否尽可能少的依赖其他类。   1.6 类中的方法(C++:类的成员函数)是否单用途。   2 对构造的类层次结构的测试   为能充分发挥面向对象的继承共享特性,OOD的类层次结构,通常基于OOA中产生的分类结构的原则来组织,着重体现父类和子类间一般性和特殊性。两者概念上的差异。在当前的问题空间,对类层次结构的主要要求是能在解空间构造实现全部功能的结构框架。为此,测试如下方面:   2.1 类层次结构是否含盖了所有定义的类。   2.2 是否能体现OOA中所定义的实例关联。   2.3 是否能实现OOA中所定义的消息关联。   2.4 子类是否具有父类没有的新特性。   2.5 子类间的共同特性是否完全在父类中得以体现。   3 对类库支持的测试   对类库的支持虽然也属于类层次结构的组织问题,但其强调的重点是再次软件开发的重用。由于它并不直接影响当前软件的开发和功能实现,因此,将其单独提出来测试,也可作为对高质量类层次结构的评估。拟订测试点如下:   3.1 一组子类中关于某种含义相同或基本相同的操作,是否有相同的接口(包括名字和参数表)。   3.2 类中方法(C++:类的成员函数)功能是否较单纯,相应的代码行是否较少。   3.3 类的层次结构是否是深度大,宽度小。 五 面向对象编程的测试(OOP Test)   典型的面向对象程序具有继承、封装和多态的新特性,这使得传统的测试策略必须有所改变。封装是对数据的隐藏,外界只能通过被提供的操作来访问或修改数据,这样降低了数据被任意修改和读写的可能性,降低了传统程序中对数据非法操作的测试。继承是面向对象程序的重要特点,继承使得代码的重用率提高,同时也使错误传播的概率提高。继承使得传统测试遇见了这样一个难题:对继承的代码究竟应该怎样测试?(参见面向对象单元测试)。多态使得面向对象程序对外呈现出强大的处理能力,但同时却使得程序内"同一"函数的行为复杂化,测试时不得不考虑不同类型具体执行的代码和产生的行为。   面向对象程序是把功能的实现分布在类中。能正确实现功能的类,通过消息传递来协同实现设计要求的功能。正是这种面向对象程序风格,将出现的错误能精确的确定在某一具体的类。因此,在面向对象编程(OOP)阶段,忽略类功能实现的细则,将测试的目光集中在类功能的实现和相应的面向对象程序风格,主要体现为以下两个方面(假设编程使用C++语言)。   ☆ 数据成员是否满足数据封装的要求   ☆ 类是否实现了要求的功能   1 数据成员是否满足数据封装的要求   数据封装是数据和数据有关的操作的集合。检查数据成员是否满足数据封装的要求,基本原则是数据成员是否被外界(数据成员所属的类或子类以外的调用)直接调用。更直观的说,当改编数据成员的结构时,是否影响了类的对外接口,是否会导致相应外界必须改动。值得注意,有时强制的类型转换会破坏数据的封装特性。例如:   class Hiden   {private:   int a=1;   char *p= "hiden";}   class Visible   {public:   int b=2;   char *s= "visible";}   …..   …..   Hiden pp;   Visible *qq=(Visible *)&pp;   在上面的程序段中,pp的数据成员可以通过qq被随意访问。   2 类是否实现了要求的功能   类所实现的功能,都是通过类的成员函数执行。在测试类的功能实现时,应该首先保证类成员函数的正确性。单独的看待类的成员函数,与面向过程程序中的函数或过程没有本质的区别,几乎所有传统的单元测试中所使用的方法,都可在面向对象的单元测试中使用。具体的测试方法在面向对象的单元测试中介绍。类函数成员的正确行为只是类能够实现要求的功能的基础,类成员函数间的作用和类之间的服务调用是单元测试无法确定的。因此,需要进行面向对象的集成测试。具体的测试方法在面向对象的集成测试中介绍。需要着重声明,测试类的功能,不能仅满足于代码能无错运行或被测试类能提供的功能无错,应该以所做的OOD结果为依据,检测类提供的功能是否满足设计的要求,是否有缺陷。必要时(如通过OOD结仍不清楚明确的地方)还应该参照OOA的结果,以之为最终标准。 六 面向对象的单元测试(OO Unit Test)   传统的单元测试是针对程序的函数、过程或完成某一定功能的程序块。沿用单元测试的概念,实际测试类成员函数。一些传统的测试方法在面向对象的单元测试中都可以使用。如等价类划分法,因果图法,边值分析法,逻辑覆盖法,路径分析法,程序插装法等等,方法的具体实现参见[6]。单元测试一般建议由程序员完成。   用于单元级测试进行的测试分析(提出相应的测试要求)和测试用例(选择适当的输入,达到测试要求),规模和难度等均远小于后面将介绍的对整个系统的测试分析和测试用例,而且强调对语句应该有100%的执行代码覆盖率。在设计测试用例选择输入数据时,可以基于以下两个假设:   1. 如果函数(程序)对某一类输入中的一个数据正确执行,对同类中的其他输入也能正确执行。   2. 如果函数(程序)对某一复杂度的输入正确执行,对更高复杂度的输入也能正确执行。例如需要选择字符串作为输入时,基于本假设,就无须计较于字符串的长度。除非字符串的长度是要求固定的,如IP地址字符串。在面向对象程序中,类成员函数通常都很小,功能单一,函数的间调用频繁,容易出现一些不宜发现的错误。例如:   · if (-1==write (fid, buffer, amount)) error_out(); 该语句没有全面检查write()的返回值,无意中断然假设了只有数据被完全写入和没有写入两种情况。当测试也忽略了数据部分写入的情况,就给程序遗留了隐患。   · 按程序的设计,使用函数strrchr()查找最后的匹配字符,但误程序中写成了函数strchr(),使程序功能实现时查找的是第一个匹配字符。   · 程序中将if (strncmp(str1,str2,strlen(str1)))误写成了if (strncmp(str1,str2,strlen(str2)))。如果测试用例中使用的数据str1和str2长度一样,就无法检测出。   因此,在做测试分析和设计测试用例时,应该注意面向对象程序的这个特点,仔细的进行测试分析和设计测试用例,尤其是针对以函数返回值作为条件判断选择,字符串操作等情况。   面向对象编程的特性使得对成员函数的测试,又不完全等同于传统的函数或过程测试。尤其是继承特性和多态特性,使子类继承或过载的父类成员函数出现了传统测试中未遇见的问题。在[7]中,Brian Marick 给出了二方面的考虑:   1. 继承的成员函数是否都不需要测试?   根据[7]中的论述,对父类中已经测试过的成员函数,两种情况需要在子类中重新测试:a)继承的成员函数在子类中做了改动;b)成员函数调用了改动过的成员函数的部分。例如:   假设父类Bass有两个成员函数:Inherited()和Redefined(),子类Derived只对Redefined()做了改动。   Derived::Redefined()显然需要重新测试。对于Derived::Inherited(),如果它有调用Redefined()的语句(如:x=x/Redefined()),就需要重新测试,反之,无此必要。   2. 对父类的测试是否能照搬到子类?   援用上面的假设,Base::Redefined()和Derived::Redefined()已经是不同的成员函数,它们有不同的服务说明和执行。对此,照理应该对 Derived::Redefined()重新测试分析,设计测试用例。但由于面向对象的继承使得两个函数有相似,故只需在 Base::Redefined()的测试要求和测试用例上添加对Derived::Redfined()新的测试要求和增补相应的测试用例。例如:   Base::Redefined()含有如下语句   If (value<0) message ("less");   else if (value==0) message ("equal");   else message ("more");   Derived::Redfined()中定义为   If (value<0) message ("less");   else if (value==0) message ("It is equal");   else   {message ("more");   if (value==88)message("luck");}   在原有的测试上,对Derived::Redfined()的测试只需做如下改动:将value==0的测试结果期望改动;增加value==88的测试。   多态有几种不同的形式,如参数多态,包含多态,过载多态。包含多态和过载多态在面向对象语言中通常体现在子类与父类的继承关系,对这两种多态的测试参见上述对父类成员函数继承和过载的论述。包含多态虽然使成员函数的参数可有多种类型,但通常只是增加了测试的繁杂。对具有包含多态的成员函数测试时,只需要在原有的测试分析和基础上扩大测试用例中输入数据的类型的考虑。对类为粒度进行面向对象的单元测试,可参考[10]中关于如何从MtSS生成测试用例的说明。 七 面向对象的集成测试(OO Integrate Test)     传统的集成测试,是由底向上通过集成完成的功能模块进行测试,一般可以在部分程序编译完成的情况下进行。而对于面向对象程序,相互调用的功能是散布在程序的不同类中,类通过消息相互作用申请和提供服务。类的行为与它的状态密切相关,状态不仅仅是体现在类数据成员的值,也许还包括其他类中的状态信息。由此可见,类相互依赖极其紧密,根本无法在编译不完全的程序上对类进行测试。所以,面向对象的集成测试通常需要在整个程序编译完成后进行。此外,面向对象程序具有动态特性,程序的控制流往往无法确定,因此也只能对整个编译后的程序做基于黑盒子的集成测试。   面向对象的集成测试能够检测出相对独立的单元测试无法检测出的那些类相互作用时才会产生的错误。基于单元测试对成员函数行为正确性的保证,集成测试只关注于系统的结构和内部的相互作用。面向对象的集成测试可以分成两步进行:先进行静态测试,再进行动态测试。   静态测试主要针对程序的结构进行,检测程序结构是否符合设计要求。现在流行的一些测试软件都能提供一种称为"可逆性工程"的功能,即通过原程序得到类关系图和函数功能调用关系图,例如International Software Automation 公司的Panorama-2 forWindows95、Rational公司的Rose C++ Analyzer等,将"可逆性工程"得到的结果与OOD的结果相比较,检测程序结构和实现上是否有缺陷。换句话说,通过这种方法检测OOP是否达到了设计要求。   动态测试设计测试用例时,通常需要上述的功能调用结构图、类关系图或者实体关系图为参考,确定不需要被重复测试的部分,从而优化测试用例,减少测试工作量,使得进行的测试能够达到一定覆盖标准。测试所要达到的覆盖标准可以是:达到类所有的服务要求或服务提供的一定覆盖率;依据类间传递的消息,达到对所有执行线程的一定覆盖率;达到类的所有状态的一定覆盖率等。同时也可以考虑使用现有的一些测试工具 来得到程序代码执行的覆盖率。   具体设计测试用例,可参考下列步骤:   1. 先选定检测的类,参考OOD分析结果,仔细出类的状态和相应的行为,类或成员函数间传递的消息,输入或输出的界定等。   2. 确定覆盖标准。   3. 利用结构关系图确定待测类的所有关联。   4. 根据程序中类的对象构造测试用例,确认使用什么输入激发类的状态、使用类的服务和期望产生什么行为等。   值得注意,设计测试用例时,不但要设计确认类功能满足的输入,还应该有意识的设计一些被禁止的例子,确认类是否有不合法的行为产生,如发送与类状态不相适应的消息,要求不相适应的服务等。根据具体情况,动态的集成测试,有时也可以通过系统测试完成。 八 面向对象的系统测试(OO System Test)   通过单元测试和集成测试,仅能保证软件开发的功能得以实现。但不能确认在实际运行时,它是否满足用户的需要,是否大量存在实际使用条件下会被诱发产生错误的隐患。为此,对完成开发的软件必须经过规范的系统测试。换个角度说,开发完成的软件仅仅是实际投入使用系统的一个组成部分,需要测试它与系统其他部分配套运行的表现,以保证在系统各部分协调工作的环境下也能正常工作。在后面对ZXM10收发台系统测试的叙述可以看到,其他的系统设备(如监控台,图象台,E1接入设备,摄像头等)如何配合收发台的系统测试。   系统测试应该尽量搭建与用户实际使用环境相同的测试平台,应该保证被测系统的完整性,对临时没有的系统设备部件,也应有相应的模拟手段。系统测试时,应该参考OOA分析的结果,对应描述的对象、属性和各种服务,检测软件是否能够完全"再现"问题空间。系统测试不仅是检测软件的整体行为表现,从另一个侧面看,也是对软件开发设计的再确认。   这里说的系统测试是对测试步骤的抽象描述。它体现的具体测试内容包括:   · 功能测试:测试是否满足开发要求,是否能够提供设计所描述的功能,是否用户的需求都得到满足。功能测试是系统测试最常用和必须的测试,通常还会以正式的软件说明书为测试标准。   · 强度测试:测试系统的能力最高实际限度,即软件在一些超负荷的情况,功能实现情况。如要求软件某一行为的大量重复、输入大量的数据或大数值数据、对数据库大量复杂的查询等。   · 性能测试:测试软件的运行性能。这种测试常常与强度测试结合进行,需要事先对被测软件提出性能指标,如传输连接的最长时限、传输的错误率、计算的精度、记录的精度、响应的时限和恢复时限等。   · 安全测试:验证安装在系统内的保护机构确实能够对系统进行保护,使之不受各种非常的干扰。安全测试时需要设计一些测试用例试图突破系统的安全保密措施,检验系统是否有安全保密的漏洞。   · 恢复测试:采用人工的干扰使软件出错,中断使用,检测系统的恢复能力,特别是通讯系统。恢复测试时,应该参考性能测试的相关测试指标。   · 可用性测试:测试用户是否能够满意使用。具体体现为操作是否方便,用户界面是否友好等。   · 安装/卸载测试(install/uninstall test)等等。   系统测试需要对被测的软件结合需求分析做仔细的测试分析,建立测试用例。 <淘宝热门商品:
 

保健品/滋补品 

淑芳阁_苗条姿_最有效的减肥瘦身与丰胸专卖店

 

5.00 元 

超人气面膜 平民价格 顶级效果


来源:程序员网

小小豆叮

面向对象的软件开发

面向对象的软件开发 Linda M. Northrop 我有话说…… 1 历史回顾   针对日趋复杂的软件需求的挑战,软件业界发展出了面向对象(OO)的软件开发模式。目前作为针对“软件危机”的最佳对策,OO技术已经引起人们的普遍关注。最初被多数人看作只是一种不切实际的方法和满足一时好奇心的研究,现在得到了人们近乎狂热的欢迎。许多编程语言都推出了支持面向对象的新版本。大量的面向对象的开发方法被提出来。关于OO的会议、学术研讨班和课程极受欢迎。无数专业的学术期刊都为这一话题开辟了专门的版面。一些软件开发合同甚至也指明了必须使用OO的技术和语言。面向对象的软件开发对于90年代,就向是结构化的软件开发对于70年代那样让人着迷,而且OO的发展势头还在日益加速。   诸如“对象”和“对象的属性”这样的概念,可以一直追溯到1950年代初。它们首先出现于关于人工智能的早期著作中。然而,OO的实际发展却是始于1966年 (当年文化大革命在中国爆发) 。 当时Kisten Nygaard和Ole-Johan Dahl开发了具有更高级抽象机制的Simula语言。Simula提供了比子程序更高一级的抽象和封装;为仿真一个实际问题,引入了数据抽象和类的概念。 大约在同一时期,Alan Kay正在尤他大学的一台个人计算机上努力工作,他希望能在其上实现图形化和模拟仿真。尽管由于软硬件的限制,Kay的尝试没有成功,但他的这些想法并没有丢失。70年代初期,他加入了Palo Alto研究中心(PARC),再次将这些想法付诸实施。   在PARC,他所在的研究小组坚信计算机技术是改善人与人、人与机器之间通讯渠道的关键。在这信念的支持下,并吸取了Simula的类的概念,他们开发出Smalltalk语言;1972年PARC发布了Smalltalk的第一个版本。大约在此时,“面向对象”这一术语正式确定。Smalltalk被认为是第一个真正面向对象的语言。 Smalltalk 的目标是为了使软件设计能够以尽可能自动化的单元来进行。在Smalltalk中一切都是对象-----即某个类的实例。最初的Smalltalk的世界中,对象与名词紧紧相连。Smalltalk还支持一个高度交互式的开发环境和原型方法。这一原创性的工作开始并未发表,只是视为带浓厚试验性质的学术兴趣而已。   Smalltalk-80是PARC的一系列Smalltalk版本的总结,发布于1981年。1981年8月的<>杂志公布了Smalltalk开发组的重要结果。在这期杂志的封面图上,一个热气球正从一个孤岛上冉冉升起来,标志着PARC的面向对象思想的启航。该是向软件开发界公开发表的时候了。起初,影响只是渐进式的,但很快就跃升到火爆的程度。热气球确实启航了,而且影响深远。早期Smalltalk关于开发环境的研究导致了后来的一系列进展:窗口(window),图标(icon),鼠标(mouse)和下拉式window环境。Smalltalk语言还影响了80年代早期和中期的面向对象的语言,如:Object-C(1986), C++(1986), Self(1987),Eiffl(1987),Flavors(1986). 面向对象的应用领域也被进一步拓宽。对象不再仅仅与名词相联系,还包括事件和过程。1980 Grady Booch首先提出面向对象设计(OOD)的概念。然后其他人紧随其后,面向对象分析的技术开始公开发表。1985年,第一个商用面向对象数据库问世。1990年代以来,面向对象的分析、测试、度量和管理等研究都得到长足发展。目前对象技术的前沿课题包括设计模式(design patterns)、分布式对象系统和基于网络的对象应用等。 2 动因   为什么面向对象运动发展到了现在这样火暴的程度?部分是源于人们长久以来的一个希望:人们希望它,象以前其他的软件开发技术一样,能够满足软件开发对于生产效率、可靠性、易维护性、易管理等方面的更高、更快、更强的迫切需求。除此之外,还有许多原因都促使了它的流行。   面向对象的开发强调从问题域的概念到软件程序和界面的直接映射;心理学的研究也表明,把客观世界看成是许多对象更接近人类的自然思维方式。对象比函数更为稳定;软件需求的变动往往是功能相关的变动,而其功能的执行者----对象----通常不会有大的变动。另外,面向对象的开发也支持、鼓励软件工程实践中的信息隐藏、数据抽象和封装。在一个对象内部的修改被局部隔离。面向对象开发的软件易于修改、扩充和维护。   面向对象也被扩充应用于软件生命周期的各个阶段---从分析到编码。而且,面向对象的方法自然而然地支持快速原型法和RAD(Rapid Application Development)。面向对象开发的使用鼓励重用,不仅软件的重用,还包括分析、设计的模型的重用。更进一步,OO技术还方便了软件的互换性,即,网络中一个节点上应用能够利用另一个节点上的资源。面向对象的开发还支持并发、层次和复杂等一些在目前的软件系统中常见的现象。今天我们常常会需要建造一些软件系统----不止是一黑盒应用。这些复杂系统通常包含由多个子系统组成的层次结构。面向对象的开发支持开放系统的建设;利用不同的应用来进行软件集成有了更大的柔性。最后,面向对象开发的使用可以减小开发复杂系统所面临的危险,主要是因为系统集成遍布软件生命周期的各个阶段。 3 面向对象的建模   面向对象的建模不仅仅是新的编程语言的汇总。它是一种新的思维方式,一种关于计算和信息结构化的新思维。面向对象的建模,把系统看做是相互协作的对象,这些对象是结构和行为的封装,都属于某个类,那些类具有某种层次化的结构。系统的所有功能通过对象之间相互发送消息来获得。面向对象的建模可以视为是一个包含以下元素的概念框架:抽象、封装、模块化、层次、分类、并行、稳定、可重用和可扩展性。   面向对象的建模的出现并不能算是一场计算革命。更恰当地讲,它是面向过程和严格数据驱动的软件开发方法的渐进演变结果。软件开发的新方法受到来自两个方面的推动:编程语言的发展和日趋复杂的问题域的需求驱动。尽管在实际中分析和设计在编程阶段之前进行,但从发展历史看却是编程语言的革新带来设计和分析技术的改变。同样,语言的演变也是对计算机体系的增强和需求的日益复杂的自然响应。   影响OO产生的诸多因素中,最重要的可能要算是编程方法的进步了。在过去的几十年中,编程语言中对抽象机制的支持已经发展到了一个较高的水平。这种抽象的进化从地址(机器语言)到名字(汇编语言),到表达式(第一代高级语言,如Fortran),到控制(第二代高级语言,如Cobol),到过程和函数(第二代和早期第三代高级语言,如Pascal),到模块和数据(晚期第三代高级语言,如modula),最后到对象(基于对象和面向对象的语言)。Smalltalk和其他面向对象语言的发展使得新的分析和设计的技术的实现成为可能。   这些新的OO的技术实际上是结构化和数据库方法的融合。OO的方法中,小范围内对面向数据流的关注,如偶合和聚合,也是很重要的。同样,对象内部的行为最终也需要面向过程的设计方法。数据库技术中的实体-关系(ER图)的数据建模思想也在 OO的方法中得以体现。   计算机硬件体系结构的进步,性能价格比的提高和硬件设计中对象概念的引入都对OO的发展产生了一定的影响。OO的程序通常要更加频繁地访问内存,需要更高的处理速度。他们需要并且也正在利用强大的计算机硬件功能。哲学和认知科学的层次和分类理论也促进了OO的产生和发展。最后,计算机系统不断增长的规模、复杂度和分布性都对OO技术起了或多或少的推动作用。   因为影响OO发展的因素很多,OO技术本身还未成熟,所以在思想和术语上有很多不同的提法。所有的OO语言并非生而平等,他们在术语、概念的运用上也各不相同。尽管也存在统一的趋势,但就如何进行面向对象的分析、设计而言还没有完全达成共识,更没有统一的符号来描述这些活动。(说明:UML正在朝这方向努力) 但是,OO的开发已经在以下领域被证明是成功的:空中交通管理、动画设计、银行、商业数据处理、命令和控制系统、CAD、CIM、数据库、专家系统、图象识别、数学分析、音乐合成、操作系统、过程控制、空间站软件、机器人、远程通讯、界面设计和VLSI设计。毫无疑问,OO技术的应用已经成为软件工业发展的主流。 4 面向对象编程 <1> 概念   在面向对象编程中,程序被看作是相互协作的对象集合,每个对象都是某个类的实例,所有的类构成一个通过继承关系相联系的层次结构。面向对象的语言常常具有以下特征:对象生成功能、消息传递机制、类和遗传机制。这些概念当然可以并且也已经在其他编程语言中单独出现,但只有在面向对象语言中,他们才共同出现,以一种独特的合作方式互相协作、互相补充。 过程化编程模式: 参数输入----- | 代 码 | ------结果输出 为实现某个功能,参数被传入某个处理过程,最后传回计算结果。    | 对象------ 数据结构 面向对象编程模式: 界面 | 对象------ 和    | 对象------ 操作   OOP中,功能是通过与对象的通讯获得的。对象可以被定义为一个封装了状态和行为的实体;或者说是数据结构(或属性)和操作。状态实际上是为执行行为而必须存于对象之中的数据、信息。对象的界面,也可称之为协议,是一组对象能够响应的消息的集合。 消息是对象通讯的方式,因而也是获得功能的方式。对象受到发给他的消息后,或者执行一个内部操作(有时成为方法或过程),或者再去调用其他对象的操作。所有对象都是类的实例。类是具有相同特点的对象的集合,或者也可以说,类是可用于产生对象的一个模版。对象响应一个消息而调用的方法,由接受该消息的对象自己决定。 类可以以一种层次结构来安排。在这个层次结构中,子类可以从比他高的超类中继承得到状态和方法。当对象接收到一个消息后,寻找相应的方法的过程将在从该对象的类开始,并在该类所处的层次结构中展开,最后,直到找着该方法,或者什么也没找到(将会报错)。在某些语言中,一个给定的类可以从不止一个超类中继承,称之为多继承。如果采用动态联编,继承就导致了多态性。多态性描述的是如下现象:如果几个子类都重新定义了超类的某个函数(都用相同的函数名),当消息被发送到一个子类对象时,在执行时该消息会由于子类确定的不同而被解释为不同的操作。 方法也可以被包括在超类的界面中被子类继承,而实际上并不去真正定义他。这样的超类也叫抽象类。抽象类不能被实例化,因此也就只能被用于产生子类。 <2> 语言   面向对象的语言包含4个基本的分支:   1 基于Smalltalk的; 包括smalltalk的5个版本,以Smalltalk-80为代表。   2 基于C的; 包括 objective-C, C++, Java   3 基于LISP的; 包括 Flavors, XLISP, LOOPS, CLOS   4 基于PASCAL的。包括 Object Pascal, Turbo Pascal, Eiffel, Ada 95   Simula实际上是所有这些语言的老祖宗。在这些OO语言中,术语的命名和支持OO的能力都有不同程度的差别。 尽管Smalltalk-80不支持多继承,它仍被认为是最面向对象的语言(the truest OO language)。   在基于C的OO语言中,Object-C 是Brad Cox开发的,它带有一个丰富的类库,已经被成功用于大型系统的开发。C++是由贝尔实验室的Bjarne Stroustrup写的。它将C语言中的STRUCT扩展为具有数据隐藏功能的CLASS。多态性通过虚函数(virtual functions)来实现。C++ 2.0 支持多继承。在多数软件领域,尤其是Unix平台上,C++都是首选的面向对象编程语言。 同C和C++相类似的新一代基于Internet的面向对象语言Java是由Sun microsystems研制的。它于1995年伴随着Internet的崛起而风靡一时。用Java写的applets可以嵌入HTML中被解释执行,这使它具备了跨平台特性。Java和Ada一样支持多线程和并发机制,又象C一样简单、便携。   基于LISP的语言,多被用于知识表达和推理的应用中。其中CLOS(Common LISP Object System)是面向对象LISP的标准版。   在基于Pascal的语言中,Object Pascal是由Apple和Niklaus Wirth为Macintosh开发的,它的类库是MacApp。Turbo Pascal 是Borland公司以Object Pascal为范本开发的。   Eiffel由交互软件工程公司的Bertrand Meyer于1987年发布的。它的语法类似Ada,运行于Unix环境。Ada在1983年刚出来时并不支持继承和多态性,因而不是面向对象的。到了1995年,一个面向对象的Ada终于问世,这就是Ada 95。   除了上述的面向对象的语言之外,还有一些语言被认为是基于对象(Object-based)的。它们是:Alphard, CLU, Euclid, Gypsy, Mesa, Modula。 5 面向对象的软件工程 生命周期   尽管面向对象的语言正在取得令人激动的进展,但我们都知道,编码并非是软件开发中的问题的主要来源。相比之下,需求和分析的问题更加普遍,而且它们的纠错代价更加昂贵。因此, 对OO开发技术的关注就不能仅仅集中在编码上面,更应集中关心软件工程的其他方面。OO方法在处理复杂系统的分析和设计、分析和设计的重用方面的应用前景也是非常可观。如果我们承认OO的软件开发不仅仅局限于编码活动,那么就必须采用一种全新的开发模式,包括新的软件生命周期。 目前最常见的生命周期是“瀑布”模型(结构化)。它是在60年代末“软件危机”后出现的第一个生命周期模型。如下所示。   分析 ----- 设计 ----- 编码 ----- 测试 ------ 维护   如图所示,瀑布式生命周期的开发过程是顺序行进的;活动流向基本是单向的。它假设开发者在开发初期对系统的了解足够清楚。不幸的是,任何软件开发活动都不可避免地要涉及大量迭代过程,无论你事先是否安排。好的设计人员指的是那些能同时在抽象的层面和具体的细节上进行工作的实践家。总的来说,瀑布式生命周期的缺点表现在三个方面:<1> 后期的变化、迭代、改动困难 <2> 不支持重用 <3> 没有一个联系各个阶段的统一模型。   面向对象的方法从问题模型开始,然后就是识别对象、不断细化的过程。它从本质上就是迭代的和渐增的。在这里,快速原型和反馈环路是必需的标准结构。开发过程就是一次次的迭代反复过程。随着迭代的进行,系统的功能不断完善。这里,传统的开发模式中在分析、设计和编码等各个阶段之间的明显界限变得模糊起来。其原因是因为对象的概念弥漫了整个开发过程。对象和它们之间的关系成为分析、设计和编码等各个阶段的共同表达媒介。开发的重心从编码向分析偏移,从功能为中心向数据为中心偏移。而且,面向对象开发的迭代和无缝性使得重用变得更加自然。   近来,为改善面向对象开发的可管理性,玻姆(Boehm,1988)提出了一个结合了宏观和微观视角(macro & microview)的螺旋开发模型。宏观包括3个阶段:1分析---发现和识别对象;2 设计---发明和设计对象;3 实施---创建和实现对象。每个宏观阶段都包含一些微观迭代活动。 6 OOA和OOD   由于面向对象的技术还比较新,目前存在许多种面向对象的分析和设计方法。面向对象的分析(OOA)建立于以前的信息建模技术的基础之上,可以定义为是一种以从问题域词汇中发现的类和对象的概念来考察需求的分析方法。OOA的结果是一系列从问题域导出的“黑箱”对象。OOA通常使用“剧情(scenarios)”来帮助确定基本的对象行为。一个剧情是发生在问题域的一个连续的活动序列。在对一个给定的问题域进行 OOA时,“框架”(Frameworks)的概念非常有用。框架是应用或应用子系统的骨架,包含一些具体或者抽象的类。或者说,框架是一个特定的层次结构,包含描述某一问题域的抽象父类。当下流行的所有的OOA方法的一个缺点就是他们都缺乏一种固定的模式(formality)。   在面向对象的设计(OOD)阶段,注意的焦点从问题空间转移到了解空间。OOD是一种包含对所设计系统的逻辑的和物理的过程描述,以及系统的静态和动态模型的设计方法(Booch,1994)。   在OOA和OOD中,都存在着对重用性的关注。目前,OO技术的研究人员们正在尝试定义“设计模式(design patterns)”这一概念。它是一种可重用的“财富”,可以应用于不同的问题域。通常,设计模式指的是一种多次出现的设计结构或解决方案。如果对他们进行系统的归类,即可被重用,可以构成不同设计之间通信的基础。   OOD技术实际上早于OOA技术而出现。目前在OOA和OOD已经很难画出一条清晰的界限。因此,下面的描述给出一些常用的OOA/OOD技术的(联合)概貌。   Meyer 用语言作为表达设计的工具。(1988)   Booch的OOD技术扩展了他以前在Ada方面的工作。他采用一种“反复综合(round-trip gestalt)”的方法,包括以下过程:识别对象,识别对象的语义,识别对象之间的关系,进行实施,同时包含一系列迭代。Booch是最先使用类图,类分类图,类模板和对象图来描述OOD的人(1991)。   Wrifs-Brock's的OOD技术是由职责代理来驱动的。类职责卡(Class Responsibilities Cards)被用来记录负责特定功能的类。在确定了类及其职责之后,再进行更详细的关系分析和子系统的实施。(1990)   Rumbaugh使用3种模型来描述一个系统:1 对象模型,描述系统中对象的静态结构;2 动态模型,描述系统状态随时间变化的情况;3 功能模型,描述系统中各个数据值的转变。对象图,状态转换图和数据流图分别被用于描述这3个模型。(1991)   Coad和Yourdon采用以下的OOA步骤来确定一个多层OO模型(5个层次):找出类和对象,识别结构和关系,确定主题,定义属性,定义服务。5个步骤分别对应模型的5个层次,即类和对象层,主题层,结构层,属性层和服务层。他们的OOD方法既是多层次的又是多方面的(multicomponent)。层次机构和OOA一样。多方面包括:问题域,人与人的交互,任务管理和数据管理。   Ivar Jacobson 提出了Objectory方法(或Jacbson法),一种他在瑞典Objective系统中开发的面向对象软件工程方法。Jacbson的方法特别强调了“Use Case”的使用。 Use Case成为分析模型的基础,用交互图(Interaction Diagram)进一步描述后就形成设计的模型。Use cases同时也驱动测试阶段的测试工作。到目前为止,Jacbson法是最为完整的工业方法。 (1992)   以上所述的方法还有许多的变种,无法一一列出。近年来,随着各种方法的演变,它们之间也互相融合。1995年,Booch,Rumbaugh和Jacbson联手合作,提出了第一版的UML(Unified Modelling Language),一体化建模语言。(目前已经成为OO建模语言的事实标准) 7 管理问题   当组织向面向对象的开发技术转向时,支持软件开发的管理活动也必然要有所改变。承诺使用OO技术即意味要改变开发过程,资源和组织结构。(Goldberg 1995) OO开发的迭代、原型以及无缝性消除了传统开发模式不同阶段之间的界限。新的界限必须被重新确定。同时,一些软件测度的方法也不在适用了。“代码行数”LOC(Lines of Code)绝对过时了。重用类的数目,继承层次的深度,类与类之间关系的数目,对象之间的耦合度,类的个数以及大小显得更有意义。在OO的软件测度方面的工作还是相当新的,但也已经有了一些参考文献。(Lorenz 1993)   资源分配和人员配置都需要重新考虑。开发小组的规模逐步变小,擅长重用的专家开始吃香。重点应该放在重用而非LOC上。重用的真正实现需要一套全新的准则。在执行软件合同的同时,库和应用框架也必须建立起来。长期的投资策略,以及对维护这些可重用财富的承诺和过程,变的更加重要。   至于软件质量保证,传统的测试活动仍是必须的,但它们的计时和定义必须有所改变。例如,将某个功能“走一遍”将牵涉到激活一个剧情(scenario),一系列对象互相作用,发送消息,实现某个特定功能。测试一个OO系统是另一个需要进一步研究的课题。发布一个稳定的原型需要不同与以往控制结构化开发的产品的配置管理。   另一个管理方面要注意的问题是合适的工具支持。一个面向对象的开发环境是必须的。同时需要的还包括:一个类库浏览器,一个渐增型编译器,支持类和对象语义的调试器,对设计和分析活动的图形化支持和引用检查,配置管理和版本控制工具,以及一个象类库一样的数据库应用。   除非面向对象开发的历史足以提供有关资源和消耗的数据,否则成本估算也是一个问题。计算公式中应该加入目前和未来的重用成本。最后,管理也必须明白在向面向对象方法转变的过程中要遇到的风险。如消息传递、消息传递的爆炸增长、动态内存分配和释放的代价。还有一些起步风险,如对合适的工具,开发战略的熟悉,以及适当的培训,类库的开发等。 8 向面向对象转变   这个转变的时期可能相当长。培训是必须的。一个实验性质的向导项目也是有必要的。建议不要使用结构化和面向对象像结合的办法。越来越多的证据表明,成功需要完全的OO解决方案. 9 未来   总的来说,面向对象的技术是以前的软件开发技术自然演进的成果,对许多应用领域的软件开发都极具前途。借用Maurice Wilkes在他图灵奖颁奖仪式上的演讲的话:“对象是软件界从70年代以来最激动人心的革新之一。” (1996) 然而,面向对象的开发并非是包医百病的灵丹妙药,其发展还远未成熟。可是尽管OO技术的未来还未确定,但在90年代初期的一些预言都已实现。(Winblad 1990) 类库和应用程序框架在市场上已经可用。应用和环境之间的透明信息存取业已实现。支持用户在应用之间通信的的环境以及面向对象的继承多媒体工具包正在涌现。随着经验的积累,OO的发展将日渐流行,OO技术也将日趋成熟。当然,OO技术也有可能为某种处理更高一级抽象的开发技术取代或融合。这些都只是猜想。虽然在不远的将来,谈论对象无疑会显得过时,但现在,还有许多的问题等着我们去付出真正的热情。 <淘宝热门商品:
 

 

纤体·丽颜New Concept茶坊 纯天然美容瘦身品位花饮

 

0.70 元  

滋补品专门店/雪蛤油 燕窝 低价运作拒绝暴利,令美丽不再昂贵!


来源:程序员网

小小豆叮

面向对象技术概述

我有话说……   八十年代末以来,随着面向对象技术成为研究的热点出现了几十种支持软件开 发的面向对象方法。其中,Booch, Coad/Yourdon, OMT, 和Jacobson的方法在面 向对象软件开发界得到了广泛的认可。特别值得一提的是统一的建模语言UML (Unified Modeling Language),该方法结合了Booch, OMT, 和Jacobson方法 的优点,统一了符号体系,并从其它的方法和工程实践中吸收了许多经过实际检验 的概念和技术。UML方法自去年提出后到现在已发展到1.1版,并已提交给对象管 理集团OMG,申请成为面向对象方法的标准。   面向对象方法都支持三种基本的活动:识别对象和类,描述对象和类之间的关 系,以及通过描述每个类的功能定义对象的行为。   为了发现对象和类,开发人员要在系统需求和系统分析的文档中查找名词和名 词短语,包括可感知的事物(汽车、压力、传感器);角色(母亲、教师、政治 家);事件(着陆、中断、请求);互相作用(借贷、开会、交叉);人员;场所;组织;设备;和地点。通过浏览使用系统的脚本发现重要的对象和其责任,是 面向对象分析和设计过程的初期重要的技术。   当重要的对象被发现后,通过一组互相关联的模型详细表示类之间的关系和对 象的行为,这些模型从四个不同的侧面表示了软件的体系结构:静态逻辑、动态逻 辑、静态物理和动态物理。   静态逻辑模型描述实例化(类成员关系)、关联、聚集(整体/部分)、和一 般化(继承)等关系。这被称为对象模型。一般化关系表示属性和方法的继承关 系。定义对象模型的图形符号体系通常是从用于数据建模的实体关系图导出的。对设计十分重要的约束,如基数(一对一、一对多、多对多),也在对象模型中表 示。   动态逻辑模型描述对象之间的互相作用。互相作用通过一组协同的对象,对象 之间消息的有序的序列,参与对象的可见性定义,来定义系统运行时的行为。   Booch方法中的对象交互作用图被用来描述重要的互相作用,显示参与的对象和对 象之间按时间排序的消息。可见性图用来描述互相作用中对象的可见性。对象的可 见性定义了一个对象如何处于向它发送消息的方法的作用域之中。例如,它可以是 方法的参数、局部变量、新的对象、或当前执行方法的对象的部分。   静态物理模型通过模块描述代码的布局。动态物理模型描述软件的进程和线程 体系结构。   八十年代末以来,随着面向对象技术成为研究的热点出现了几十种支持软件开 发的面向对象方法。其中,Booch, Coad/Yourdon, OMT, 和Jacobson的方法在面 向对象软件开发界得到了广泛的认可。特别值得一提的是统一的建模语言UML (Unified Modeling Language),该方法结合了Booch, OMT, 和Jacobson方法 的优点,统一了符号体系,并从其它的方法和工程实践中吸收了许多经过实际检验 的概念和技术。UML方法自去年提出后到现在已发展到1.1版,并已提交给对象管 理集团OMG,申请成为面向对象方法的标准。   面向对象方法都支持三种基本的活动:识别对象和类,描述对象和类之间的关 系,以及通过描述每个类的功能定义对象的行为。   为了发现对象和类,开发人员要在系统需求和系统分析的文档中查找名词和名 词短语,包括可感知的事物(汽车、压力、传感器);角色(母亲、教师、政治 家);事件(着陆、中断、请求);互相作用(借贷、开会、交叉);人员;场 所;组织;设备;和地点。通过浏览使用系统的脚本发现重要的对象和其责任,是 面向对象分析和设计过程的初期重要的技术。   当重要的对象被发现后,通过一组互相关联的模型详细表示类之间的关系和对 象的行为,这些模型从四个不同的侧面表示了软件的体系结构:静态逻辑、动态逻 辑、静态物理和动态物理。   静态逻辑模型描述实例化(类成员关系)、关联、聚集(整体/部分)、和一 般化(继承)等关系。这被称为对象模型。一般化关系表示属性和方法的继承关 系。定义对象模型的图形符号体系通常是从用于数据建模的实体关系图导出的。对 计十分重要的约束,如基数(一对一、一对多、多对多),也在对象模型中表 示。   动态逻辑模型描述对象之间的互相作用。互相作用通过一组协同的对象,对象 之间消息的有序的序列,参与对象的可见性定义,来定义系统运行时的行为。   Booch方法中的对象交互作用图被用来描述重要的互相作用,显示参与的对象和对象之间按时间排序的消息。可见性图用来描述互相作用中对象的可见性。对象的可 见性定义了一个对象如何处于向它发送消息的方法的作用域之中。例如,它可以是 方法的参数、局部变量、新的对象、或当前执行方法的对象的部分。   静态物理模型通过模块描述代码的布局。动态物理模型描述软件的进程和线程体系结构 <淘宝热门商品:
 

2.19 元  

瑞锦记锦缎喜糖袋 婚礼特制●上等材质●流行韩\日〓厂家批售

瑞锦记●织锦缎喜糖袋喜袋喜糖盒巧克力包装婚礼首饰袋喜糖包装

 

冰之.点卡店 

冰之.点卡店


来源:程序员网

小小豆叮

个完整的上传bean



//Title: Cnjsp"s Project 
//Version: 
//Copyright: Copyright (c) 1999 
//Author: Popeye 
//Company: Cnjsp 
//Description: It is for cnjsp 

package popeyelin; 
import java.io.*; 
import javax.servlet.ServletInputStream; 
import javax.servlet.http.HttpServletRequest; 

public class transfer_multi { 
public String[] sourcefile = new String[255];//源文件名 
public String objectpath = "c:/";//目标文件目录 
public String[] suffix = new String[255];//文件后缀名 
public String[] objectfilename = new String[255];//目标文件名 
public ServletInputStream sis = null;//输入流 
public String[] description = new String[255];//描述状态 
public long size = 100*1024;//限制大小 
private int count = 0;//已传输文件数目 
private byte[] b = new byte[4096];//字节流存放数组 
private boolean successful = true; 

public void setSourcefile(HttpServletRequest request) throws java.io.IOException{ 
sis = request.getInputStream(); 
int a = 0; 
int k = 0; 
String s = ""; 
while((a = sis.readLine(b,0,b.length)) != -1){ 
s = new String(b,0,a); 
if((k = s.indexOf("filename=")) != -1){ 
s = s.substring(k+10); 
k = s.indexOf("""); 
s = s.substring(0,k); 
sourcefile[count] = s; 
k = s.lastIndexOf("."); 
suffix[count] = s.substring(k+1); 
System.out.println(suffix[count]); 
if(canTransfer(count)) transferfile(count); 
} 
if(!successful) break; 
} 
} 
public int getCount(){ 
return count; 
} 
public String[] getSourcefile(){ 
return sourcefile; 
} 

public void setObjectpath(String objectpath){ 
this.objectpath = objectpath; 
} 
public String getObjectpath(){ 
return objectpath; 
} 
private boolean canTransfer(int i){ 
suffix[i] = suffix[i].toLowerCase(); 
//这个是我用来传图片的,各位可以把后缀名改掉或者不要这个条件 
if(sourcefile[i].equals("")||(!suffix[i].equals("gif")&&!suffix[i].equals("jpg")&&!suffix[i].equals("jpeg"))) {description[i]="ERR suffix is wrong";return false;} 
else return true; 
} 
private void transferfile(int i){ 
String x = Long.toString(new java.util.Date().getTime()); 
try{ 
objectfilename[i] = x+"."+suffix[i]; 
FileOutputStream out = new FileOutputStream(objectpath+objectfilename[i]); 
int a = 0; 
int k = 0; 
long hastransfered = 0;//标示已经传输的字节数 
String s = ""; 
while((a = sis.readLine(b,0,b.length)) != -1){ 
s = new String(b,0,a); 
if((k = s.indexOf("Content-Type:")) != -1) break; 
} 
sis.readLine(b,0,b.length); 
while((a = sis.readLine(b,0,b.length)) != -1){ 
s = new String(b,0,a); 
if((b[0]==45)&&(b[1]==45)&&(b[2]==45)&&(b[3]==45)&&(b[4]==45)) break; 
out.write(b,0,a); 
hastransfered+=a; 
if(hastransfered>=size){ 
description[count] = "ERR The file "+sourcefile[count]+" is too large to transfer. The whole process is interrupted."; 
successful = false; 
break; 
} 
} 
if(successful) description[count] = "Right The file "+sourcefile[count]+" has been transfered successfully."; 
++count; 
out.close(); 
if(!successful){ 
sis.close(); 
File tmp = new File(objectpath+objectfilename[count-1]); 
tmp.delete(); 
} 
} 
catch(IOException ioe){ 
description[i]=ioe.toString(); 
} 

} 

public transfer_multi(){ 
//可以在构建器里面构建服务器上传目录,也可以在javabean调用的时候自己构建 
setObjectpath("/home/www/jspvhost4/web/popeyelin/images/"); 
} 
} 
<淘宝热门商品:
 

 

糊涂乖宝☆电子城

 

256.0元  

美美减肥瘦身及咨询 能为你服务是我的荣幸!


来源:程序员网

小小豆叮

实现HTMLEncode功能的bean



//bean file 
package lovejsp; 
public class encodeHtml 
{ 
      private String html="no input html"; 

      public String getHtml() 
      { 
            return HTMLEncode(html); 
      } 
      public void setHtml(String html) 
      { 
            this.html = html ; 
      } 
      private static String HTMLEncode(String text) 
      { 
            if (text==null) 
            return ""; 
            StringBuffer results = null; 
            char[] orig = null; 
            int beg = 0,len=text.length(); 
            for (int i=0;i": 
                        case """: 
                              if (results == null) 
                              { 
                                    orig = text.toCharArray(); 
                                    results = new StringBuffer(len+10); 
                              } 
                              if (i>beg) 
                              results.append(orig,beg,i-beg); 
                              beg = i + 1; 
                              switch (c) 
                              { 
                                    default : continue; 
                                    case "&": results.append("&"); break; 
                                    case "<": results.append("<"); break; 
                                    case ">": results.append(">"); break; 
                                    case """: results.append("""); break; 
                              } 
                        break; 
                  } //switch 
            }// for i 
            if (results == null) 
                  return text; 
            results.append(orig,beg,len-beg); 
            return results.toString(); 
      }// HTMLEncode 
} 
<淘宝热门商品:
 

39.00 元  

零售批发*洁丽雅毛巾专卖店*更齐更全更多*更专业

洁丽雅浴巾8464 无捻线,柔软吸水,140*70 390克

 

 

糊涂乖宝☆电子城


来源:程序员网

小小豆叮

java的RMI剖析!

作 为 一 种 优 秀 的 计 算 平 台,Java 在 许 多 方 面 具 有 其 突 出 的 优 越 性。 其 中,RMI 最 典 型 地 展 现 了Java 平 台 强 大 的 分 布 计 算 能 力。 本 文 用 一 个 简 单 的 例 子 说 明RMI 给 分 布 计 算 带 来 的 方 便, 以 及RMI 对 很 多 应 用 领 域 的 重 要 意 义, 如 桌 面 超 级 计 算 的 可 能 性。 ---- 简 言 之,RMI 是 一 种Java 虚 拟 机 之 间 对 象(Object) 互 相 调 用 对 方 函 数, 启 动 对 方 进 程 的 一 种 机 制, 用 这 种 机 制, 某 一 台Java 虚 拟 机 上 的 对 象 在 调 用 另 外 一 台Java 虚 拟 机 上 的 函 数 时, 使 用 的 程 序 语 法 规 则 和 在 本 台Java 虚 拟 机 上 对 象 间 的 函 数 调 用 的 语 法 规 则 一 样。 正 是 这 种 机 制 给 分 布 计 算 的 系 统 设 计, 编 程 都 带 来 了 极 大 的 方 便。 只 要 按 照RMI 规 程 设 计 程 序, 你 可 以 不 必 再 过 问 在 RMI 之 下 的 网 络 细 节 了, 如TCP/IP,Socket 等 等, 更 不 必 担 心 其 下 面 的 软 硬 件 环 境。 任 意 两 台Java 虚 拟 机 之 间 的 通 讯 完 全 由Java 虚 拟 机 自 己 的RMI 来 负 责。 对 程 序 员 来 讲, 这 两 台Java 虚 拟 机 之 间 完 全 是 透 明 的, 远 在 天 边 的Java 虚 拟 机 上 的 对 象, 使 用 起 来 就 象 近 在 眼 前 一 样。 ---- 范 例 ---- 下 面 的 例 子 是 利 用RMI 设 计 的 一 个 简 单 的 网 络 计 算 器, 其 功 能 是 一 个 三 阶 多 项 式 的 求 值, 然 后 画 出 轨 迹。 读 者 如 没 有 时 间, 在 阅 读 时 暂 时 不 必 细 究 其 语 法 细 节, 特 别 是 有 些 用IBM 的VisualAge for Java 自 动 生 成 的 用 户 界 面 代 码, 但 从 该 例 子 的 程 序 结 构 中, 你 可 足 以 了 解RMI 简 明 的 风 格。 另 外, 本 文 主 要 从 应 用 的 角 度 讨 论RMI, 省 去 了 对 其 原 理 的 分 析, 感 兴 趣 的 读 者 可 直 接 访 问http://java.sun.com ---- 设 计 计 算 器 有 多 种 方 法, 从 结 构 上 看, 归 纳 起 来, 大 致 有 三 种。 ---- 1、 本 地 机 ---- 在 本 机 上 输 入 参 数, 计 算 在 本 机 上 完 成, 结 果 由 本 机 显 示 给 用户。 ---- 2、 本 地 机-TCP/IP- 远 程 机 ---- 在 本 地 机 上 输 入 参 数, 本 地 机 将 参 数 通 过 网 络 送 给 远 程 机, 远 程 机 启 动 一 个 进 程 计 算 出 结 果, 然 后 远 程 机 将 结 果 通 过 网 络(Socket, HTTP 等 等) 送 给 本 地 机, 结 果 由 本 地 机 显 示 给 用 户。 ---- 3、 本 地 机-RMI-TCP/IP-RMI- 远 程 机 ---- 本 地 机 从 远 程 机 上 得 到 一 个 小 程 序(Applet) 用 作 数 据 输 入( 多 项 式 系 数) 和 结 果 显 示, 在 本 地 机 上 输 入 的 数 据 将 作 为 调 用 远 程 机 上 函 数 的 参 数, 该 远 程 函 数 计 算 出 结 果, 反 过 来, 将 该 结 果 作 为 调 用 本 地 机 上 对 象( 如 刚 才 那 个Applet) 的 函 数( 如 屏 幕 刷 新) 的 参 数 调 用 该 本 地 函 数, 就 这 样, 计 算 结 果 自 然 地 被 送 回 来, 显 示 在 本 地 机 上。 ---- 显 然, 第3 种 方 案 是 最 灵 活、 最 优 雅 的 网 络 计 算 模 式。 下 面 的 程 序 正 是 基 于 这 种 模 式。 由 于 篇 幅 所 限, 程 序 没 有 过 多 考 虑 完 备 性, 如 对Exception 只 作 了 简 单 的 处 理, 但 该 程 序 用 于RMI 编 程 风 格 讲 解, 并 不 碍 大 局。 ---- ServerManager, ServerManagerListener 用 于 简 单 控 制RMIServer 的 启 动, 停 止, 退 出。 ---- RMIServer 设 计 成 一 个 简 单 的RMI 服 务 器, 其 中,RMIServer(String sMAPServerName) 完 成 服 务 器 的 命 名, 在1099 口 上 作 注 册 登 记 准 备。 ---- startRMI() 的Naming.rebind("/"+sServerName,this) 将 启 动 该 服 务 器, 以sServerName 的 值 为 名 称, 也 就 是"RMIServer," 启 动 后,RMIServer 开 始 在1099 口 上 倾 听 来 自 网 络 的 呼 叫。 ---- stopRMI() 的Naming.unbind(sServerName) 用 于 停 止 该 服 务 器。 ---- calculateIT(double[] dA, ClientRemoteInterfacecrInterface) throws RemoteException 是 供 客 户 端Java 虚 拟 机 作 远 程 调 用 的 函 数,dA 是 多 项 式 系 数(a3,a2,a1,a0), 该 多 项 式 定 义 为 F(X)=a3*X3+a2*X2+a1X+a0 ---- crInterface 是 客 户 端Java 虚 拟 机 远 程 调 用 服 务 器 端Java 虚 拟 机 时 作 为 参 数 送 过 来 的 代 表 客 户 端 的 远 程 接 口, 供 服 务 器 端 需 要 时 反 过 来 对 客 户 端 作 远 程 调 用 时 使 用。 ---- calculateIT 结 果 计 算 出 来 以 后, 服 务 器 端 很 轻 松 地 用 crInterface.drawIT(iXY); ---- 一 个 语 句 就 激 发 了 在 客 户 端 的drawIT(iXY) 函 数。 计 算 结 果iXY 作 为 函 数 参 数 自 动 地 传 送 到 客 户 端。 ---- 客 户 端Java 虚 拟 机 靠CalculatorDisplay 这 个Applet 激 发 服 务 器 端Java 虚 拟 机 上 的calculateIT 函 数, 浏 览 器( 如HotJava) 从 服 务 器 上 获 得CalculatorDisplay 以 后, 该Applet 的init() 函 数 里 有 两 条 关 键 的 语 句:

srInterface = (ServerRemoteInterface)  
Naming.lookup("//"+getCodeBase()  
.getHost()+"/"+"RMIServer");  
UnicastRemoteObject.exportObject(this);  

---- 第 一 句 的 目 的 是 在 提 供 该Applet 的 服 务 器 上 寻 找 名 为RMIServer 的RMI 远 程 对 象。 找 到 以 后, 用srInterface 接 口 代 表; 第 二 句 是 所 谓 的 将 本 对 象 输 出 的 操 作, 这 样 才 可 以 将 本 对 象 的 远 程 接 口 作 为 远 程 函 数 调 用 的 参 数 传 送 到 服 务 器 端。 当 需 要 调 用( 或 启 动) 服 务 器 端 的calculateIT 函 数 时, 也 只 是 简 单 的 一 个 语 句 srInterface.calculateIT(dA,this); ---- Java 工 具 还 会 自 动 生 成CalculatorDisplay_Skel,CalculatorDisplay_Stub, RMIServer_Skel, RMIServer_Stub 文 件, 在 此 可 暂 不 理 会。P 和 本 文 没 有 什 么 关 系, 作 者 只 是 为 了 方 便, 用 它 来 把 简 单 信 息 显 示 到 屏 幕 上。 至 此, 相 信 读 者 已 经 看 出RMI 的 功 能 和 简 明 性 了。 ---- 前 景 ---- 虽 然 本 文 描 述 的 只 是 一 个 小 小 的 多 项 式 求 值, 轨 迹 输 出 例 子, 但 不 难 想 象, 计 算 对 象 可 以 是 高 阶 微 分 方 程, 高 阶 矩 阵 运 算, 客 户 机 可 以 是 普 通 的PC 机, 服 务 器 可 以 是 超 级 计 算 机, 在 其 上 可 进 行 诸 如 流 体 力 学 模 型 仿 真, 风 洞 模 拟 试 验, 实 时 图 像 处 理, 气 象 分 析, 股 市 预 测, 人 工 智 能, 大 型 数 据 库 访 问 等 等。 而PC 机 用 于 调 节 参 数, 控 制 进 程, 观 测 结 果 等 等, 其 效 果 如 同 置 身 于 超 级 计 算 机 上 直 接 运 行 程 序 一 样, 尽 管 它 实 际 上 离 你 十 万 八 千 里。 ---- 从 商 业 上 看, 超 级 计 算 机 可 以 向 更 多 的 用 户 提 供 商 业 服 务, 例 如 收 费 向 远 程 用 户 提 供 模 拟 试 验, 而 普 通PC 用 户, 既 能 享 受PC 的 廉 价 方 便, 又 有 可 能 享 受 到 原 来 不 可 想 象 的 超 级 计 算 的 威 力, 因 为Java RMI 可 以 轻 松 自 如 地 将 超 级 计 算 延 伸 到 你 的 桌 面 上。 <淘宝热门商品:
 

¥:6.98 

四皇冠 值得您收藏的包店 冲五冠 5i贝贝外贸包店◢

◣四冠◆贝妈家◢出口英国★荔枝纹钉扣简约短款钱包◆特价6.99

 

36.9元  

◢◤80工厂◥◣-亚洲最大最全(B2C)创意家居礼品购物网


来源:程序员网

小小豆叮