成人91视频,日本视频一区二区三区,麻豆导航在线观看http://www.aygfsteel.com/hilor/category/25382.html我的學(xué)習(xí)檔案館zh-cnWed, 02 Jan 2008 23:39:51 GMTWed, 02 Jan 2008 23:39:51 GMT60FCKeditor(JAVA版)配置詳解http://www.aygfsteel.com/hilor/archive/2008/01/02/172190.htmlhilorhilorWed, 02 Jan 2008 06:29:00 GMThttp://www.aygfsteel.com/hilor/archive/2008/01/02/172190.htmlhttp://www.aygfsteel.com/hilor/comments/172190.htmlhttp://www.aygfsteel.com/hilor/archive/2008/01/02/172190.html#Feedback0http://www.aygfsteel.com/hilor/comments/commentRss/172190.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/172190.html 1. 下載最新版的FCKeditor
        http://www.fckeditor.net/download/
        目前最新版是:FCKeditor_2.3.2(我用的是2.3.1)和 FCKeditor.Java
(FCKeditor-2.3)
2. 簡介
        解壓FCKeditor 2.3.1.zip后得到如下目錄結(jié)構(gòu):
FCKeditor_2.3.1
---editor
    ---_source (有的資料說要?jiǎng)h除此文件夾,刪除將會(huì)出現(xiàn)很多初始化js錯(cuò)誤)
    ---css(樣式)
    ---dialog(editor所有的網(wǎng)頁對話框都在這里了)
    ---filemanager(文件上傳管理部分)
        ---browser(存放用于瀏覽選擇上傳到服務(wù)器的文件,創(chuàng)建文件夾的瀏覽器)
        ---defult
             ---connectors(asp、php 、aspx等實(shí)現(xiàn)文件瀏覽、創(chuàng)建文件夾的文件。java項(xiàng)目中用 connectorservlet.Java實(shí)現(xiàn),所以可以刪除下面所有文件)
        ---upload(asp、php、aspx等實(shí)現(xiàn)文件上傳時(shí)的文件,java項(xiàng)目中用 servlet實(shí)現(xiàn)上傳,所以可以刪除下面所有文件)
    ---images(editor使用到的圖片)
    ---js
    ---lang (存放用于支持多語言的js文件)
    ---plugins(擴(kuò)展插件)
    ---skins(editor皮膚,2.3.1版有default、office 2003和silvers三種)
fckconfig.js
fckeditor.js
fckstyles.xml
fcktemplates.xml
….其余文件刪掉即可
解壓FCKeditor 2.3.zip后得到如下目錄結(jié)構(gòu):
FCKeditor_2.3
---docs
    ---api(api文檔,介紹了類的功能和配置方法)
---src(java源文件)
---web
    ---_samples
    ---web-inf
         ---lib(存放FCKeditor-2.3.jar 和Apache文件上傳開源項(xiàng)目commons-fileupload.jar)
        Web.xml
Build.xml
Readme.txt

3. demo
我的開發(fā)環(huán)境是eclipse3.1和Myeclipse4.1,jdk1.5,resin-pro-3.0.18
    3.1 建立一個(gè)webproject,命名為FCKeditor
    3.2 將FCKeditor_2.3.1下的editor文件夾和fckeditor.js,fckconfig.js,fckstyles.xml,fcktemplates.xml拷貝到FCKeditor/webroot下。
    3.3 FCKeditor.java 2.3解壓后,把其中的web目錄下的WEB-INF目錄copy到FCKeditor/webroot下(里面有commons-fileupload.jar, FCKeditor-2.3.jar,web.xml等幾個(gè)文件), 再把其中的src目錄下的FCKeditor.tld文件copy到FCKeditor/webroot/WEB-INF/下,_samples文件夾拷貝到FCKeditor/webroot/下。
    3.4 修改web.xml和FCKeditor/webroot/editor/fckconfig.js:
<web-app>
        <display-name>FCKeditor Test Application</display-name>

        <servlet>
                <servlet-name>Connector</servlet-name>
                <servlet-class>com.fredck.FCKeditor.connector.ConnectorServlet</servlet-class>
                <init-param>
                        <param-name>baseDir</param-name>
將在FCKeditor/editor/下創(chuàng)建Image和Flash文件夾,用于存放上傳文件
                        <param-value>/editor/</param-value>
                </init-param>
                <init-param>
                        <param-name>debug</param-name>
                        <param-value>false</param-value>調(diào)試時(shí)設(shè)為true
                </init-param>
                <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet>
                <servlet-name>SimpleUploader</servlet-name>
                <servlet-class>com.fredck.FCKeditor.uploader.SimpleUploaderServlet</servlet-class>
                <init-param>
                 <param-name>baseDir</param-name>
將在FCKeditor/editor/下創(chuàng)建Image和Flash文件夾,用于存放上傳文件
                        <param-value>/editor/</param-value>
                </init-param>
                <init-param>
                        <param-name>debug</param-name>
                        <param-value>true</param-value>調(diào)試時(shí)設(shè)為true
                </init-param>
                <init-param>
                        <param-name>enabled</param-name>
                        <param-value>true</param-value>修改成true
                </init-param>
                <init-param>
                        <param-name>AllowedExtensionsFile</param-name>
                        <param-value></param-value>
                </init-param>
                <init-param>
                        <param-name>DeniedExtensionsFile</param-name>
                        <param-value>php|php3|php5|phtml|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|dll|reg|cgi</param-value>
                </init-param>
                <init-param>
                        <param-name>AllowedExtensionsImage</param-name>
                        <param-value>jpg|gif|jpeg|png|bmp</param-value>
                </init-param>
                <init-param>
                        <param-name>DeniedExtensionsImage</param-name>
                        <param-value></param-value>
                </init-param>
                <init-param>
                        <param-name>AllowedExtensionsFlash</param-name>
                        <param-value>swf|fla</param-value>
                </init-param>
                <init-param>
                        <param-name>DeniedExtensionsFlash</param-name>
                        <param-value></param-value>
                </init-param>
                <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet-mapping>
                <servlet-name>Connector</servlet-name>
和fckconfig.js的ImageBrowserURL等對應(yīng)
                <url-pattern>/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>
        </servlet-mapping>

        <servlet-mapping>
                <servlet-name>SimpleUploader</servlet-name>
這里你可以按自己應(yīng)用具體配置,需要和fckconfig.js的ImageUploadUrl等對應(yīng)
                <url-pattern>/editor/upload.do</url-pattern>
        </servlet-mapping>

        
        <welcome-file-list>配置歡迎文件
                <welcome-file>_samples/index.jsp</welcome-file>
        </welcome-file-list>
        
        <taglib>
                <taglib-uri>/etag</taglib-uri>配置FCKeditor自定義標(biāo)簽
                <taglib-location>/web-inf/FCKeditor.tld</taglib-location>
        </taglib>

</web-app>
  

        修改 fckconfig.js中:
FCKConfig.DefaultLanguage = 'zh-cn' ; 修改默認(rèn)語言為簡體中文

    把FCKConfig.LinkBrowserURL等的值替換成以下內(nèi)容:

FCKConfig.LinkBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Connector=connectors/" + _FileBrowserLanguage + "/connector"

FCKConfig.ImageBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Image&Connector=connectors/" + _FileBrowserLanguage + "/connector";

FCKConfig.FlashBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/" + _FileBrowserLanguage + "/connector";

FCKConfig.LinkUploadURL = FCKConfig.BasePath + "filemanager/upload/" + _QuickUploadLanguage + "/connector?Type=File";

FCKConfig.ImageUploadURL=FCKConfig.BasePath + "upload.do?Type=Image";

FCKConfig.FlashUploadURL=FCKConfig.BasePath+ "upload.do?Type=Flash";
Connector參數(shù)的值完全可以修改,只要和web.xml中配置一致即可 

    3.5    有的例子說必須在FCKeditor/webroot/editor/下手工新建Image和Flash兩個(gè)文件夾,F(xiàn)CKeditor不會(huì)自己創(chuàng)建文件上傳的文件夾,否則無法上傳文件,將提示無權(quán)操作,在java應(yīng)用下無需自己創(chuàng)建,ConnectorServlet會(huì)在你第一次執(zhí)行文件瀏覽時(shí),根據(jù)url的type參數(shù),判斷baseDir下是否存在以type值為名字的文件夾,不存在就創(chuàng)建它。

3.6  FCKConfig.TabSpaces = 0 ; 改為FCKConfig.TabSpaces = 1 ; 即在編輯器域內(nèi)可以使用Tab鍵。
        找到: FCKConfig.FontNames = 'Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;
      加上幾種我們常用的字體
      FCKConfig.FontNames
      = '宋體;黑體;隸書;楷體_GB2312;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana' ;



hilor 2008-01-02 14:29 發(fā)表評(píng)論
]]>
引入外部JS發(fā)生錯(cuò)語的解決方法http://www.aygfsteel.com/hilor/archive/2008/01/02/172137.htmlhilorhilorWed, 02 Jan 2008 04:18:00 GMThttp://www.aygfsteel.com/hilor/archive/2008/01/02/172137.htmlhttp://www.aygfsteel.com/hilor/comments/172137.htmlhttp://www.aygfsteel.com/hilor/archive/2008/01/02/172137.html#Feedback0http://www.aygfsteel.com/hilor/comments/commentRss/172137.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/172137.html今天碰到一個(gè)問題, 引入外部JS文件發(fā)生錯(cuò)誤...   經(jīng)過DBUG, 發(fā)現(xiàn)原來又是編碼問題,  JS文件里出現(xiàn)中文, 就要注意編碼了..  把JS存為UTF-8, 然后導(dǎo)入時(shí)設(shè)置charset=UTF-8
<script language="javascript" type="text/javascript" src="/test/test.js" charset="UTF-8"></script>



hilor 2008-01-02 12:18 發(fā)表評(píng)論
]]>
apache2.X版與Tomcat5.X整合http://www.aygfsteel.com/hilor/archive/2007/11/01/157496.htmlhilorhilorThu, 01 Nov 2007 07:05:00 GMThttp://www.aygfsteel.com/hilor/archive/2007/11/01/157496.htmlhttp://www.aygfsteel.com/hilor/comments/157496.htmlhttp://www.aygfsteel.com/hilor/archive/2007/11/01/157496.html#Feedback1http://www.aygfsteel.com/hilor/comments/commentRss/157496.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/157496.html 下面來簡述一下,我配置的過程,準(zhǔn)備工作如下:
 關(guān)于apache2.X版與Tomcat5.X整合的技術(shù)文檔,在網(wǎng)上找了兩天,大部分都是指定使用apache2.08+tomcat5.0.16+mod_jk2.dll什么的,我用其它版本的怎樣試也不行,無奈之余,就又到網(wǎng)上四處找tomcat5.0.16版,TOMCAT官方網(wǎng)站沒有下載了,其實(shí)我是步入了一個(gè)誤區(qū),其實(shí)盡信書則不如無書,TOMCAT無論用哪個(gè)版本,高版本大部分都兼容低版本的功能.希望各位以后網(wǎng)上資料參考就好了,最主要是看開源的幫助文檔才最重要,不過是E文的,慢慢看吧,帶個(gè)金山詞霸.^_^ 閑話少說,言歸正傳,下面介紹我的配置步驟吧!
 
前提準(zhǔn)備工作及配置環(huán)境如下:
操作系統(tǒng)是,WINDOWS2K SERVICE版
jdk1.5(其實(shí)什么版本也無所謂了,1.4以上都行)
TOMCAT5.0.19.exe文件,在TOMCAT官方網(wǎng)也沒有下載了,我以前下載的,要的話,可以發(fā)郵件給我,(5.0版本都無所謂了)
apache_2.0.49-win32-x86-no_ssl.msi apache服務(wù)器(這個(gè)apache版本,因apache我不太熟,限不限定版本號(hào),沒有測試過)
下載網(wǎng)址:http://archive.apache.org/dist/httpd/binaries/win32/
jakarta-tomcat-connectors-jk2.0.4-win32-apache2.0.49.zip(TOMCAT5與APACHE2 plus)//這個(gè)中間件在apache官方網(wǎng)有下載
下載網(wǎng)址:http://archive.apache.org/dist/tomcat/tomcat-connectors/jk2/binaries/win32/
1.    安裝并測試Apache和TomCat5.0;
注意事項(xiàng): Apache默認(rèn)端口為80,與IIS沖突,更改端口或關(guān)閉IIS,
TomCat安裝完后配置環(huán)境變量。
2.    開始整合;
首先,先把jakarta-tomcat-connectors-jk2.0.4-win32-apache2.0.49.zip解壓后,從modules目錄中取出來mod_jk2.so文件,復(fù)制到,apache安裝根目錄/apache2/modules/目錄下.
其次,編輯配置文件。具體的配置文件有四個(gè),
它們分別是:httpd.conf、jk2.properties、server.xml、workers2.properties。

我的配置如下:

a、 修改ApacheRoot\Apache2\conf\httpd.conf 文件
1>修改web 主目錄,即將
DocumentRoot "D:/websrv/Apache2/htdocs" 改為自己的web主目錄
eg:     DocumentRoot    "D:/test/jsptest"
2>修改web 主目錄對應(yīng)的目錄,即將
<Directory "D:/websrv/Apache2/htdocs">改為
eg:     <Directory "D:/test/jsptest" >
此目錄塊要與DocumentRoot的路徑對應(yīng),塊中的語法是對此塊對應(yīng)Web主目錄的操作權(quán)限設(shè)置。
3>修改目錄缺省的web文件,即將
DirectoryIndex index.html index.html.var 改為
eg:      DirectoryIndex index.html index.html.var index.jsp
語法說明:當(dāng)向Apache 發(fā)出請求時(shí)容器將順次去找index.html,如果沒有,將接著找index.htm,最后找index.jsp。
4>修改cgi-bin 所在目錄,即將
ScriptAlias /cgi-bin/ "D:/websrv/Apache2/cgi-bin/"改為
ScriptAlias /cgi-bin/ "D:/test/jsptest/cgi-bin/"
<Directory "D:/websrv/Apache2/cgi-bin"> 改為
<Directory "D:/test/jsptest/cgi-bin">
如果程序中需要用到cgi時(shí)修改以上兩處。
5>添加指定的虛擬目錄(別名),及其對應(yīng)目錄的屬性
#這是測試用的文件夾,能執(zhí)行jsp 文件。
Alias  /jmmis/           "D:/test/jsptest/jmmis/"
<Directory       "D:/test/jsptest/jmmis" >
AllowOverride None
Options IncludesNoExec
AddOutputFilter Includes html
AddHandler type-map var
Order allow,deny
Allow from all
</Directory>
    
#在web主目錄jsptest中添加了jmmis目錄
語法說明:
 
      Alias  /web程序別名/     "程序根目錄/"                            ##別忘啦最后有“/”
      <Directory              "程序根目錄" >
        AllowOverride None
        Options IncludesNoExec
        AddOutputFilter Includes html                           對此程序的具體操作權(quán)限設(shè)置   
        AddHandler type-map var                                  
        Order allow,deny
       Allow from all
</Directory>
注意:
                   程序根目錄必須和%Tomcat5%\conf\server.xml中配置的虛擬目錄相吻合。
           6>添加默認(rèn)字符集的設(shè)置
  AddDefaultCharset GB2312
            7>在文件最后添加如下內(nèi)容,以加載jk2 模塊
   
<IfModule !mod_jk2.c>
LoadModule jk2_module modules/mod_jk2.so
</IfModule>
以上都是配置httpd.conf Apache服務(wù)器的東西!

接下來配JK2了
JK2指定一個(gè)worker2.properties文件
存放路徑為就是SERVERROOT/conf
這里的serverroot 是apache的安裝目錄
原JK2幫助文檔顯示如下所示
workers2.properties is used on the webserver side. For the Apache servers the default path is in the ServerRoot/conf directory.
worker2.properties文件如下:

[shm]
info=Scoreboard. Requried for reconfiguration and status with multiprocess servers.
file=anon
# Defines a load balancer named lb. Use even if you only have one machine.
[lb:lb]
# Example socket channel, override port and host.
[channel.socket:localhost:8019]
port=8019
host=127.0.0.1
# define the worker
[ajp13:localhost:8019]
channel=channel.socket:localhost:8019
group=lb
# Map the Tomcat examples webapp to the Web server uri space
[uri:/*.jsp]
group=lb
[uri:/Servlet/*]
group=lb
[status:]
info=Status worker, displays runtime information
[uri:/jkstatus/*]
info=The Tomcat /jkstatus handler
group=status:
接著修改JK2.properties文件,默認(rèn)不用作什么修改,
TOMCAT5/conf的jk2.properties文件不需太多修改,
 jk2的屬性文件如下
 ## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED
## WHEN YOU EDIT THE FILE.
## COMMENTS WILL BE _LOST_
## DOCUMENTATION OF THE FORMAT IN JkMain javadoc.
 #Set the desired handler list
 handler.list=apr,request,channelJni
#
# Override the default port for the socketChannel
 channelSocket.port=8019
# Default:
# channelUnix.file=${jkHome}/work/jk2.socket
# Just to check if the the config  is working
# shm.file=${jkHome}/work/jk2.shm
# In order to enable jni use any channelJni directive
# channelJni.disabled = 0
# And one of the following directives:
#apr.NativeSo=/home1/jakarta/jakarta-tomcat-connectors/jk/build/jk2/apache2/jkjni.so
 apr.jniModeSo=/ApacheRoot/apache2/modules/mod_jk2.so
#apr.jniModeSo=C:/Apache/Apache2/modules/mod_jk2.so
# If set to inprocess the mod_jk2 will Register natives itself
# This will enable the starting of the Tomcat from mod_jk2
 apr.jniModeSo=inprocess
#Shared memory directive
shm.file=C:/Apache/Apache2/logs/jk2.shm
修改TOMCAT下/conf目錄下的server.xml文件

保持通信管道端口號(hào)一致
與worker2.properties文件中,
# define the worker
[ajp13:localhost:8019]
channel=channel.socket:localhost:8019
所定義的8019一致
<Connector port="8019"
               enableLookups="true" redirectPort="8443" debug="0"
               protocol="AJP/1.3" />
同時(shí)在</host>位置增加虛擬目錄
 <Context path="/jmmis" docBase="D:/test/jsptest/jmmis" debug="0" reloadable="true"
crossContext="true"></Context>
這里也許會(huì)報(bào)警告信息,修改 TOMCAT/CONF/下的server-minimal.xml的文件,把默認(rèn)的8009修改為8019
以上修改完成后,重啟APACHE TOMCAT就大功告成了!


hilor 2007-11-01 15:05 發(fā)表評(píng)論
]]>
DES加密解密算法http://www.aygfsteel.com/hilor/archive/2007/10/30/156986.htmlhilorhilorTue, 30 Oct 2007 09:09:00 GMThttp://www.aygfsteel.com/hilor/archive/2007/10/30/156986.htmlhttp://www.aygfsteel.com/hilor/comments/156986.htmlhttp://www.aygfsteel.com/hilor/archive/2007/10/30/156986.html#Feedback0http://www.aygfsteel.com/hilor/comments/commentRss/156986.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/156986.htmlimport java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;

/**
 * @author aujlure
 * 加密解密
 */
public class DESPlus {
 private static String strDefaultKey = "hilor"; //默認(rèn)密鑰

 private Cipher encryptCipher = null;

 private Cipher decryptCipher = null;

 /**
  * 將byte數(shù)組轉(zhuǎn)換為表示16進(jìn)制值的字符串, 如:byte[]{8,18}轉(zhuǎn)換為:0813, 和public static byte[]
  * hexStr2ByteArr(String strIn) 互為可逆的轉(zhuǎn)換過程
  *
  * @param arrB
  *            需要轉(zhuǎn)換的byte數(shù)組
  * @return 轉(zhuǎn)換后的字符串
  * @throws Exception
  *             本方法不處理任何異常,所有異常全部拋出
  */
 public static String byteArr2HexStr(byte[] arrB) throws Exception {
  int iLen = arrB.length;
  // 每個(gè)byte用兩個(gè)字符才能表示,所以字符串的長度是數(shù)組長度的兩倍
  StringBuffer sb = new StringBuffer(iLen * 2);
  for (int i = 0; i < iLen; i++) {
   int intTmp = arrB[i];
   // 把負(fù)數(shù)轉(zhuǎn)換為正數(shù)
   while (intTmp < 0) {
    intTmp = intTmp + 256;
   }
   // 小于0F的數(shù)需要在前面補(bǔ)0
   if (intTmp < 16) {
    sb.append("0");
   }
   sb.append(Integer.toString(intTmp, 16));
  }
  return sb.toString();
 }

 /**
  * 將表示16進(jìn)制值的字符串轉(zhuǎn)換為byte數(shù)組, 和public static String byteArr2HexStr(byte[] arrB)
  * 互為可逆的轉(zhuǎn)換過程
  *
  * @param strIn
  *            需要轉(zhuǎn)換的字符串
  * @return 轉(zhuǎn)換后的byte數(shù)組
  * @throws Exception
  *             本方法不處理任何異常,所有異常全部拋出
  * @author <a href="mailto:leo841001@163.com">LiGuoQing</a>
  */
 public static byte[] hexStr2ByteArr(String strIn) throws Exception {
  byte[] arrB = strIn.getBytes();
  int iLen = arrB.length;

  // 兩個(gè)字符表示一個(gè)字節(jié),所以字節(jié)數(shù)組長度是字符串長度除以2
  byte[] arrOut = new byte[iLen / 2];
  for (int i = 0; i < iLen; i = i + 2) {
   String strTmp = new String(arrB, i, 2);
   arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
  }
  return arrOut;
 }

 /**
  * 默認(rèn)構(gòu)造方法,使用默認(rèn)密鑰
  *
  * @throws Exception
  */
 public DESPlus() throws Exception {
  this(strDefaultKey);
 }

 /**
  * 指定密鑰構(gòu)造方法
  *
  * @param strKey
  *            指定的密鑰
  * @throws Exception
  */
 public DESPlus(String strKey) throws Exception {
  Security.addProvider(new com.sun.crypto.provider.SunJCE());
  Key key = getKey(strKey.getBytes());

  encryptCipher = Cipher.getInstance("DES");
  encryptCipher.init(Cipher.ENCRYPT_MODE, key);

  decryptCipher = Cipher.getInstance("DES");
  decryptCipher.init(Cipher.DECRYPT_MODE, key);
 }

 /**
  * 加密字節(jié)數(shù)組
  *
  * @param arrB
  *            需加密的字節(jié)數(shù)組
  * @return 加密后的字節(jié)數(shù)組
  * @throws Exception
  */
 public byte[] encrypt(byte[] arrB) throws Exception {
  return encryptCipher.doFinal(arrB);
 }

 /**
  * 加密字符串
  *
  * @param strIn
  *            需加密的字符串
  * @return 加密后的字符串
  * @throws Exception
  */
 public String encrypt(String strIn) throws Exception {
  return byteArr2HexStr(encrypt(strIn.getBytes()));
 }

 /**
  * 解密字節(jié)數(shù)組
  *
  * @param arrB
  *            需解密的字節(jié)數(shù)組
  * @return 解密后的字節(jié)數(shù)組
  * @throws Exception
  */
 public byte[] decrypt(byte[] arrB) throws Exception {
  return decryptCipher.doFinal(arrB);
 }

 /**
  * 解密字符串
  *
  * @param strIn
  *            需解密的字符串
  * @return 解密后的字符串
  * @throws Exception
  */
 public String decrypt(String strIn) throws Exception {
  return new String(decrypt(hexStr2ByteArr(strIn)));
 }

 /**
  * 從指定字符串生成密鑰,密鑰所需的字節(jié)數(shù)組長度為8位 不足8位時(shí)后面補(bǔ)0,超出8位只取前8位
  *
  * @param arrBTmp
  *            構(gòu)成該字符串的字節(jié)數(shù)組
  * @return 生成的密鑰
  * @throws java.lang.Exception
  */
 private Key getKey(byte[] arrBTmp) throws Exception {
  // 創(chuàng)建一個(gè)空的8位字節(jié)數(shù)組(默認(rèn)值為0)
  byte[] arrB = new byte[8];

  // 將原始字節(jié)數(shù)組轉(zhuǎn)換為8位
  for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
   arrB[i] = arrBTmp[i];
  }

  // 生成密鑰
  Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");

  return key;
 }

 public static void main(String[] args) {

  String test = "username";
  // DESPlus des = new DESPlus();//默認(rèn)密鑰
  DESPlus des;
  try {
   des = new DESPlus();
   // 自定義密鑰
   System.out.println("加密前的字符:" + test);
   System.out.println("加密后的字符:" + des.encrypt(test));
   System.out.println("解密后的字符:" + des.decrypt(des.encrypt(test)));
  } catch (Exception e) {
   e.printStackTrace();
  }

 }
}



hilor 2007-10-30 17:09 發(fā)表評(píng)論
]]>
ANT使用http://www.aygfsteel.com/hilor/archive/2007/10/23/155238.htmlhilorhilorTue, 23 Oct 2007 04:14:00 GMThttp://www.aygfsteel.com/hilor/archive/2007/10/23/155238.htmlhttp://www.aygfsteel.com/hilor/comments/155238.htmlhttp://www.aygfsteel.com/hilor/archive/2007/10/23/155238.html#Feedback0http://www.aygfsteel.com/hilor/comments/commentRss/155238.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/155238.html

  ant是jakarta一個(gè)非常好的OpenSource子項(xiàng)目,是基于java的編譯工具。下面簡單介紹一下在linux環(huán)境中如何安裝ant:

  1.下載
  從 http://ant.apache.org/bindownload.cgi
可以下載最新的tar包:apache-ant-1.6.2.tar.gz,如果是windows環(huán)境則是zip文件,解壓后,在系統(tǒng)環(huán)境變量里設(shè)置
ANT_HOME為f:\project\tools\apache-ant-1.6.2,并將f:\project\tools\apache-ant
-1.6.2\bin目錄添加到classpath中,然后就可以使用了

  2.安裝,解壓到/usr/local下
> tar zxpvf apache-ant-1.6.2.tar.gz
> ln -s apache-ant-1.6.2 ant

  3.設(shè)置環(huán)境
  將ANT_HOME設(shè)置到當(dāng)前用戶的.bash_profile文件/home/admin/.bash_profile

[admin@tangtang home]$ su - admin
[admin@tangtang home]$ vi .bash_profile
export ANT_HOME=/usr/local/ant
export PATH=/usr/local/ant/bin:$PATH

  如果是windows環(huán)境,需要設(shè)置%ANT_HOME%,并把%ANT_HOME%\bin目錄全路徑加入到%path%中

  4.測試
  用ant命令測試運(yùn)行情況
[admin@tangtang home]$ ant
Buildfile: build.xml does not exist!
Build failed

[admin@tangtang home]$ ant -version
Apache Ant version 1.6.2 compiled on July 16 2004

  若出現(xiàn)這樣的錯(cuò)誤:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/tools/ant/launch/Launcher
  這是linux系統(tǒng)默認(rèn)安裝了一些ant的lib,修改 /etc/ant.conf中 ANT_HOME=/usr/share/ant 為你正確安裝ant的地址,如 /usr/local/ant

  5、build腳本
  如果是在linux環(huán)境中,下面是build腳本的一個(gè)范例:

#build腳本
#! /bin/sh
# 進(jìn)入到上級(jí)目錄
cd `dirname $0`/..
# 獲取當(dāng)前目錄為PROJECT_HOME
PROJECT_HOME=`pwd`
# 設(shè)置JAVA_HOME
export JAVA_HOME=/usr/cyber/java
# 得到CLASSPATH
CLASSPATH1=$CLASSPATH
# 添加CLASSPATH
CLASSPATH=${PROJECT_HOME}\webapps\WEB-INF\conf:${PROJECT_HOME}\webapps\WEB-INF\classes:$CLASSPATH
# ant build,-buildfile 參數(shù),是使用自定義的build.xml文件,$@是參數(shù)數(shù)組
/usr/local/ant/bin/ant -buildfile ${PROJECT_HOME}/build/build.xml "$@"
# build腳本結(jié)束

  如果是在windows環(huán)境中,下面是build.bat腳本的一個(gè)范例:

# build.bat 
# 關(guān)閉echo顯示
@echo off
# 設(shè)置%JAVA_HOME%
if "%JAVA_HOME%"=="" set JAVA_HOME=f:\tools\java
# 設(shè)置%ANT_HOME%
if "%ANT_HOME%"=="" set ANT_HOME=f:\tools\ant
# 設(shè)置PROJECT_HOME
set PROJECT_HOME = %CD%\..
set CLASSPATH_BAK=%CLASSPATH%
set CLASSPATH=
# 執(zhí)行build
%ANT_HOME%\bin\ant.bat -buildfile ..\build\build.xml %1 %2 %3 %4 %5 %6 %7 %8 %9

  6、build配置文件
  在${PROJECT_HOME}/build目錄下面,需要定義兩個(gè)文件,一個(gè)是build.properties,一個(gè)是build.xml
  build.properties文件定義了build的一些常量

# build.properties
project = tangtang
version = 1.1.1
# 采用classic編譯,即采用ant編譯
build.compiler = classic
# 采用jikes編譯
#build.compiler = jikes

year = 2004
debug = on
optimize = on
deprecation = on

os = linux
author = tangtang
email = syvin_tom@hotmail.com
url = www.tangtang.org
company = tangtang.org

build.xml文件是ant編譯的主要配置文件,ant功能強(qiáng)大,需要通過相應(yīng)的配置項(xiàng)來表現(xiàn)。
<?xml version="1.0" encoding="gb2312"?>

<!-- Build file for project -->

<project name="cyber" default="jar" basedir=".">
<property file="${user.home}/.ant.properties" />
<!-- ant build properties -->
<property file="build.properties"/>

<property name="build.dir" value=".."/>
<property name="build.src" value="${build.dir}/webapps/WEB-INF/src/java"/>
<property name="build.dest" value="${build.dir}/webapps/WEB-INF/classes"/>
<property name="build.lib" value="${build.dir}/webapps/WEB-INF/lib"/>
<property name="build.ext" value="./lib"/>
<property name="build.tpl" value="${build.dir}/webapps/WEB-INF/templates"/>
<property name="build.encoding" value="gb2312"/>

<property name="src.java.dir" value="../src/java"/>
<property name="javadoc.destdir" value="../docs/api"/>
<property name="javadoc.link" value="http://www.tangtang.org/java/docs/api/"/>
<property name="final.name" value="${project}-${version}"/>
<property name="dist.root" value="${build.dir}/dist"/>
<property name="dist.dir" value="${dist.root}/${final.name}"/>

<path id="classpath">
<pathelement path="${java.class.path}/"/>
<fileset dir="${build.lib}">
<include name="*.jar"/>
</fileset>
<fileset dir="${build.ext}">
<include name="*.jar"/>
</fileset>
</path>

<property name="classpath" refid="classpath"/>
<!-- =================================================================== -->
<!-- prints the environment -->
<!-- =================================================================== -->
<target name="env">
<echo message="build.compiler = ${build.compiler}"/>
<echo message="java.home = ${java.home}"/>
<echo message="user.home = ${user.home}"/>
<!--echo message="java.class.path = ${java.class.path}"/-->
<echo message="classpath = ${classpath}"/>
</target>

<!-- =================================================================== -->
<!-- Prepares the build directory -->
<!-- =================================================================== -->
<target name="prepare" depends="env">

<tstamp/>
<filter token="year" value="${year}"/>
<filter token="version" value="${version}"/>
<filter token="date" value="${DSTAMP}"/>
<!--
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.dest}"/>
<mkdir dir="${build.src}"/>
-->
<!-- chose a class that's from j2ee.jar -->
<available classname="javax.sql.DataSource"
property="J2EE.present">
<classpath refid = "classpath"/>
</available>
</target>
<target name="J2EE-error" depends="prepare" unless="J2EE.present">

<echo>
********************************************************
**
** J2EE has not been found and is needed for the target
** you have chosen
**
** Since CLASSPATH is an evil idea, just link or drop
** a copy of your j2ee.jar into build/lib directory.
**
*********************************************************
</echo>
</target>

<target name="init">
<echo>
build init
build compile
</echo>
<mkdir dir="${build.dir}/data"/>
<mkdir dir="${build.dir}/logs"/>
<mkdir dir="${build.dir}/dist"/>
</target>

<target name="jar" depends="compile">
<mkdir dir="${dist.root}"/>
<delete dir="${dist.root}/${project}-${version}.jar"/>
<jar jarfile="${dist.root}/${project}-${version}.jar">
<fileset dir="${build.dest}">
<include name="org/tangtang/**"/>
<exclude name="org/tangtang/test/**"/>
</fileset>
</jar>
</target>

<target name="srcjar" depends="prepare">
<delete dir="${dist.root}/${project}-${version}-src.jar"/>
<jar jarfile="${dist.root}/${project}-${version}-src.jar">
<fileset dir="${build.src}">
<include name="org/tangtang/**"/>
<include name="org/tangtang/test/**"/>
</fileset>
</jar>
</target>

<target name="tpl" depends="env">
<jar jarfile="${dist.root}/${project}-${version}-tpl.jar">
<fileset dir="${build.tpl}">
<include name="tangtang/**"/>
</fileset>
</jar>
</target>

<target name="javadocs">
<mkdir dir="${build.dir}/docs/api"/>
<javadoc
sourcepath="${build.src}"
overview="${build.dir}/docs/overview.html"
packagenames="org.tangtang.*"
destdir="${build.dir}/docs/api"
encoding="${build.encoding}"
author="true"
version="true"
use="true"
link="${javadoc.link}"
windowtitle="${project} ${version} API"
doctitle="${project} ${version} API"
bottom="Copyright &copy; ${year} tangtang.org. All Rights Reserved."
>
<tag name="todo" description="To Do:"/>
</javadoc>
</target>

<target name="poolman" depends="prepare">
<jar jarfile="${dist.root}/poolman.jar">
<fileset dir="${build.dest}">
<include name="com/codestudio/**"/>
</fileset>
</jar>
</target>

<target name="nightly" depends="prepare">
<tstamp/>
<jar jarfile="${dist.root}/nightly/${project}-${version}-${DSTAMP}-src.jar">
<fileset dir="${build.src}">
<include name="org/tangtang/**"/>
</fileset>
</jar>
</target>

<target name="compile" depends="prepare">
<mkdir dir="${build.dest}"/>

<!-- 檢查依賴性 -->
<depend srcdir="${build.src}"
destdir="${build.dest}"
cache="${build.dest}">
<classpath refid="classpath"/>
</depend>

<javac srcdir="${build.src}"
destdir="${build.dest}"
debug="${debug}"
deprecation="${deprecation}"
optimize="${optimize}">
<classpath refid="classpath"/>
</javac>
</target>

<target name="clean">
<delete>
<fileset dir="${build.dest}">
<include name="**/*.class"/>
</fileset>
</delete>
</target>

<target name="clean_dist">
<delete>
<fileset dir="${dist.root}" includes="*"/>
</delete>
<delete dir="${dist.dir}" quiet="false"/>
</target>

<target name="deploy" depends="jar">
<mkdir dir="${dist.dir}/data"/>
<mkdir dir="${dist.dir}/logs"/>

<copy todir="${dist.dir}/bin">
<fileset dir="${build.dir}/bin">
<include name="*"/>
</fileset>
</copy>

<fixcrlf srcdir="${dist.dir}/bin" eol="lf" eof="remove"
includes="**/*"
excludes="**/*.bat"
/>

<copy todir="${dist.dir}/conf">
<fileset dir="${build.dir}/conf">
<include name="templates/*"/>
<exclude name="*"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/build">
<fileset dir="${build.dir}/build">
<include name="*"/>
<include name="lib/*"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/templates">
<fileset dir="${build.dir}/templates">
<include name="**/*.vm"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/webapps/html">
<fileset dir="${build.dir}/webapps/html">
<include name="**/*"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/webapps/applet">
<fileset dir="${build.dir}/webapps/applet">
<include name="**/*"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/webapps/icons">
<fileset dir="${build.dir}/webapps/icons">
<include name="**/*.gif"/>
<include name="**/*.jpg"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/webapps/images">
<fileset dir="${build.dir}/webapps/images">
<include name="**/*.gif"/>
<include name="**/*.jpg"/>
<exclude name="**/*.bak"/>
<exclude name="**/bak/**"/>
</fileset>
</copy>

<copy todir="${dist.dir}/webapps/WEB-INF/">
<fileset dir="${build.dir}/webapps/WEB-INF/">
<include name="**/*"/>
<exclude name="classes/**"/>
<exclude name="conf/*"/>
<exclude name="src/**"/>
</fileset>
</copy>

<jar jarfile="${dist.root}/${project}-${version}-war.jar">
<fileset dir="${dist.dir}">
<include name="**/*"/>
</fileset>
</jar>
</target>

<target name="conf">
<delete>
<fileset dir="${build.dir}/conf" includes="*"/>
<fileset dir="${build.dir}/webapps/WEB-INF/conf" includes="*"/>
</delete>
<filter filtersfile="deploy.properties"/>
<copy todir="${build.dir}/conf" filtering="true">
<fileset dir="${build.dir}/conf/templates">
<include name="*"/>
</fileset>
</copy>
<copy todir="${build.dir}/webapps/WEB-INF/conf" filtering="true">
<fileset dir="${build.dir}/webapps/WEB-INF/conf/templates">
<include name="*"/>
</fileset>
</copy>
</target>
</project>


hilor 2007-10-23 12:14 發(fā)表評(píng)論
]]>
抽象類與接口的區(qū)別http://www.aygfsteel.com/hilor/archive/2007/08/29/141030.htmlhilorhilorWed, 29 Aug 2007 09:55:00 GMThttp://www.aygfsteel.com/hilor/archive/2007/08/29/141030.htmlhttp://www.aygfsteel.com/hilor/comments/141030.htmlhttp://www.aygfsteel.com/hilor/archive/2007/08/29/141030.html#Feedback1http://www.aygfsteel.com/hilor/comments/commentRss/141030.htmlhttp://www.aygfsteel.com/hilor/services/trackbacks/141030.htmlabstract class和interface是Java語言中對于抽象類定義進(jìn)行支持的兩種機(jī)制,正是由于這兩種機(jī)制的存在,才賦予了Java強(qiáng)大的面向?qū)ο竽芰Αbstract class和interface之間在對于抽象類定義的支持方面具有很大的相似性,甚至可以相互替換,因此很多開發(fā)者在進(jìn)行抽象類定義時(shí)對于abstract class和interface的選擇顯得比較隨意。
       其實(shí),兩者之間還是有很大的區(qū)別的,對于它們的選擇甚至反映出對于問題領(lǐng)域本質(zhì)的理解、對于設(shè)計(jì)意圖的理解是否正確、合理。本文將對它們之間的區(qū)別進(jìn)行一番剖析,試圖給開發(fā)者提供一個(gè)在二者之間進(jìn)行選擇的依據(jù)。
一、 理解抽象類
       abstract class和interface在Java語言中都是用來進(jìn)行抽象類(本文中的抽象類并非從abstract class翻譯而來,它表示的是一個(gè)抽象體,而abstract class為Java語言中用于定義抽象類的一種方法,請讀者注意區(qū)分)定義的,那么什么是抽象類,使用抽象類能為我們帶來什么好處呢?
       在面向?qū)ο蟮母拍钪校覀冎浪械膶ο蠖际峭ㄟ^類來描繪的,但是反過來卻不是這樣。并不是所有的類都是用來描繪對象的,如果一個(gè)類中沒有包含足夠的信息來描繪一個(gè)具體的對象,這樣的類就是抽象類。抽象類往往用來表征我們在對問題領(lǐng)域進(jìn)行分析、設(shè)計(jì)中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象。
       比如:如果我們進(jìn)行一個(gè)圖形編輯軟件的開發(fā),就會(huì)發(fā)現(xiàn)問題領(lǐng)域存在著圓、三角形這樣一些具體概念,它們是不同的,但是它們又都屬于形狀這樣一個(gè)概念,形狀這個(gè)概念在問題領(lǐng)域是不存在的,它就是一個(gè)抽象概念。正是因?yàn)槌橄蟮母拍钤趩栴}領(lǐng)域沒有對應(yīng)的具體概念,所以用以表征抽象概念的抽象類是不能夠?qū)嵗摹?br>       在面向?qū)ο箢I(lǐng)域,抽象類主要用來進(jìn)行類型隱藏。我們可以構(gòu)造出一個(gè)固定的一組行為的抽象描述,但是這組行為卻能夠有任意個(gè)可能的具體實(shí)現(xiàn)方式。這個(gè)抽象描述就是抽象類,而這一組任意個(gè)可能的具體實(shí)現(xiàn)則表現(xiàn)為所有可能的派生類。模塊可以操作一個(gè)抽象體。由于模塊依賴于一個(gè)固定的抽象體,因此它可以是不允許修改的;同時(shí),通過從這個(gè)抽象體派生,也可擴(kuò)展此模塊的行為功能。熟悉OCP的讀者一定知道,為了能夠?qū)崿F(xiàn)面向?qū)ο笤O(shè)計(jì)的一個(gè)最核心的原則OCP(Open-Closed Principle),抽象類是其中的關(guān)鍵所在。

二、從語法定義層面看abstract class和interface
       在語法層面,Java語言對于abstract class和interface給出了不同的定義方式,下面以定義一個(gè)名為Demo的抽象類為例來說明這種不同。使用abstract class的方式定義Demo抽象類的方式如下:
abstract class Demo {
 abstract void method1();
 abstract void method2();
 …

使用interface的方式定義Demo抽象類的方式如下:
interface Demo {
 void method1();
 void method2();
 …
}
在abstract class方式中,Demo可以有自己的數(shù)據(jù)成員,也可以有非abstarct的成員方法,而在interface方式的實(shí)現(xiàn)中,Demo只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員(也就是必須是static final的,不過在interface中一般不定義數(shù)據(jù)成員),所有的成員方法都是abstract的。從某種意義上說,interface是一種特殊形式的abstract class。
       從編程的角度來看,abstract class和interface都可以用來實(shí)現(xiàn)"design by contract"的思想。但是在具體的使用上面還是有一些區(qū)別的。
       首先,abstract class在Java語言中表示的是一種繼承關(guān)系,一個(gè)類只能使用一次繼承關(guān)系。但是,一個(gè)類卻可以實(shí)現(xiàn)多個(gè)interface。也許,這是Java語言的設(shè)計(jì)者在考慮Java對于多重繼承的支持方面的一種折中考慮吧。
       其次,在abstract class的定義中,我們可以賦予方法的默認(rèn)行為。但是在interface的定義中,方法卻不能擁有默認(rèn)行為,為了繞過這個(gè)限制,必須使用委托,但是這會(huì) 增加一些復(fù)雜性,有時(shí)會(huì)造成很大的麻煩。
       在抽象類中不能定義默認(rèn)行為還存在另一個(gè)比較嚴(yán)重的問題,那就是可能會(huì)造成維護(hù)上的麻煩。因?yàn)槿绻髞硐胄薷念惖慕缑妫ㄒ话阃ㄟ^abstract class或者interface來表示)以適應(yīng)新的情況(比如,添加新的方法或者給已用的方法中添加新的參數(shù))時(shí),就會(huì)非常的麻煩,可能要花費(fèi)很多的時(shí)間(對于派生類很多的情況,尤為如此)。但是如果界面是通過abstract class來實(shí)現(xiàn)的,那么可能就只需要修改定義在abstract class中的默認(rèn)行為就可以了。
       同樣,如果不能在抽象類中定義默認(rèn)行為,就會(huì)導(dǎo)致同樣的方法實(shí)現(xiàn)出現(xiàn)在該抽象類的每一個(gè)派生類中,違反了"one rule,one place"原則,造成代碼重復(fù),同樣不利于以后的維護(hù)。因此,在abstract class和interface間進(jìn)行選擇時(shí)要非常的小心。

二、 從設(shè)計(jì)理念層面看abstract class和interface
       上面主要從語法定義和編程的角度論述了abstract class和interface的區(qū)別,這些層面的區(qū)別是比較低層次的、非本質(zhì)的。本文將從另一個(gè)層面:abstract class和interface所反映出的設(shè)計(jì)理念,來分析一下二者的區(qū)別。作者認(rèn)為,從這個(gè)層面進(jìn)行分析才能理解二者概念的本質(zhì)所在。
       前面已經(jīng)提到過,abstarct class在Java語言中體現(xiàn)了一種繼承關(guān)系,要想使得繼承關(guān)系合理,父類和派生類之間必須存在"is a"關(guān)系,即父類和派生類在概念本質(zhì)上應(yīng)該是相同的。對于interface 來說則不然,并不要求interface的實(shí)現(xiàn)者和interface定義在概念本質(zhì)上是一致的,僅僅是實(shí)現(xiàn)了interface定義的契約而已。為了使論述便于理解,下面將通過一個(gè)簡單的實(shí)例進(jìn)行說明。
       考慮這樣一個(gè)例子,假設(shè)在我們的問題領(lǐng)域中有一個(gè)關(guān)于Door的抽象概念,該Door具有執(zhí)行兩個(gè)動(dòng)作open和close,此時(shí)我們可以通過abstract class或者interface來定義一個(gè)表示該抽象概念的類型,定義方式分別如下所示:
使用abstract class方式定義Door:

abstract class Door {
 abstract void open();
 abstract void close();
}

使用interface方式定義Door:

interface Door {
 void open();
 void close();
}
其他具體的Door類型可以extends使用abstract class方式定義的Door或者implements使用interface方式定義的Door。看起來好像使用abstract class和interface沒有大的區(qū)別。
       如果現(xiàn)在要求Door還要具有報(bào)警的功能。我們該如何設(shè)計(jì)針對該例子的類結(jié)構(gòu)呢(在本例中,主要是為了展示abstract class和interface反映在設(shè)計(jì)理念上的區(qū)別,其他方面無關(guān)的問題都做了簡化或者忽略)下面將羅列出可能的解決方案,并從設(shè)計(jì)理念層面對這些不同的方案進(jìn)行分析。

解決方案一:
       簡單的在Door的定義中增加一個(gè)alarm方法,如下:
abstract class Door {
 abstract void open();
 abstract void close();
 abstract void alarm();
}

或者

interface Door {
 void open();
 void close();
 void alarm();
}

那么具有報(bào)警功能的AlarmDoor的定義方式如下:
class AlarmDoor extends Door {
 void open() { … }
 void close() { … }
 void alarm() { … }
}

或者

class AlarmDoor implements Door {
 void open() { … }
 void close() { … }
 void alarm() { … }

這種方法違反了面向?qū)ο笤O(shè)計(jì)中的一個(gè)核心原則ISP(Interface Segregation Priciple),在Door的定義中把Door概念本身固有的行為方法和另外一個(gè)概念"報(bào)警器"的行為方法混在了一起。這樣引起的一個(gè)問題是那些僅僅依賴于Door這個(gè)概念的模塊會(huì)因?yàn)?報(bào)警器"這個(gè)概念的改變(比如:修改alarm方法的參數(shù))而改變,反之依然。

解決方案二:
       既然open、close和alarm屬于兩個(gè)不同的概念,根據(jù)ISP原則應(yīng)該把它們分別定義在代表這兩個(gè)概念的抽象類中。定義方式有:這兩個(gè)概念都使用abstract class方式定義;兩個(gè)概念都使用interface方式定義;一個(gè)概念使用abstract class方式定義,另一個(gè)概念使用interface方式定義。 顯然,由于Java語言不支持多重繼承,所以兩個(gè)概念都使用abstract class方式定義是不可行的。后面兩種方式都是可行的,但是對于它們的選擇卻反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計(jì)意圖的反映是否正確、合理。我們一一來分析、說明。
       如果兩個(gè)概念都使用interface方式來定義,那么就反映出兩個(gè)問題:
1、 我們可能沒有理解清楚問題領(lǐng)域,AlarmDoor在概念本質(zhì)上到底是Door還是報(bào)警器?
2、如果我們對于問題領(lǐng)域的理解沒有問題,比如:我們通過對于問題領(lǐng)域的分析發(fā)現(xiàn)AlarmDoor在概念本質(zhì)上和Door是一致的,那么我們在實(shí)現(xiàn)時(shí)就沒有能夠正確的揭示我們的設(shè)計(jì)意圖,因?yàn)樵谶@兩個(gè)概念的定義上(均使用interface方式定義)反映不出上述含義。 如果我們對于問題領(lǐng)域的理解是:AlarmDoor在概念本質(zhì)上是Door,同時(shí)它有具有報(bào)警的功能。我們該如何來設(shè)計(jì)、實(shí)現(xiàn)來明確的反映出我們的意思呢?前面已經(jīng)說過,abstract class在Java語言中表示一種繼承關(guān)系,而繼承關(guān)系在本質(zhì)上是"is a"關(guān)系。所以對于Door這個(gè)概念,我們應(yīng)該使用abstarct class方式來定義。另外,AlarmDoor又具有報(bào)警功能,說明它又能夠完成報(bào)警概念中定義的行為,所以報(bào)警概念可以通過interface方式定義。如下所示:
abstract class Door {
 abstract void open();
 abstract void close();
}
interface Alarm {
 void alarm();
}
class AlarmDoor extends Door implements Alarm {
 void open() { … }
 void close() { … }
    void alarm() { … }
}

這種實(shí)現(xiàn)方式基本上能夠明確的反映出我們對于問題領(lǐng)域的理解,正確的揭示我們的設(shè)計(jì)意圖。其實(shí)abstract class表示的是"is a"關(guān)系,interface表示的是"like a"關(guān)系,大家在選擇時(shí)可以作為一個(gè)依據(jù),當(dāng)然這是建立在對問題領(lǐng)域的理解上的,比如:如果我們認(rèn)為AlarmDoor在概念本質(zhì)上是報(bào)警器,同時(shí)又具有Door的功能,那么上述的定義方式就要反過來了。
       abstract class和interface是Java語言中的兩種定義抽象類的方式,它們之間有很大的相似性。但是對于它們的選擇卻又往往反映出對于問題領(lǐng)域中的概念本質(zhì)的理解、對于設(shè)計(jì)意圖的反映是否正確、合理,因?yàn)樗鼈儽憩F(xiàn)了概念間的不同的關(guān)系(雖然都能夠?qū)崿F(xiàn)需求的功能)。這其實(shí)也是語言的一種的慣用法,希望讀者朋友能夠細(xì)細(xì)體會(huì)。



hilor 2007-08-29 17:55 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 东光县| 松溪县| 宜兰市| 罗田县| 阿图什市| 方正县| 九江市| 玉屏| 北京市| 孟村| 墨竹工卡县| 延津县| 托里县| 隆昌县| 沾化县| 云和县| 云安县| 睢宁县| 文山县| 重庆市| 石城县| 霍邱县| 桂东县| 延庆县| 泰州市| 共和县| 隆德县| 左权县| 正蓝旗| 涟水县| 涟源市| 西昌市| 湖北省| 大荔县| 沾益县| 壤塘县| 金溪县| 长海县| 衡水市| 同仁县| 宁津县|