春天里,百花香...
2008年7月18日
#
我習(xí)慣連代碼和文章一起貼,現(xiàn)在空間用完了,重新注冊(cè)了一個(gè)( http://m.tkk7.com/heyang ),歡迎大家訪問。
摘要: 我們可以使用DOM來解析來自服務(wù)器端的XML反饋,但返回結(jié)果比較復(fù)雜時(shí)我們必須在XML文檔中一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)的向下鉆探,而使用XPath(專門用于定位匹配模式的一個(gè)或多個(gè)節(jié)點(diǎn)的小語言)只要一行代碼就能遍歷多個(gè)節(jié)點(diǎn)。與使用DOM相比,使用XSLT和XPath編碼所投入的精力要小得多,隨著應(yīng)用規(guī)模的增長(zhǎng),后者的優(yōu)勢(shì)會(huì)越來越顯著。
閱讀全文
摘要: 側(cè)邊欄靜態(tài)樹狀菜單在WebApp中很常見,本文涉及了靜態(tài)樹狀菜單的制作和顯示控制。比較簡(jiǎn)單。
閱讀全文
摘要: 如果WebApp的側(cè)面菜單項(xiàng)較多時(shí)我們可以采用SlideBar的方式將部分菜單顯示,大部隱藏,類似Visio中做得那樣。本文討論了Slidebar的做法和顯示控制,比較簡(jiǎn)單。
閱讀全文
摘要: 工字型布局中都有一個(gè)側(cè)邊菜單欄目用以導(dǎo)航,它們存在的一個(gè)普遍問題是:用戶無法迅速的找到自己所處頁面在整個(gè)網(wǎng)站中的位置。
當(dāng)菜單項(xiàng)較多時(shí)這會(huì)演變成一個(gè)大問題,當(dāng)用戶需要刻意尋找網(wǎng)頁標(biāo)志來確定自己所處位置時(shí),這已經(jīng)說明網(wǎng)站給了客戶一種迷宮的感覺,有流失客戶的潛在可能性。很多網(wǎng)站采用了球拍式菜單來凸顯當(dāng)前所在頁面,本文探討了這種球拍式菜單的實(shí)現(xiàn)方式。
閱讀全文
摘要: SQL注入攻擊的基本原理,是從客戶端合法接口提交特殊的非法代碼,讓其注入到服務(wù)器端執(zhí)行業(yè)務(wù)的SQL中去,進(jìn)而改變SQL語句的原有邏輯和影響服務(wù)器端正常業(yè)務(wù)的處理。SQL注入攻擊是Web應(yīng)用中一個(gè)重要的安全問題,雖然Java具備較高的安全性,但如果開發(fā)人員不注意,也有可能留下安全隱患,本文將對(duì)此展開一些粗淺的探討,歡迎批評(píng)指正。
閱讀全文
摘要: 將網(wǎng)頁鏈接做成按鈕形狀是側(cè)邊菜單欄和頂端菜單欄常采用的形態(tài),本文總結(jié)了四種常用鏈接按鈕形態(tài)的CSS制法。
閱讀全文
//*****************************************************
// 《飛翔》 話劇《切格瓦拉》插曲 詞 黃繼蘇 曲 張廣天
//*****************************************************
陸地淹沒了,
你就在海上飛翔。
海洋干涸了,
你就在天上飛翔。
天雷滾動(dòng)了,
你就在火里飛翔。
火焰熄滅了,
你就在苦難中飛翔。
過去倒下了,
你就在未來飛翔。
未來退卻了,
你就在現(xiàn)在飛翔。
現(xiàn)在遲疑了,
你就在心中飛翔。
心靈敗壞了,
你就在創(chuàng)造中飛翔。
飛翔,飛翔,
永遠(yuǎn)的飛翔。
飛翔,飛翔,
不朽的飛翔!
//*****************************************************
// 隨遇而安方為福 曾國藩
//*****************************************************
人生世間,自有知識(shí)以來,即有憂患如意事。小兒叫號(hào),皆其意有不平。自幼至少至壯至老,如意之事常少,不如意之事常多。雖大富貴之人,天下所仰慕以為神仙,而其不如意處各自有之,與貧賤人無異,特所憂慮之事異爾。故謂之缺陷世界,以人生世間無足心滿意者。能達(dá)此理而順受之,則可稍安。
//*****************************************************
// 治學(xué)之道 《中華處世絕學(xué)》 一三九頁
//*****************************************************
治學(xué)之道,最緊要的是立下堅(jiān)卓不俗的大志,立志是事業(yè)的大門,一個(gè)人追求的目標(biāo)越高,他的學(xué)問長(zhǎng)進(jìn)就越快。
當(dāng)然,僅有高大的志向是遠(yuǎn)遠(yuǎn)不夠的。治學(xué),還要有“只問耕耘,不問收獲”的務(wù)實(shí)精神,避免奢談,踏實(shí)認(rèn)真。要明白學(xué)問的取得,不是一朝一夕的事情,必須勤學(xué)好問,持之以很。學(xué)問好比金字塔,基礎(chǔ)越深越搏越好,這樣才能在廣播的基礎(chǔ)上求得高精尖。做學(xué)問,必須重視讀書的方法,不要貪多,而要專注于一書,力求吃透。同時(shí),治學(xué)須避免門戶之見,博采眾長(zhǎng),兼收并蓄,為我所用,才能學(xué)貫中西,博古通今。而依賴于不俗的才學(xué),一個(gè)人才可能為國立功,為己立德,為人立言,受到后人的敬仰。
//*****************************************************
// 子曰
//*****************************************************
君子博學(xué)而日參省乎己 則知明而行無過矣.
子曰:賜也,汝以予為多學(xué)而識(shí)之者與?對(duì)曰:然,非與?曰:解也!予一以貫之。
//*****************************************************
// 尼采:在世紀(jì)的轉(zhuǎn)折點(diǎn)上 周國平著
//*****************************************************
大自然的星空,群星燦爛。哪最早閃現(xiàn)的,未必是最亮的星宿。有的星宿孤獨(dú)的燃燒著,熄滅了,很久很久以后,它的光才到達(dá)我們的眼睛。
歷史和文化的星空何嘗不是如此呢?
誰終將聲震人間,必長(zhǎng)久深自緘默;誰終將點(diǎn)燃閃電,必長(zhǎng)久如云漂泊。
一個(gè)精神貧乏,缺乏獨(dú)特個(gè)性的人,當(dāng)然不會(huì)遭受精神上危機(jī)的折磨。
許多人的所謂成熟,不過是被習(xí)俗磨去了棱角,變得世故而實(shí)際了。那不是成熟,而是精神的早衰和個(gè)性的夭亡。真正的成熟,應(yīng)當(dāng)是獨(dú)特個(gè)性的形成,真實(shí)自我的發(fā)現(xiàn),精神上的結(jié)果和豐收。
當(dāng)一個(gè)人要靠作品來批準(zhǔn)自己的一生,他在根基上就變得極為苛求了。
書籍,知識(shí),他人的思想都只能拿來為我所用,而不應(yīng)當(dāng)成為目的本身。
偉大的思想,與美麗的女子有相同的趣味,絕不肯讓萎靡的弱者來占有自己。
人只以勇敢和毅力所許可的限度接近真理。強(qiáng)者必須認(rèn)識(shí)并肯定現(xiàn)實(shí),正如弱者必須害怕和逃避現(xiàn)實(shí)一樣。
一個(gè)人倘若有健全旺盛的內(nèi)在生命力,他是不會(huì)屈服于悲觀主義的,悲觀主義是生命力衰退的表現(xiàn),屈服于悲觀主義有如屈服于霍亂,表明肌體已經(jīng)患病。
一個(gè)人健康,他就向往人生的快樂;一個(gè)人羸弱,他就念念不忘死亡,就悲觀厭世。一個(gè)要在世間有所建樹的人最忌悲觀主義“看破紅塵--這是巨大的疲勞和一切創(chuàng)造者的末日。”
沒有痛苦,人只能有卑微的幸福。偉大的幸福正是戰(zhàn)勝巨大痛苦所產(chǎn)生的生命的崇高感。痛苦磨練了意志,激發(fā)了生機(jī),解放了心靈。
熱愛人生的人縱然比別人感受到更多更多強(qiáng)烈的痛苦,同時(shí)也感受到更多更強(qiáng)烈的生命之歡樂。與痛苦相對(duì)抗,是人生最有趣味的事。
假如你在偉大的事業(yè)中失敗了,你自己因此便是失敗了么?假如你們自己是失敗了,人類因此便是失敗了么?假如人類也是失敗了,好吧,別在意!
堅(jiān)強(qiáng)而沉重,或者堅(jiān)強(qiáng)而陰郁,仍然不符合酒神精神。人生的偉大肯定者應(yīng)該兼有堅(jiān)硬的骨頭和輕捷的足,和歌者,武士與自由精神為一體。他應(yīng)當(dāng)學(xué)會(huì)“神圣的舞蹈”,學(xué)會(huì)歡笑。
//*****************************************************
// 自悟
//*****************************************************
唯有才華具有穿透心靈和穿越時(shí)空的力量。
//*****************************************************
// 其它摘錄
//*****************************************************
可以缺錢、可以缺吃、缺化,卻不可以缺德、確信用、缺操守!公司可以缺資金、缺設(shè)備,確不可以確倫理、缺道德、缺人才!
世事復(fù)雜,干什么事都不是那么簡(jiǎn)單。要想在一生中有所作為,干一番事業(yè),思想上必須有這樣的準(zhǔn)備:別怕麻煩,肯于吃苦,受些窩囊氣也能挺得住。否則,遇到麻煩事,意外事,不順心事就急躁,想逃避,不肯吃苦,不能耐心處理麻煩事;或者遇見不公就會(huì)生怒氣,發(fā)牢騷而不再努力,這樣的人事業(yè)難成。
平時(shí)外表懶散而身懷絕技的高手只存在于古龍的武俠小說里,平時(shí)不認(rèn)真,關(guān)鍵時(shí)刻肯定掉鏈子。
你可以靠謊言暫時(shí)領(lǐng)先,可不能靠它領(lǐng)先一輩子。
生活是一面鏡子,他照出了你的現(xiàn)實(shí),別人對(duì)你不好,一定是自己的原因,決不是別人。
只有掙到錢、這才是男人成功的絕佳體現(xiàn)。有時(shí)候想,錢的確比文憑、文章等一切虛無的東西更實(shí)在,更能證明一個(gè)人。
問題是帶人走出困境的最好的向?qū)?危機(jī)是教人進(jìn)行創(chuàng)造的最好的老師 看到問題就是看到出路 碰到危機(jī)就是碰到機(jī)會(huì)。對(duì)于勇視現(xiàn)實(shí) 不滿現(xiàn)狀 只求進(jìn)取 冷靜觀察 深入分析 甚至敢于自繪敗狀 自覺接受挑戰(zhàn)的人來說 問題就是希望 危機(jī)就是專輯。 或者簡(jiǎn)單地說,只有在危機(jī)中不能驚覺新轉(zhuǎn)機(jī)的人,有真正的危機(jī).
摘要: 模擬Blogjava制作的一個(gè)用CSS控制樣式的表格,比較簡(jiǎn)單。
閱讀全文
摘要: 工字型布局是Web中應(yīng)用比較廣泛的布局,它將整個(gè)頁面分成頁頭,側(cè)面導(dǎo)航欄,內(nèi)容欄和頁腳欄四部分,頁頭一般包括logo,網(wǎng)站標(biāo)題等;側(cè)面導(dǎo)航欄是導(dǎo)航菜單,根據(jù)客戶的喜好可以放在左邊也可以放在右邊;內(nèi)容是正文部分,左右也可以根據(jù)用戶的喜好放置;頁腳包括版權(quán)信息,聯(lián)系我們等。根據(jù)content欄的寬度是否會(huì)隨著瀏覽器的寬度改變可以將工字型布局分為固定兩欄方式和可變兩欄方式,本文討論了這兩種方式的制法。
閱讀全文
摘要: 除了Div,Table,F(xiàn)orm外,我們最常用的Html元素之一就是無序列表ul,使用它通常可以實(shí)現(xiàn)以下形式:
1.實(shí)現(xiàn)文本數(shù)據(jù)列表,這是無序列表的原始意圖。
2.嵌套使用無序列表,以實(shí)現(xiàn)樹狀結(jié)構(gòu)。
3.修改無序列表的樣式,將它作為菜單使用。相對(duì)于用表格制作的菜單項(xiàng),它修改起來比較方便,樣式也很容易設(shè)置。
第三點(diǎn)就是本文的主要議題。
閱讀全文
摘要: 一次將數(shù)據(jù)庫設(shè)計(jì)三范式應(yīng)用于表設(shè)計(jì)的實(shí)踐過程,比較淺顯。
閱讀全文
摘要: 表單是Web應(yīng)用中一個(gè)重要的組成部分,用戶向服務(wù)器端提交數(shù)據(jù)主要依靠表單進(jìn)行. 好的表單能幫助用戶順利的完成數(shù)據(jù)的填寫, 不好的表單會(huì)讓用戶對(duì)填寫過程充滿困惑和挫折感.這些都會(huì)影響客戶的心理,進(jìn)而會(huì)影響客戶對(duì)整個(gè)網(wǎng)站的感覺.
我覺得,前臺(tái)的表單設(shè)計(jì)和后臺(tái)的業(yè)務(wù)組件都很重要,和程序設(shè)計(jì)一樣,表單的設(shè)計(jì)也要遵照一定的原則和規(guī)范.
設(shè)計(jì)一個(gè)良好的表單,程序員需要綜合運(yùn)用HTML,CSS,JavaScript等方面的知識(shí),下面就是本人的一些關(guān)于表單設(shè)計(jì)的粗淺想法,斗膽拿出來和大家一起探討探討.
閱讀全文
摘要: 本文就分頁的理由,分頁的方式和MySql,Oracle中兩種不同的分頁技術(shù)進(jìn)行了一些闡述,比較淺顯。
閱讀全文
摘要: 此文是“Web頁面表單域驗(yàn)證方式的改進(jìn)”的續(xù)篇。
示例頁面:登錄頁面
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="/WEB-INF/tld/struts-html.tld" prefix="html"...
閱讀全文
摘要: 在基于Model2的應(yīng)用中,控制層的類總會(huì)包含對(duì)業(yè)務(wù)層諸類的調(diào)用,業(yè)務(wù)層諸類不可避免的要產(chǎn)生各種異常,如果統(tǒng)一到控制層進(jìn)行處理的話會(huì)導(dǎo)致代碼變得龐大臃腫還有不少重復(fù),這種的例子在Web應(yīng)用中的Servlet和Action諸類中并不少見。
如果我們使用模板方法模式(Template Method Pattern)將業(yè)務(wù)處理和異常處理分開,能有效簡(jiǎn)化控制層諸類的代碼,借用這種模式,我們可以把固定的異常處理代碼放在基類中,而讓子類來實(shí)現(xiàn)具體的業(yè)務(wù),如果執(zhí)行業(yè)務(wù)過程中出現(xiàn)異常如數(shù)據(jù)庫無法連接,用戶找不到等異常后,直接將異常拋出讓基類來處理,這樣做成功的把業(yè)務(wù)處理和異常處理分開到了子類和基類兩種類中,涉及具體業(yè)務(wù)處理的子類代碼得到了很大的簡(jiǎn)化,更方便閱讀,修改和管理。
有點(diǎn)疑惑的是,現(xiàn)在還不確定這樣做會(huì)有什么消極印象,如安全性或結(jié)構(gòu)方面的,大家要是覺得有問題請(qǐng)不吝賜教。
閱讀全文
摘要: 一般來說涉及數(shù)據(jù)庫的應(yīng)用中,表的主鍵有兩種生成方案,一種是專門定義一個(gè)主鍵表,在其中放置一個(gè)自增長(zhǎng)的字段為其它表提供主鍵;另一種是使用Oracle的sequence。這兩種方案都有一定麻煩,Spring為此專門提供了一個(gè)ID增長(zhǎng)器以簡(jiǎn)化具體步驟,下文就是它的相關(guān)使用方法的,使用的數(shù)據(jù)庫是MySql5.
歸納
使用Spring的自增長(zhǎng)ID生成器完成以下三步即可:
1)配置自增長(zhǎng)id生成器,它需要一個(gè)數(shù)據(jù)源的支持。
2)根據(jù)配置將自增長(zhǎng)id生成器注入DAO各類中。
3)使用nextStringValue,nextIntValue,nextLongValue方法得到ID。
閱讀全文
注意:本文說到的log4j版本為1.2.15,使用的配置文件是屬性文件(properties),如果這些與您的環(huán)境不符則請(qǐng)快速離開,以免耽誤你的寶貴時(shí)間。
一.log4j在桌面程序中的配置
這個(gè)相對(duì)簡(jiǎn)單了,它的步驟就這樣兩步:
1)將log4j-1.2.15.jar引入到工程的lib目錄中.
2)確保配置文件log4j.properties在程序的代碼目錄(如src目錄,cfg目錄)中,它編譯后應(yīng)該位于類路徑classes中.
log4j.properties示例(可以拷貝使用):
- log4j.rootLogger=debug, stdout, R
-
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
- log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
- # Pattern to output the caller's file name and line number.
- log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
-
- log4j.appender.R=org.apache.log4j.RollingFileAppender
- log4j.appender.R.File=輸出log文件.log
-
- log4j.appender.R.MaxFileSize=1000KB
- # Keep one backup file
- log4j.appender.R.MaxBackupIndex=1
-
- log4j.appender.R.layout=org.apache.log4j.PatternLayout
- log4j.appender.R.layout.ConversionPattern=%d %5p [%t] (%F:%L) - %m%n
要對(duì)這個(gè)文件進(jìn)行修改的話,基本上改兩個(gè)地方就行了。
一個(gè)是輸出文件名稱,一個(gè)是輸出等級(jí)設(shè)置。
1) 輸出文件名稱:
log4j.appender.R.File=輸出log文件.log
2) 輸出等級(jí):
log4j.rootLogger=debug, stdout, R
Debug說明只要是logger.debug以上的都記錄
配置到這里,就結(jié)束了。下面請(qǐng)看如何在程序中使用log4j。
二.log4j的使用
1) 首先,那個(gè)類要用到log4j記錄日志,就應(yīng)該為類添加一個(gè)靜態(tài)的成員變量loogger,示例如下:
- public class Main{
- private static Logger logger = Logger.getLogger(Main.class);
-
- public static void main(String[] args){
- logger.info("成員管理程序啟動(dòng)");
- new MemberMngCtrl();
- }
- }
2) 其次,你就可以使用logger.debug ,logger.info, logger.warn, logger.error, logger.fatal等函數(shù)(記錄等級(jí)依次提高)來記錄日志內(nèi)容了,確實(shí)是很簡(jiǎn)單方便的。
三.log4j在Web工程中的配置
與桌面程序一樣的是,properties文件也需要能被編譯到classes(WEB-INF/classes/)中,建議將屬性文件放在特定的目錄下并設(shè)置為源碼目錄,另外放在WEB-INF\src下也不錯(cuò)。
這一步比前面稍多的是需要配置一個(gè)初始化log4j的initServlet,就是在一開始就啟動(dòng)的Servlet,代碼如下:
- public class Log4jInit extends HttpServlet {
- private static final long serialVersionUID = -4499302208753939187L;
- static Logger logger = Logger.getLogger(Log4jInit.class);
-
- public void init(ServletConfig config) throws ServletException {
- String prefix = config.getServletContext().getRealPath("/");
- String file = config.getInitParameter("log4j");
- String filePath = prefix + file;
- Properties props = new Properties();
-
- try {
- FileInputStream istream = new FileInputStream(filePath);
- props.load(istream);
- istream.close();
-
- String logFile = prefix + props.getProperty("log4j.appender.R.File");
- props.setProperty("log4j.appender.R.File",logFile);
-
-
- PropertyConfigurator.configure(props);
- } catch (IOException e) {
- System.out.println("Could not read configuration file [" + filePath + "].");
- System.out.println("Ignoring configuration file [" + filePath + "].");
- return;
- }
- }
- }
然后,在Web.xml中配置一下,讓它在一開始啟動(dòng)就可以了。
-
- <servlet>
- <servlet-name>log4j-init</servlet-name>
- <servlet-class>
- com.sitinspring.action.Log4jInit
- </servlet-class>
- <init-param>
- <param-name>log4j</param-name>
- <param-value>WEB-INF/classes/log4j.properties</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
全文完。
一般來說, 在創(chuàng)建一個(gè)應(yīng)用程序之前,首先要決定這個(gè)應(yīng)用程序的體系結(jié)構(gòu)。應(yīng)用程序體系結(jié)構(gòu)(Application Architecture)由應(yīng)用程序開發(fā)者設(shè)計(jì),它指定了在各種各樣的終端系統(tǒng)上,應(yīng)用程序是如何組織在一起的。為了降低設(shè)計(jì)難度,大部分程序都以層(稱為layer或level)的方式組織在一起,每一層都建立在它的下層基礎(chǔ)上,使用下層提供的服務(wù),下層對(duì)上層隱藏了許多服務(wù)實(shí)現(xiàn)的細(xì)節(jié)。這種方法幾乎應(yīng)用于整個(gè)計(jì)算機(jī)科學(xué)領(lǐng)域,也可以稱為信息隱藏,數(shù)據(jù)類型抽象,數(shù)據(jù)封裝,面向?qū)ο缶幊痰取?/p>
分層即是對(duì)類進(jìn)行一些規(guī)劃,以流程中的類的用途和所處環(huán)節(jié)劃分,把程序中將要用到的各個(gè)類分別歸納到各個(gè)包(目錄)中。分層是對(duì)系統(tǒng)進(jìn)行細(xì)分的第一步,它旨在將系統(tǒng)按具體功能和用途分解為相對(duì)獨(dú)立的各個(gè)部分.如果說細(xì)分是將把難以解決的大問題分解成了各個(gè)容易解決的小問題的話,分層則是把解決同類小問題的類歸納到一起,這樣程序的結(jié)構(gòu)更加清晰,程序的可讀性和可維護(hù)性越好,也更容易得到重用。
從大的尺度來講,一個(gè)程序可粗略的分成三個(gè)層次:
界面層(UI layer),這是用戶能直接感受到的,包含顯示和控制兩部分;
業(yè)務(wù)層(Business layer),其中包含了業(yè)務(wù)邏輯和業(yè)務(wù)處理;
持久層(Persistence layer),它用來將數(shù)據(jù)存儲(chǔ)和將數(shù)據(jù)從持久層提取出來。

界面層(UI layer)中,包含兩個(gè)層次:視圖層View和控制層Controller.
視圖層View是用戶查看數(shù)據(jù),輸入和向用戶輸出結(jié)果的一層,這一層是用戶唯一能夠感受軟件功能的窗口,它或者由Swing組件搭建(桌面系統(tǒng)或C/S系統(tǒng)中),或者由JSP搭建(B/S系統(tǒng)),它負(fù)責(zé)讓用戶輸入數(shù)據(jù)和將控制層返回的數(shù)據(jù)顯示給客戶。其中返回的數(shù)據(jù)一般是領(lǐng)域?qū)ο蟮淖凅w或者直接就是領(lǐng)域?qū)ο蠡蚱浼稀T赪eb程序中jsp基本就屬于這一層的。
控制層Controller是用來將界面和業(yè)務(wù)層聯(lián)系在一起的,在系統(tǒng)的各層次中,應(yīng)該和View層打交道一般只有Controller層, Controller層是View層和系統(tǒng)其它層次進(jìn)行交互的中介者, View層越過中介者直接調(diào)用其它層次的行為應(yīng)該盡量避免。
一般來說,為了減少耦合,提高程序的可維護(hù)性,我們一般采用MVC架構(gòu)模式將業(yè)務(wù)層,視圖層和控制層分開。
業(yè)務(wù)層(Business layer)中包含領(lǐng)域?qū)?nbsp;Domain,服務(wù)層 Service和實(shí)用工具層Util。
業(yè)務(wù)層是整個(gè)系統(tǒng)的關(guān)鍵部分,它主要由領(lǐng)域模型和業(yè)務(wù)邏輯組成,領(lǐng)域模型定義系統(tǒng)內(nèi)相互作用的各個(gè)實(shí)體,業(yè)務(wù)邏輯則定義了領(lǐng)域模型所能執(zhí)行的不同操作, 領(lǐng)域?qū)拥母鱾€(gè)類代表了領(lǐng)域模型,而服務(wù)層的各個(gè)類代表了業(yè)務(wù)邏輯. 領(lǐng)域?qū)雍头?wù)層是起點(diǎn),其它各層都從這里起步.
領(lǐng)域?qū)?nbsp;Domain:領(lǐng)域?qū)ο笫菍?duì)現(xiàn)實(shí)世界業(yè)務(wù)處理對(duì)象的抽象和歸納,領(lǐng)域?qū)又械念惢旧隙际菍?shí)體(Entity)類,如員工管理系統(tǒng)中的Employee,學(xué)籍管理系統(tǒng)中的Student,借貸管理系統(tǒng)中的Contract等,系統(tǒng)的業(yè)務(wù)處理中用到那些實(shí)體對(duì)象,領(lǐng)域?qū)又幸话憔蛻?yīng)該有和這個(gè)實(shí)體對(duì)象相對(duì)應(yīng)的實(shí)體類。這些類在剛開始設(shè)計(jì)時(shí)可能只有一些屬性和對(duì)應(yīng)的getter/setter方法,以后會(huì)不斷的加入新的內(nèi)容(主要是方法),如果有必要的話,可以為這些領(lǐng)域?qū)ο笤O(shè)計(jì)一些上層的抽象類或者接口,借助于泛型,反射,控制反轉(zhuǎn)等高級(jí)技能能在一定程度上簡(jiǎn)化程序的編寫過程。此外,領(lǐng)域?qū)邮浅绦虻暮诵膬?nèi)容,因?yàn)槠渌麑哟味荚诤艽蟪潭壬弦蕾嘍omain層的設(shè)計(jì),如果這一層設(shè)計(jì)不夠完善會(huì)使以后的工作步履蹣跚.
服務(wù)層Service:這一層就是為領(lǐng)域?qū)ο筇峁┓?wù)用的,領(lǐng)域?qū)ο笠话悴恢苯雍捅憩F(xiàn)層,持久層直接打交道而是通過服務(wù)層進(jìn)行代理.服務(wù)層是UI層到持久層的中間通道,它處于上通界面下通持久層的中間環(huán)節(jié),這個(gè)特性是使的這一層決定了軟件功能的多少。
一般來說,UI層向服務(wù)層傳入的是用戶輸入的一些參數(shù),服務(wù)層進(jìn)行驗(yàn)證,重組后向下層DAO傳輸;而服務(wù)層從Dao層收到的是領(lǐng)域?qū)ο蠡蚱浼希騏I層返回的是領(lǐng)域?qū)ο蠡蛘咂浼系淖凅w或者直接是領(lǐng)域?qū)ο蠡蛘咂浼媳旧怼ervice諸類的實(shí)例在桌面程序和CS程序中一般作為Model的一個(gè)私有成員,而在Web程序中常常要用到時(shí)再創(chuàng)建出來。除領(lǐng)域?qū)油?其余各層是在圍繞它而設(shè)計(jì).
實(shí)用工具層Util:這一層相對(duì)簡(jiǎn)單,它包含了各種工具類,類中包含的主要是靜態(tài)函數(shù)和靜態(tài)成員變量,這些類對(duì)共通的函數(shù),變量進(jìn)行了歸納,它旨在消除重復(fù)代碼,降低主體代碼的復(fù)雜程度.一般此層中類的復(fù)用程度很高.值得通過項(xiàng)目積累.
持久層(Persistence layer)是直接與持久介質(zhì)打交道的層次,持久介質(zhì)可以是常見的關(guān)系型數(shù)據(jù)庫,文件甚至Web Service,它一般包含兩個(gè)部分。
數(shù)據(jù)存儲(chǔ)對(duì)象層(DAO層),sql語句一般寫在這層中, 然后由它調(diào)用;DAO層是最低的一層,與持久介質(zhì)直接打交道,它包含具體文件的位置,數(shù)據(jù)庫連接等;
另一個(gè)部分就是持久介質(zhì),通常是關(guān)系型數(shù)據(jù)庫。
Dao層中各個(gè)類一般作為Service的私有成員,供Service調(diào)用。
下圖是各層間的位置關(guān)系圖:

如何從需求中分析出諸個(gè)層次中的類呢,我們?cè)诖蟪叨壬峡梢园凑障旅娴牟襟E進(jìn)行:
Domain the first:首先從業(yè)務(wù)流和業(yè)務(wù)規(guī)則中歸納總結(jié)出領(lǐng)域?qū)ο?
Service the second:為領(lǐng)域?qū)ο笤O(shè)計(jì)服務(wù)類。
Persistence the third:持久層的負(fù)責(zé)領(lǐng)域?qū)ο蟪志没匠志媒橘|(zhì)以及逆過程,它的設(shè)計(jì)在領(lǐng)域?qū)雍头?wù)層之后,比較典型的持久層設(shè)計(jì)有數(shù)據(jù)庫表的設(shè)計(jì)和ER圖(實(shí)體關(guān)系圖)的繪制.
View the last:最后設(shè)計(jì)表現(xiàn)層,表現(xiàn)層受領(lǐng)域?qū)雍头?wù)層制約, 容易變化且易于修改,通常放在最后實(shí)現(xiàn).
具體步驟如下
1.理解,分析,鉆研需求,徹底了解你的客戶想要什么,需要你做些什么.
2.將大系統(tǒng)分解成一個(gè)個(gè)子系統(tǒng),細(xì)分出各個(gè)層次,搞清楚各層的任務(wù)。
3.分析業(yè)務(wù)邏輯,歸納出業(yè)務(wù)流.
4.從業(yè)務(wù)流和業(yè)務(wù)規(guī)則中總結(jié)出領(lǐng)域?qū)ο?
5.為領(lǐng)域?qū)訉?shí)現(xiàn)服務(wù)層.
6.以Domain層和Service層為核心設(shè)計(jì)表現(xiàn)層和持久層,直到形成完整的程序.
7.加入實(shí)用層消除重復(fù)代碼,梳理結(jié)構(gòu)和簡(jiǎn)化流程,.
8.限制跨層的調(diào)用.
軟件開發(fā)過程中,唯一不變的就是變化。這是一句老生常談,也就是說軟件開發(fā)中永恒的主題就是變化。當(dāng)你把代碼都寫好了,測(cè)試也完成了,準(zhǔn)備交付的時(shí)候客戶忽然要求你在指定時(shí)間做出變化,這種情況在外包行業(yè)中很常見;而對(duì)一些銀行金融項(xiàng)目,邊調(diào)研邊開發(fā)邊測(cè)試屢見不鮮;對(duì)于一些Web項(xiàng)目,從來就只有永遠(yuǎn)的Beta版,改來改去的事更是家常便飯。對(duì)此,程序員一定要求清晰的認(rèn)識(shí),抱怨只能是嘴上痛快,不解決實(shí)際問題。真要解決實(shí)際問題,非要?jiǎng)右环X筋不可,如果合理使用了設(shè)計(jì)模式,反射或是Spring的IoC,便能變修改噩夢(mèng)為一次有趣的智慧之旅。
首先我們看原始要求:客戶要求將一批雇員名單存入到CSV和XML兩種文件中去,以后還有可能增加別的文件格式,比如PDF,XLS等,雖然這是下一期的內(nèi)容,但這一期應(yīng)該考慮到變化,客戶要求擴(kuò)展性一定要好。
沒問題,有了設(shè)計(jì)模式響應(yīng)變化不難。這時(shí)我們可以用到模板方法模式:
定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。
先請(qǐng)看骨架抽象類:
- public abstract class FileMaker {
-
-
-
- private List<Employee> employees;
-
-
-
-
-
-
-
- public final void makeFile(List<Employee> employees,String fileName){
- setEmployees(employees);
- makeFile(fileName);
- }
-
-
-
-
-
- protected abstract void makeFile(String fileName);
-
- public final void setEmployees(List<Employee> employees) {
- this.employees = employees;
- }
-
- public List<Employee> getEmployees() {
- return employees;
- }
- }
很好,固定的函數(shù)和步驟都在抽象基類中寫定了,再看兩個(gè)具體實(shí)現(xiàn)類,它們要實(shí)現(xiàn)的就是makeFile函數(shù)而已。
- public class CSVFileMaker extends FileMaker{
- protected void makeFile(String fileName){
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
-
- for(Employee emp:getEmployees()){
- String line="";
- line+=emp.getName()+",";
- line+=(emp.isMale()?"男":"女")+",";
- line+=emp.getAge()+",";
-
- out.write(line+"\r\n");
- }
-
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- public class XMLFileMaker extends FileMaker{
- protected void makeFile(String fileName){
- try {
- Document document = DocumentHelper.createDocument();
- Element root = document.addElement("employees");
-
- for(Employee emp:getEmployees()){
- Element empElm=root.addElement("employee");
-
- Element nameElm=empElm.addElement("name");
- nameElm.setText(emp.getName());
-
- Element sexElm=empElm.addElement("sex");
- sexElm.setText(emp.isMale()?"男":"女");
-
- Element ageElm=empElm.addElement("age");
- ageElm.setText(String.valueOf(emp.getAge()));
- }
-
- OutputFormat format = OutputFormat.createPrettyPrint();
- format.setEncoding("GBK");
- XMLWriter writer = new XMLWriter(new FileWriter(fileName),format);
-
- writer.write(document);
- writer.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
這樣昨完以后感覺很好,因?yàn)槲覀兂晒Φ陌炎兓筒蛔兎蛛x開來,不變的部分放在了抽象基類中,而容易變化的部分放在了兩個(gè)具體的子類中,這樣如果再增加一種新文件格式,從抽象基類再擴(kuò)展出一個(gè)子類即可。很好,這樣就不怕變化了。客戶對(duì)此也沒有異議。
調(diào)用示例如下:
- List<Employee> emps=new ArrayList<Employee>();
- emps.add(new Employee("Andy",true,21));
- emps.add(new Employee("Bill",false,23));
- emps.add(new Employee("Cindy",true,25));
- emps.add(new Employee("Douglas",false,28));
-
- FileMaker fileMaker=new CSVFileMaker();
- fileMaker.makeFile(emps, "1.csv");
-
- fileMaker=new XMLFileMaker();
- fileMaker.makeFile(emps, "2.xml");
客戶看到了我們的調(diào)用的例子,覺得應(yīng)該更靈活一些,他說存成各種不同的文件是通過點(diǎn)擊按鈕來實(shí)現(xiàn)的,如果每個(gè)按鈕的事件處理函數(shù)都要生成具體子類豈不是太死板了嗎?這樣做每個(gè)文件下載按鈕的事件處理代碼不是都不一樣?
有點(diǎn)道理,如今理解到這一層的客戶實(shí)在是不多見了。不過很容易滿足他的需求,我們可以引入反射的方法:
- public static void main(String[] args) {
- List<Employee> emps=new ArrayList<Employee>();
- emps.add(new Employee("Andy",true,21));
- emps.add(new Employee("Bill",false,23));
- emps.add(new Employee("Cindy",true,25));
- emps.add(new Employee("Douglas",false,28));
-
- callByReflect("csv",emps,"1.csv");
- callByReflect("xml",emps,"2.xml");
- }
-
- public static void callByReflect(String type,List<Employee> emps,String fileName){
- try{
- Class cls=Class.forName("com.heyang."+type.toUpperCase()+"FileMaker");
- FileMaker fileMaker=(FileMaker)cls.newInstance();
- fileMaker.makeFile(emps, fileName);
- }
- catch(Exception ex){
- ex.printStackTrace();
- }
- }
因?yàn)榘粹o上的文字和類名是有關(guān)的,如下載CSV的按鈕上就有CSV的文字,這可以通過正則表達(dá)式取道,再組合一下不就是類名了嗎?csv到com.heyang.CSVFileMaker,xml到com.heyang.XMLFileMaker,其實(shí)變化就是三個(gè)字母而已。如果增加按鈕,取出按鈕中的三個(gè)字母再調(diào)用callByReflect函數(shù)即可,這個(gè)過程簡(jiǎn)直可以固化。
客戶看到反射方法以后很是滿意,沒有意見了。待客戶走后,項(xiàng)目經(jīng)理把你拉到一邊,說:
“你剛才的方法不錯(cuò),確實(shí)很強(qiáng),但看得懂反射并能靈活掌握的人水平要夠一年經(jīng)驗(yàn)才行,維護(hù)的活讓一年經(jīng)驗(yàn)的人去干太可惜了,最好改改,最好達(dá)到讓新手也能掌握并修改的程度。”。
沒辦法,領(lǐng)導(dǎo)總有領(lǐng)導(dǎo)的考慮,他這么說也很合理,成本問題我可以不考慮,但如果把程序搞得復(fù)雜貌似NB,能讓一些學(xué)藝不精的人產(chǎn)生云山霧罩的感覺,有時(shí)還能被人尊稱一聲“大俠”,但誰也不比誰傻多少,這聲大俠不是白叫的,但是出了問題或是有了變化別人還是要找你,到頭來還是給自己添亂,這些都是義務(wù)勞動(dòng),何苦來呢?還是應(yīng)該改得容易些,讓大家都能修改,我可不愿意半夜三更被人叫起來問問題。
用Spring的IoC就可以解決問題,寫一個(gè)新類并配置到XML文件中對(duì)新手來說問題不大,這下可以讓領(lǐng)導(dǎo)放心了,自己就更放心了。
IoC方案代碼如下:
- public class Main {
- public static void main(String[] args) {
- List<Employee> emps=new ArrayList<Employee>();
- emps.add(new Employee("Andy",true,21));
- emps.add(new Employee("Bill",false,23));
- emps.add(new Employee("Cindy",true,25));
- emps.add(new Employee("Douglas",false,28));
-
- callByIoc("csv",emps,"1.csv");
- callByIoc("xml",emps,"2.xml");
- }
-
- public static void callByIoc(String type,List<Employee> emps,String fileName){
- try{
- ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
- FileMaker fileMaker=(FileMaker)ctx.getBean(type);
- fileMaker.makeFile(emps, fileName);
- }
- catch(Exception ex){
- ex.printStackTrace();
- }
- }
- }
Bean。xml文件內(nèi)容很簡(jiǎn)單吧:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="csv" class="com.heyang.CSVFileMaker"/>
- <bean id="xml" class="com.heyang.XMLFileMaker"/>
- </beans>
好了。到這里問題就徹底結(jié)束了,終于滿足了客戶和上級(jí)的要求,可以回家睡個(gè)好覺了,不用擔(dān)心別人打攪了。
態(tài)度改變一切,變化來了人總是要多做一些,心理當(dāng)然是不愿意的,但抱怨或是消極抵制都不是解決問題之道;如果把它看做一個(gè)挑戰(zhàn)的契機(jī),凡事多思考一些,不但能解決問題,自己也會(huì)有所提高,這就是積極的態(tài)度帶來的好處。
摘要: 在工程中經(jīng)常有發(fā)送郵件的任務(wù),如果使用JavaMail來發(fā)送郵件,用到的代碼較多,過程和細(xì)節(jié)也相對(duì)復(fù)雜,而使用Spring的MailSender能相對(duì)簡(jiǎn)單方便些,這樣使程序員能更快捷的完成郵件發(fā)送任務(wù)。下面請(qǐng)看示例代碼:
注意在執(zhí)行代碼前,請(qǐng)確認(rèn)已經(jīng)將activation.jar,commons-logging-1.0.4.jar,mail.jar和spring.jar載入工程。...
閱讀全文
在Web開發(fā)中,文本郵件發(fā)送的任務(wù)比較常見,我們可以利用它進(jìn)行一些客戶通知和異常通知,文本郵件發(fā)送一般用到JavaMail API,下面是一個(gè)我有時(shí)用到的郵件發(fā)送實(shí)用工具類,把其中一些參數(shù)修改一下就能為你所用。
注意:在執(zhí)行代碼前,請(qǐng)把mail.jar和activation.jar載入工程。
代碼如下:
- package com.heyang;
-
- import java.util.Date;
- import java.util.Properties;
-
- import javax.mail.Address;
- import javax.mail.Message;
- import javax.mail.Session;
- import javax.mail.Transport;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeMessage;
-
-
-
-
-
-
- public final class MailUtil {
-
- private static final String SenderEmailAddr = "XXXXXXX@163.com";
-
-
- private static final String SMTPUserName = "XXXX";
-
-
- private static final String SMTPPassword = "XXXXXXX";
-
-
- private static final String SMTPServerName = "smtp.163.com";
-
-
- private static final String TransportType = "smtp";
-
-
- private static Properties props;
-
-
-
-
-
- private MailUtil() {
-
- }
-
-
-
-
- static {
- MailUtil.props = new Properties();
-
-
- MailUtil.props.put("mail.smtp.host", MailUtil.SMTPServerName);
-
- MailUtil.props.put("mail.smtp.auth", "true");
- }
-
-
-
-
-
-
-
- public static void sendMail(String emailAddr, String mailTitle,
- String mailConcept) {
-
- Session s = Session.getInstance(MailUtil.props, null);
-
-
- s.setDebug(false);
-
-
- Message message = new MimeMessage(s);
- try {
-
- Address from = new InternetAddress(MailUtil.SenderEmailAddr);
- message.setFrom(from);
-
-
- Address to = new InternetAddress(emailAddr);
- message.setRecipient(Message.RecipientType.TO, to);
-
-
- message.setSubject(mailTitle);
-
- message.setText(mailConcept);
-
- message.setSentDate(new Date());
-
- message.saveChanges();
-
- Transport transport = s.getTransport(MailUtil.TransportType);
-
- transport.connect(MailUtil.SMTPServerName, MailUtil.SMTPUserName,
- MailUtil.SMTPPassword);
-
-
- transport.sendMessage(message, message.getAllRecipients());
- transport.close();
-
- System.out.println("發(fā)送郵件,郵件地址:" + emailAddr + " 標(biāo)題:" + mailTitle
- + " 內(nèi)容:" + mailConcept + "成功!");
- } catch (Exception e) {
- System.out.println(e.getMessage());
- System.out.println("發(fā)送郵件,郵件地址:" + emailAddr + " 標(biāo)題:" + mailTitle
- + " 內(nèi)容:" + mailConcept + "失敗! 原因是" + e.getMessage());
- }
- }
-
-
-
-
-
- public static void main(String[] args){
- MailUtil.sendMail("XXXXXX@gmail.com", "title", "concept");
- }
- }
在面向?qū)ο缶幊讨校覀円话悴捎脧捻斚蛳碌木幊谭绞剑聪仍O(shè)計(jì)類的層次,如View,Controller,Service,Dao,Domain,Util等,再完善各層中的類。在這個(gè)過程中,我發(fā)現(xiàn)按功能和形態(tài)來分,系統(tǒng)中類可分為以下幾個(gè)類別:
1.實(shí)體類(Entity Classes):這種類一般是現(xiàn)實(shí)世界事物在代碼世界中的抽象表示,和現(xiàn)實(shí)事物有著一一對(duì)應(yīng)關(guān)系.存儲(chǔ)到持久介質(zhì)中時(shí)一般對(duì)應(yīng)著一條記錄.如MIS系統(tǒng)中常見的雇員類Employee,論壇系統(tǒng)中常見的Topic等.由于這些類可以直接從現(xiàn)實(shí)事物中歸納抽象得來,寫出它們的框架代碼一般相對(duì)方便容易,但要真正理順實(shí)體類之間的關(guān)系需要投入不少精力,這些類一般處于Domain層中.
2.通道類(Plumbing Classes):這種類一般用于充當(dāng)傳輸實(shí)體類的通道,在編程中,經(jīng)常需要從持久層取出一個(gè)或多個(gè)實(shí)體類的對(duì)象或是將實(shí)體類的對(duì)象存儲(chǔ)到持久層中,這種任務(wù)一般由通道類來完成.它們一般由Service或是Dao層中的類來承擔(dān).這些類一般不保存狀態(tài),對(duì)外界來說,它們的對(duì)外接口(Public Interface)一般比具體的實(shí)現(xiàn)重要,在數(shù)量較多時(shí),也經(jīng)常抽象出一些上層的抽象類或是接口出來以方便調(diào)用.
3.輔助類(Assistant Classes):這些類一般起輔助任務(wù),一般可以把共通的處理和變量放在其中供其他層次類調(diào)用,這樣做一能避免散彈式修改,二能減少重復(fù)代碼,三能提高代碼復(fù)用度.輔助類一般放在Util包中.
4.框架類(Framework Classes):這些類一般由固定的框架提供,程序員不能改變.在類的層次上它一般處于界面和業(yè)務(wù)層之間,即控制層的位置,jsp/servlet中的Servlet,Struts1,2中的Action都是這樣的類,它承擔(dān)了接受用戶輸入,并展示業(yè)務(wù)處理的結(jié)果的任務(wù).
一個(gè)技術(shù)人員要生存,要發(fā)展,要成一番事業(yè),必須遵循一定固定的法則,若逆天而行而不自覺,輕則徒勞無功,白費(fèi)精力;重則無法立足,庸碌一生。因此把握住自己的發(fā)展之道是技術(shù)人首要的大事,只有走在正確的道路上,前進(jìn)才有意義。
一個(gè)技術(shù)人員,首先要固本培元,什么是技術(shù)人的根本呢?無論語言,框架和技術(shù)如何發(fā)展,數(shù)據(jù)結(jié)構(gòu)和算法都是其核心內(nèi)容,所謂萬變不離其宗,有了良好的數(shù)據(jù)結(jié)構(gòu)和算法的根基,接受并掌握一個(gè)新興事物不過旬月時(shí)間,若沒有而盲目跟隨,事倍而功半矣。另外面向?qū)ο蟮木枰惨盐?從根本上來講,任何現(xiàn)代框架其核心思想還是沒有超越面向?qū)ο蟮姆懂?都是面向?qū)ο蟮睦^承和發(fā)展,理解掌握了面向?qū)ο蟮乃枷?就把握住了框架根本性的東西,學(xué)習(xí)掌握起來就更容易把握其本質(zhì).
其次,技術(shù)人員必須把握主流技術(shù)方向才不至于迷失自己。若在支流中迷失自己恐有空?qǐng)?zhí)屠龍之技無用武之地之憂,古代也許還能自娛自樂,現(xiàn)代社會(huì)這樣做溫飽都無法解決,房子,車子,孩子更是白扯;只有置身主流,才能繼續(xù)奮斗下去。當(dāng)前的主流技術(shù)方向,無非SSH(Struts1/2,Spring,Hibernate)而已,徹底弄清楚它們,才有安身立命之本.君不見諸多招聘廣告,均寫SSH乎.這三項(xiàng)其實(shí)也不好掌握,尤其Hibernate,掌握不精深也不行,有些大俠也曾陰溝里翻過船。
其三,技術(shù)人員要樂于善于總結(jié)提高,對(duì)于已經(jīng)掌握的內(nèi)容,要及時(shí)歸納總結(jié)到紙面上,這樣做一能梳理脈絡(luò),讓自己掌握得更全面細(xì)致;二能查漏補(bǔ)缺,發(fā)現(xiàn)以前忽視或是未接觸過的領(lǐng)域;三能求其友聲,放在博客上供大家分析閱讀討論,彌補(bǔ)自己的不足.有此三益,于己于人都是一件大好事,何樂而不為呢?
其四,技術(shù)人員要展示自己的能力和價(jià)值,應(yīng)該具備自己的產(chǎn)品,它可以用來鞏固和展現(xiàn)自己的實(shí)力,在產(chǎn)品的研發(fā)過程中,技術(shù)人員能把自己的知識(shí)智慧實(shí)用化,可避免走入象牙塔之患;外界也能通過產(chǎn)品來了解發(fā)掘自己.這也是一件于己于人都有利的事情.
其五,技術(shù)人員應(yīng)該具備完整的思想體系,有自己獨(dú)到的見解并能有所突破創(chuàng)新. 人云亦云無異于鸚鵡學(xué)舌,有何能哉? 要想上一個(gè)層次,必須鯉魚躍龍門. Gosing和Kaven兩人可作為最好的榜樣。
最后,廣博的知識(shí)不可少.拘泥于一處難免死鉆牛角尖,很多情況下?lián)Q一種思維頓時(shí)有撥云見日之感,如有閑暇,技術(shù)人員應(yīng)該跳出圈子,廣采能用之材為我所用.
摘要: 稱球問題經(jīng)常是面試中的常客,這里我用做了一個(gè)稱球的程序,主要的方法就是遞歸和掃描,貼出來請(qǐng)大家指正。
閱讀全文
摘要: /** *//**
* 二叉樹節(jié)點(diǎn)類
* @author HEYANG
* @since 2008-7-26 下午02:59:06
*/
class Node<T extends Comparable> {
 ...
閱讀全文
摘要: 這是一個(gè)美國IT企業(yè)的面試題,原題大意是從一個(gè)文件中讀取出可連通的城市對(duì),給出兩個(gè)城市,判斷是否可連通,如果可連通就輸出yes,不可連通就輸出no,否則給出命令行幫助。
其實(shí)判斷連接狀態(tài)不用遍歷圖,用蔓延法即可,具體做法就是從起始城市開始,依次改變其周邊連通城市的連通狀態(tài),再從周邊開始向周邊連通城市蔓延,如果能蔓延到結(jié)束城市的周邊可連通城市,則說明兩個(gè)城市是完全可連通的。這種做法和多米諾骨牌效應(yīng)很像。我姑且稱之為蔓延法。
閱讀全文
找出以下字符串=符號(hào)后面對(duì)應(yīng)的屬性值

"職務(wù)=GM 薪水=50000 , 姓名=職業(yè)經(jīng)理人 ; 性別=男 年齡=45 ";

import java.util.regex.Matcher;
import java.util.regex.Pattern;


/** *//**
* 用正則表達(dá)式找出每個(gè)屬性對(duì)應(yīng)的值
* @author HEYANG
* @since 2008-7-23 下午08:12:45
*/

public class RegexFindProperty
{


public static void main(String[] args)
{
String input = "職務(wù)=GM 薪水=50000 , 姓名=職業(yè)經(jīng)理人 ; 性別=男 年齡=45 ";
// =號(hào)和空白符之間是非空格字符,這種寫法比去分開組合字母,數(shù)字和漢字的方式要快捷
Pattern pattern = Pattern.compile("=(\\S+)\\s*");

// 用Pattern類的matcher()方法生成一個(gè)Matcher對(duì)象
Matcher m = pattern.matcher(input);

// 使用find()方法查找第一個(gè)匹配的對(duì)象
boolean result = m.find();

// 使用循環(huán)找出模式匹配的內(nèi)容打印

while (result)
{
// 取得匹配的結(jié)果
String replaceStr = m.group(1);
System.out.println("匹配的屬性等于=" + replaceStr);
result = m.find();
}
}
}
摘要: package com.sitinspring.datetime;
import java.util.ArrayList;
import java.util.List;
public class MonthlyCalendar{
private static f...
閱讀全文
摘要: 輸出示例:
當(dāng)前日期時(shí)間為:2008.07.18 10:48:57
當(dāng)前日期為:2008.07.18
當(dāng)前日期為:2008.7.18
當(dāng)前時(shí)間為:10:48:57
2008.07.05與2008.07.18之間相隔:13天
當(dāng)前年月為:2008.07
本月第一天為周2
本月有31天
閱讀全文
sitinspring(http://m.tkk7.com)原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處.