<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    程序之外

    難得有空,寫(xiě)篇程序之外的文章,關(guān)于壓力的,也是自己近來(lái)的親身體會(huì)。

    眾所周知軟件這行壓力是很大的。各種各樣的問(wèn)題層出不窮,每天上班工作內(nèi)容都是排的滿(mǎn)滿(mǎn)的,遇到突發(fā)問(wèn)題就得加班。如果不及時(shí)進(jìn)行疏解,積累到一定的程度,就可能產(chǎn)生一定的負(fù)面問(wèn)題,比如上班精神狀態(tài)差、注意力不能集中、遇事喜歡逃避等等。我就親身經(jīng)歷了這樣的狀況,明知自己工作積極性差、效率很低,但也很難一下子找回自我。

    一次偶然的出游讓我從中很快走了出來(lái)。一個(gè)親戚考上廈大的博士,我請(qǐng)了 2 天的假,利用周末時(shí)間順便去廈門(mén)旅游。廈門(mén)依山傍海,的確是旅游的好去處。晚上到海邊,涼風(fēng)習(xí)習(xí),光腳沿著沙灘走過(guò),任起落的潮水在腿上腳上留下層層薄沙。內(nèi)心也變得平靜,能夠感受到海的呼吸。天地間仿佛只剩下我和大海,在進(jìn)行心靈的交流,俗世煩擾皆?huà)佒T腦后,只剩下對(duì)海的依戀。白天去爬南普陀山,并不太高,慢慢爬到山頂,整個(gè)思明區(qū)盡收眼底,遠(yuǎn)處一艘快艇在海面掠過(guò),留下一條美麗的浪花。然后順山而下到植物園,途徑無(wú)數(shù)奇花異草、層天老樹(shù),走得累了,找個(gè)湖邊石凳休息一下,人也覺(jué)得輕松愉快。

    經(jīng)過(guò)大自然的洗禮,回到單位,人的精神面貌煥然一新,抱著積極的心態(tài)處理事情,很多問(wèn)題迎刃而解。壓力測(cè)試做的很累,經(jīng)常要熬夜,但通過(guò)一輪輪的測(cè)試,逐步定位到性能問(wèn)題所在,自己也學(xué)了不少相關(guān)知識(shí),想想也就沒(méi)那么煩了。

    做事的方式,也有了長(zhǎng)進(jìn)。我現(xiàn)在信奉人一時(shí)只做一件事效率最高的原則。事情再多,也是一件件做,每天安排好近日的工作,并排個(gè)優(yōu)先級(jí),什么是要親自處理的,什么是讓別人處理的,什么是需要預(yù)先通知他人的,需要什么資源,每件事情的預(yù)計(jì)時(shí)間如何,需要如何 check 等等。做好一件事就打個(gè)勾,做到心中有數(shù)。如果事情有延誤,分析是什么原因,該如何補(bǔ)救,而不要有太大的心理負(fù)擔(dān),自己盡力了就好,是自己的責(zé)任就要勇敢扛下,死不了人的。這其實(shí)是很簡(jiǎn)單的原則,誰(shuí)都能夠?qū)W會(huì),但的確很管用。

    總結(jié):壓力是無(wú)處不在的,關(guān)鍵在于如何應(yīng)對(duì)和排解。用積極的心態(tài)和恰當(dāng)?shù)姆椒鎸?duì),壓力也就沒(méi)那么大了。感覺(jué)壓力積累到一定程度,在還未影響正常工作之前就先想辦法排解,出去旅游、運(yùn)動(dòng)等都是緩解壓力的好辦法。

    posted @ 2006-11-06 22:27 pesome 閱讀(1169) | 評(píng)論 (2)編輯 收藏

    關(guān)于代碼的一些比喻

    最近對(duì)項(xiàng)目組的一些較差的代碼進(jìn)行了些重構(gòu),同時(shí)靈光一閃,對(duì)代碼有些比較形象的比喻。

    壞的代碼就象揉面團(tuán),管什么接口什么實(shí)現(xiàn)全揉成一團(tuán),一個(gè)方法幾百行,注釋寫(xiě)再多也是面團(tuán)(夾了些小紙條而已)。然后需要重用了,就是從中抓起一把面團(tuán),然后放到其它的面團(tuán)里繼續(xù)揉。這樣重復(fù)代碼一堆,什么易讀性、擴(kuò)展性、可維護(hù)性都是無(wú)從談起。

    好的代碼就象堆積木,接口實(shí)現(xiàn)定義清清楚楚,每個(gè)接口只做一件事情,重復(fù)代碼都是通過(guò)更細(xì)的接口來(lái)消除。重用就是把積木塊往該放的地方堆,這樣的代碼,幾個(gè)大塊幾個(gè)小塊一目了然,只要方法命名規(guī)范,連注釋都可以省去。這樣耦合性低,易讀性、擴(kuò)展性、可維護(hù)性都可以得到保證。

    把面團(tuán)變成積木并不復(fù)雜,定義好模具,面團(tuán)一團(tuán)團(tuán)往里面填充,待穩(wěn)定下來(lái),就成了一塊塊積木。這里關(guān)鍵就是模具的制作,推薦制作寶典: martin fowler 的那本重構(gòu)。還得有模具的丈量工具,就非 junit 莫屬了。

    posted @ 2006-10-30 17:42 pesome 閱讀(1473) | 評(píng)論 (0)編輯 收藏

    數(shù)據(jù)庫(kù)同步trigger的記錄

    ??? 項(xiàng)目需要寫(xiě)了幾個(gè)數(shù)據(jù)庫(kù)同步用的 trigger ,就是記錄用戶(hù)的操作到一個(gè) temp 表,然后每天通過(guò) webservice 同步到其它系統(tǒng),同步成功清空該 temp 表。自認(rèn)為寫(xiě)的還行,做個(gè)記錄。是 db2 的。

    ?

    -- 用戶(hù)組新增觸發(fā)器

    --DROP TRIGGER TG_USERG;

    CREATE TRIGGER LIBING.TG_USERG AFTER INSERT ON LIBING.TM_USERG

    ? REFERENCING NEW AS NROW

    ? FOR EACH ROW

    ? MODE DB2SQL??

    ? BEGIN ATOMIC

    ?

    ? declare @groupId integer;

    ? declare @name varchar(30);

    ? declare @descn varchar(100);

    ? declare @syntype varchar(4);

    ? declare @ddlsql varchar(1024);

    ? declare @isprimary char(1);

    ? declare @updateTime timestamp;

    ? declare @createTime timestamp;

    ? declare @createBy integer;

    ? declare @updateBy integer;

    ? declare @groupType integer;

    ? declare @adminType integer;

    ? declare @appId integer;

    ?

    ? declare @oldGroupId integer;

    ?

    ? set @groupId=NROW.GROUP_ID;

    ? set @name=NROW.name;

    ? set @descn=NROW.descn;

    ? set @syntype=NROW.syn_type;

    ? set @ddlsql=NROW.ddlsql;

    ? set @isprimary=NROW.isprimary;

    ? set @updateTime=NROW.update_time;

    ? set @createTime=NROW.create_time;

    ? set @createBy=NROW.create_by;

    ? set @updateBy=NROW.update_by;

    ? set @groupType=NROW.group_type;

    ? set @adminType=NROW.admin_type;

    ? set @appId=NROW.app_id;

    ?

    ? INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ?CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ?@ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'INSERT');

    ? END;

    ?

    ? -- 更新用戶(hù)組數(shù)據(jù)的觸發(fā)器

    ?-- DROP TRIGGER TG_USERG_UPDATE;

    ? CREATE TRIGGER TG_USERG_UPDATE AFTER UPDATE ON TM_USERG

    ? ?????????? ?REFERENCING NEW AS NROW

    ????????????? ?FOR EACH ROW

    ????????????? ?MODE DB2SQL

    ????????????? ?BEGIN ATOMIC

    ????????????? ?

    ????????????? ?declare @groupId integer;

    ? ?????????? ?declare @name varchar(30);

    ? ?????????? ?declare @descn varchar(100);

    ? ?????????? ?declare @syntype varchar(4);

    ? ?????????? ?declare @ddlsql varchar(1024);

    ? ?????????? ?declare @isprimary char(1);

    ? ?????????? ?declare @updateTime timestamp;

    ? ?????????? ?declare @createTime timestamp;

    ? ?????????? ?declare @createBy integer;

    ? ?????????? ?declare @updateBy integer;

    ? ?????????? ?declare @groupType integer;

    ? ?????????? ?declare @adminType integer;

    ? ?????????? ?declare @appId integer;

    ????????????? ?

    ????????????? ?set @groupId=NROW.GROUP_ID;

    ? ?????????? ?set @name=NROW.name;

    ? ?????????? ?set @descn=NROW.descn;

    ? ?????????? ?set @syntype=NROW.syn_type;

    ? ?????????? ?set @ddlsql=NROW.ddlsql;

    ? ?????????? ?set @isprimary=NROW.isprimary;

    ? ?????????? ?set @updateTime=NROW.update_time;

    ? ?????????? ?set @createTime=NROW.create_time;

    ? ?????????? ?set @createBy=NROW.create_by;

    ? ?????????? ?set @updateBy=NROW.update_by;

    ? ?????????? ?set @groupType=NROW.group_type;

    ? ?????????? ?set @adminType=NROW.admin_type;

    ? ?????????? ?set @appId=NROW.app_id;

    ????????????? ?

    ????????????? ?-- 如果已經(jīng)有 update 則只記錄最后一條 update

    ????????????? ?IF EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId AND ACTION='UPDATE') THEN

    ????????????? ? ???? UPDATE TM_USERG_TEMP SET GROUP_ID=@groupId,

    ????????????? ? ???? ? ??????????? NAME=@name,DESCN=@descn,DDLSQL=@ddlsql,

    ?????????????????????????????????? ISPRIMARY=@isprimary,UPDATE_TIME=@updateTime,

    ?????????????????????????????????? CREATE_TIME=@createTime,CREATE_BY=@createBy,

    ?????????????????????????????????? UPDATE_BY=@updateBy,GROUP_TYPE=@groupType,

    ?????????????????????????????????? ADMIN_TYPE=@adminType,APP_ID=@appId,ACTION='UPDATE'

    ?????????????????????????????????? where GROUP_ID=@groupId AND ACTION='UPDATE';

    ????????????? ?-- 如果有 insert 則把后面的 update 當(dāng)作 insert

    ????????????? ELSEIF? EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId AND ACTION='INSERT') THEN

    ???????????????????? UPDATE TM_USERG_TEMP SET GROUP_ID=@groupId,

    ????????????? ? ???? ? ??????????? NAME=@name,DESCN=@descn,DDLSQL=@ddlsql,

    ?????????????????????????????????? ISPRIMARY=@isprimary,UPDATE_TIME=@updateTime,

    ?????????????????????????????????? CREATE_TIME=@createTime,CREATE_BY=@createBy,

    ?????????????????????????????????? UPDATE_BY=@updateBy,GROUP_TYPE=@groupType,

    ?????????????????????????????????? ADMIN_TYPE=@adminType,APP_ID=@appId,ACTION='INSERT'

    ?????????????????????????????????? where GROUP_ID=@groupId AND ACTION='INSERT';

    ????????????? ELSE????? INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ? ??????????? ???CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ? ??????????? ?? @ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'UPDATE');

    ????????????? end if;

    ????????????? ?END;??????????

    ?

    ?

    -- 刪除用戶(hù)組觸發(fā)器

    --DROP TRIGGER TG_USERG_DELETE;

    CREATE TRIGGER TG_USERG_DELETE AFTER DELETE ON TM_USERG

    ?????? ? REFERENCING OLD AS OROW

    ?????? ? FOR EACH ROW

    ?????? ? MODE DB2SQL

    ?????? ? BEGIN ATOMIC

    ?????? ?

    ?????? ? declare @groupId integer;

    ? ??? ??declare @name varchar(30);

    ? ??? ??declare @descn varchar(100);

    ? ??? ??declare @syntype varchar(4);

    ? ??? ??declare @ddlsql varchar(1024);

    ? ??? ??declare @isprimary char(1);

    ? ??? ??declare @updateTime timestamp;

    ? ??? ??declare @createTime timestamp;

    ? ??? ??declare @createBy integer;

    ? ??? ??declare @updateBy integer;

    ? ??? ??declare @groupType integer;

    ? ??? ??declare @adminType integer;

    ? ??? ??declare @appId integer;

    ????????????? ?

    ?????? ? set @groupId=OROW.GROUP_ID;

    ? ??? ??set @name=OROW.name;

    ? ??? ??set @descn=OROW.descn;

    ? ??? ??set @syntype=OROW.syn_type;

    ? ??? ??set @ddlsql=OROW.ddlsql;

    ? ??? ??set @isprimary=OROW.isprimary;

    ? ??? ??set @updateTime=OROW.update_time;

    ? ??? ??set @createTime=OROW.create_time;

    ? ??? ??set @createBy=OROW.create_by;

    ? ??? ??set @updateBy=OROW.update_by;

    ? ??? ??set @groupType=OROW.group_type;

    ? ??? ??set @adminType=OROW.admin_type;

    ? ??? ??set @appId=OROW.app_id;

    ?????? ?

    ?????? ?? -- 如果沒(méi)有操作記錄,則插入 delete 記錄

    ?????? ?? IF NOT EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId) THEN

    ?????? ?? ? ??INSERT INTO TM_USERG_TEMP(GROUP_ID,NAME,DESCN,DDLSQL,ISPRIMARY,UPDATE_TIME,CREATE_TIME,

    ? ?????????? ?CREATE_BY,UPDATE_BY,GROUP_TYPE,ADMIN_TYPE,APP_ID,ACTION) VALUES (@groupId,@name,@descn,

    ????????????? ?@ddlsql,@isprimary,@updateTime,@createTime,@createBy,@updateBy,@groupType,@adminType,@appId,'DELETE');

    ????????????? ?

    ????????????? ?-- 如果有 insert 記錄,則整體結(jié)果相當(dāng)于沒(méi)有進(jìn)行任何操作

    ????????????? ?ELSEIF EXISTS(SELECT GROUP_ID FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId and ACTION='INSERT') THEN

    ????????????? ? ??????????? DELETE FROM TM_USERG_TEMP WHERE GROUP_ID=@groupId and ACTION='INSERT';

    ????????????? ?-- 如果沒(méi)有 insert 記錄,則只需記錄最后的 delete 操作

    ????????????? ?ELSE

    ????????????? ? ???? ? UPDATE TM_USERG_TEMP set ACTION='DELETE' where GROUP_ID=@groupId;

    ?????? ?? END IF;

    ?????? ??

    ?????? ?? END;

    posted @ 2006-10-30 17:06 pesome 閱讀(1412) | 評(píng)論 (0)編輯 收藏

    關(guān)于重用

    在項(xiàng)目中碰到一些重用上的問(wèn)題,有些想法,就先寫(xiě)一點(diǎn)。

    重用應(yīng)該是高層的復(fù)用,邏輯的復(fù)用,接口的復(fù)用,而不是具體實(shí)現(xiàn)的復(fù)用。 我們項(xiàng)目開(kāi)始講復(fù)用,就是大家把別人的代碼拿過(guò)來(lái),可用的地方就用,不同的地方改改,結(jié)果問(wèn)題一堆。說(shuō)到底就是接口沒(méi)有定義清楚的,很多該復(fù)用的邏輯隱藏在了具體的實(shí)現(xiàn)中。這樣導(dǎo)致無(wú)法進(jìn)行接口的復(fù)用,轉(zhuǎn)而使用具體的實(shí)現(xiàn)復(fù)用。從程序員的角度看,他們總會(huì)使用成本最小的方法完成任務(wù)。所以我們要時(shí)刻思考如何能讓最正確的方法在他們看來(lái)同時(shí)也是成本最小。

    這里有一個(gè)較為簡(jiǎn)單的辦法,就是盡量使用方法封裝實(shí)現(xiàn),使接口的粒度最小。如果一個(gè)實(shí)現(xiàn)需要幾百行,且其中包含多個(gè)邏輯,就最好抽取出多個(gè)方法,然后在主體接口內(nèi)進(jìn)行調(diào)用。這樣的代碼邏輯清晰易讀,可重用性也高。看看大師們對(duì)代碼的不斷重構(gòu),很大程度上就是重構(gòu)出粒度最細(xì),復(fù)用性最高的接口。

    如何達(dá)到最大程度的復(fù)用,其實(shí)是非常復(fù)雜的問(wèn)題,還需要在今后的項(xiàng)目中不斷體會(huì)。

    posted @ 2006-10-15 23:13 pesome 閱讀(481) | 評(píng)論 (0)編輯 收藏

    最近做壓力測(cè)試的總結(jié)

    最近做 portal 的壓力測(cè)試,一個(gè)字“累”。其中犯了不少錯(cuò)誤,白白加了幾天班,也有一些體會(huì),就記錄下來(lái),希望對(duì)大家有所幫助。

    首先講壓力測(cè)試環(huán)境。這個(gè)很是關(guān)鍵,我們就是在這個(gè)上面吃了苦頭。我們用的 loadrunner ,原理也很簡(jiǎn)單,一臺(tái)主控機(jī),控制多臺(tái)客戶(hù)機(jī),模擬并發(fā)用戶(hù)訪問(wèn)應(yīng)用。然后需要能實(shí)時(shí)監(jiān)控各相關(guān)應(yīng)用服務(wù)器, ldap 服務(wù)器等的性能。這里每臺(tái)客戶(hù)機(jī)最好能使用同樣的配置,使用足夠帶寬的網(wǎng)絡(luò),給予同樣的負(fù)載(模擬同樣數(shù)量的用戶(hù))。同時(shí)要注意監(jiān)控客戶(hù)機(jī)的 cpu 和網(wǎng)絡(luò)狀況,時(shí)刻保證 cpu 和網(wǎng)絡(luò)利用率低于 100% 。我們犯的很大錯(cuò)誤就是使用各自的筆記本,而且都使用的是一個(gè) 10M hub 牽出的網(wǎng)線(xiàn),這樣導(dǎo)致實(shí)際的網(wǎng)絡(luò)阻塞,既沒(méi)有給予服務(wù)器足夠的負(fù)載,又導(dǎo)致報(bào)告的響應(yīng)時(shí)間比實(shí)際更長(zhǎng),從而帶來(lái)了后續(xù)很多的無(wú)用測(cè)試。

    然后講測(cè)試方法。用的較多的還是持續(xù)壓力測(cè)試,就是持續(xù)給予服務(wù)器一段時(shí)間的并發(fā)量(一般為 5 10 分鐘),然后看平均響應(yīng)時(shí)間是否在可以接受的范圍內(nèi)。這個(gè)“可接受”要視應(yīng)用類(lèi)型和實(shí)際的并發(fā)用戶(hù)而定,如何估計(jì)并發(fā)就要靠經(jīng)驗(yàn)了。對(duì)于 portal 而言,由于要與眾多的應(yīng)用接口,如進(jìn)行 SSO ,獲取數(shù)據(jù)等,有很大程度也依賴(lài)于其它應(yīng)用的性能,其性能要求不會(huì)太高。我們測(cè)試首頁(yè)的性能,在放上全部的 portlet 的情況下, 100 個(gè)并發(fā)的平均響應(yīng)時(shí)間就在 17s 左右,這肯定是不能接受的( 10s 只能算勉強(qiáng)可以)。接下來(lái)就是發(fā)現(xiàn)性能瓶頸,并嘗試進(jìn)行優(yōu)化了。

    初步的發(fā)現(xiàn)瓶頸的方法也很簡(jiǎn)單,通過(guò)對(duì) portlet 的增減,發(fā)現(xiàn)最影響性能的 portlet ,然后不斷優(yōu)化,直至達(dá)到可以接受范圍。發(fā)現(xiàn)瓶頸所在了,就得進(jìn)一步確定是什么原因:是我們本身程序的問(wèn)題,還是其它應(yīng)用接口性能不佳等等。這里光靠猜是不行的,要講數(shù)據(jù)講事實(shí),記錄時(shí)間日志就是簡(jiǎn)單有效的辦法,我們對(duì)各個(gè)時(shí)間點(diǎn)打印了日志,比如 doview 方法的全部執(zhí)行時(shí)間, jsp 的載入時(shí)間,具體接口的執(zhí)行時(shí)間等。有些接口可能在壓力較小的情況下性能不錯(cuò),而在大壓力情況下出現(xiàn)性能隱患,所以一定要在進(jìn)行壓力測(cè)試后查看日志。我們就是這樣發(fā)現(xiàn)了性能隱患,同時(shí)更進(jìn)一步對(duì)各方面進(jìn)行優(yōu)化,直至達(dá)到客戶(hù)可以接受為止。

    由于不是專(zhuān)門(mén)的測(cè)試人員,很多地方都是實(shí)際項(xiàng)目中的體會(huì),也沒(méi)什么理論基礎(chǔ)。有什么不對(duì)的地方,大家多交流。

    posted @ 2006-10-15 23:13 pesome 閱讀(2517) | 評(píng)論 (1)編輯 收藏

    項(xiàng)目應(yīng)該提倡的一些做法

    接著昨天的寫(xiě)。今天寫(xiě)我認(rèn)為的一個(gè) javaEE 項(xiàng)目中應(yīng)該提倡的做法。

    1.?????? 開(kāi)發(fā)流程盡量簡(jiǎn)化,采用迭代增量的模式,做適合項(xiàng)目需要的文檔。很多時(shí)候千言不如一圖,原型開(kāi)發(fā)我認(rèn)為也非常重要。

    2.?????? 采用成熟的框架, ssh 組合或更多 full-stack 的框架如 seam 等都是不錯(cuò)的選擇。如果一定要用公司的框架,至少 SA 要非常熟悉這個(gè)框架,在出現(xiàn)問(wèn)題時(shí)要能快速的解決。

    3.?????? 對(duì)業(yè)務(wù)的分析做到越細(xì)越好,如果有條件讓更多的開(kāi)發(fā)人員參與業(yè)務(wù)的分析,同時(shí)形成項(xiàng)目通用的業(yè)務(wù)語(yǔ)言(實(shí)在不行,精簡(jiǎn)的 user story 也可以)。對(duì)于每個(gè)達(dá)成共識(shí)的業(yè)務(wù)都要能記錄下來(lái),并能方便的進(jìn)行查閱。業(yè)務(wù)模型和業(yè)務(wù)規(guī)則要始終與當(dāng)前需求、代碼和數(shù)據(jù)庫(kù)保持一致。

    4.?????? 在團(tuán)隊(duì)的建設(shè)上,需要更多的投入。不要為了節(jié)約成本,讓很多程序員老后面才加入團(tuán)隊(duì)。一個(gè)穩(wěn)定、團(tuán)結(jié)、有沖勁的團(tuán)隊(duì)能比松散而人數(shù)更多的團(tuán)隊(duì),完成的更快更好。然后要加強(qiáng)溝通,比如每天開(kāi)個(gè)小的茶話(huà)會(huì),大家交流下各自的工作情況,有什么困惑和疑難,提出來(lái)大家一起解決,避免大家各自做相同的邏輯(很多東西經(jīng)過(guò)抽象可能就是一個(gè))。在工作之余大家一塊吃吃飯,打打游戲等都是增進(jìn)感情的好方法,大家彼此熟悉了,工作上也能更好的協(xié)作。

    5.?????? 對(duì)程序員要有更高的要求, SA 有責(zé)任讓程序員了解更多的東西,如面向?qū)ο蟮?/span> 5 大原則、一些模式、 junit 、重構(gòu)等,這些其實(shí)并不是什么高深的東西,僅僅是掌握一些方面也能對(duì)代碼質(zhì)量和開(kāi)發(fā)中的愉悅度產(chǎn)生很大促進(jìn)。要激發(fā)他們對(duì)技術(shù)的熱愛(ài)和對(duì)代碼質(zhì)量的追求,因?yàn)樽罱K受益的還是他們。 XP 所提倡的結(jié)對(duì)編程也是快速進(jìn)行知識(shí)傳遞的好辦法。

    6.?????? 采用 wiki 進(jìn)行項(xiàng)目進(jìn)度跟蹤和一些文檔的展示。這次用 excel+cvs 的方式感覺(jué)很是麻煩,在 spring 翻譯中我們采用 wiki 的方式就感覺(jué)很好。

    暫時(shí)先想到這么多,有更多體會(huì),再來(lái)補(bǔ)充!

    posted @ 2006-09-21 15:59 pesome 閱讀(1024) | 評(píng)論 (2)編輯 收藏

    用Maven做項(xiàng)目管理

         摘要: 在程序員發(fā)表的一篇maven文章,跟大家共享。用 Maven 做項(xiàng)目管理 在 Java世界中我們很多的開(kāi)發(fā)人員選擇用 Ant來(lái)構(gòu)建項(xiàng)目,一個(gè) build.xml能夠完成編譯、測(cè)試、打包、部署等很多任務(wù),但我們...  閱讀全文

    posted @ 2006-09-21 11:37 pesome 閱讀(18689) | 評(píng)論 (10)編輯 收藏

    從錯(cuò)誤中學(xué)到更多

    開(kāi)發(fā)進(jìn)行到尾聲了,但 bug 仍然層出不窮。總的來(lái)說(shuō),算是一個(gè)比較失敗的項(xiàng)目,原因很多,有外在因素也有我作為一個(gè) SA 不可推卸的責(zé)任。正好借加班的時(shí)間寫(xiě)點(diǎn)總結(jié),也算是在失敗總吸取教訓(xùn),從錯(cuò)誤中感受更多吧。

    首先是開(kāi)發(fā)流程。我是 xp 的堅(jiān)定支持者,但在項(xiàng)目中由于外界原因還是采用了傳統(tǒng)的開(kāi)發(fā)流程,沒(méi)有迭代,就是需求 -> 設(shè)計(jì) -> 程序員進(jìn)場(chǎng)開(kāi)發(fā) -> bug 。由于程序員進(jìn)場(chǎng)時(shí)間較晚,一上來(lái)就開(kāi)始開(kāi)發(fā),沒(méi)有時(shí)間進(jìn)行培訓(xùn)和團(tuán)隊(duì)的融合。然后開(kāi)發(fā)中缺少溝通,就是一個(gè)人負(fù)責(zé)一塊,開(kāi)發(fā)完了再做其它。結(jié)果開(kāi)發(fā)到現(xiàn)在,還有人不清楚我們項(xiàng)目的全貌,到底是為了解決什么業(yè)務(wù)。

    然后是開(kāi)發(fā)框架。使用了公司的框架,而我們作為 SA (我們是雙 SA ),都是第一次接觸,程序員也就一個(gè)人用過(guò)。我們最早是達(dá)成共識(shí)采用 SSH 的組合(我至少還算是了解吧,其它人也都用過(guò)),但由于上層因素沒(méi)有實(shí)施(這也導(dǎo)致我好長(zhǎng)一段時(shí)間進(jìn)入不了狀態(tài))。開(kāi)發(fā)前期大家都在探索這個(gè)框架(的確很難用,出錯(cuò)機(jī)制較差,配置文件很多,耦合較強(qiáng) ... ),在一堆莫名奇妙的問(wèn)題中摸索前行,花費(fèi)大量的精力。而比較搞笑的是,在大家開(kāi)始學(xué)習(xí)這個(gè)框架之時(shí),我作為 SA ,因?yàn)橐獙?xiě)一堆只為應(yīng)付客戶(hù)的設(shè)計(jì)文檔(后面就沒(méi)人看過(guò)),錯(cuò)過(guò)了和大家共同進(jìn)步的機(jī)會(huì),后面總是感覺(jué)“低人一等”。

    在業(yè)務(wù)方面也存在很多問(wèn)題。很多業(yè)務(wù)邏輯并沒(méi)有以很好的載體保存下來(lái),在需求文檔中很多邏輯并沒(méi)有體現(xiàn)。我維護(hù)了一套 pd 的業(yè)務(wù)模型,從概念模型 -> 物理模型 -> 數(shù)據(jù)庫(kù),這解決了后面的一些溝通問(wèn)題,但由于更多體現(xiàn)的是靜態(tài)的實(shí)體及關(guān)聯(lián),對(duì)于一些動(dòng)態(tài)的業(yè)務(wù)流程沒(méi)法體現(xiàn)。我們 SA 之間有時(shí)在一些問(wèn)題上的理解還存在分歧(討論過(guò)也達(dá)成過(guò)共識(shí),但沒(méi)有記錄下來(lái),后面可能就忘了),程序員就更是無(wú)所適從。談到這,我更感受到 DDD 這本書(shū)的價(jià)值,他所提倡的開(kāi)發(fā)人員參加模型的討論,形成項(xiàng)目的模型語(yǔ)言,并不斷隨著業(yè)務(wù)進(jìn)行演化。。。好多理念都是項(xiàng)目經(jīng)驗(yàn)的結(jié)晶啊。

    在開(kāi)發(fā)管理上我也是無(wú)所作為。 Junit 都沒(méi)有推廣下去,更別說(shuō) TDD 了,這也與框架相關(guān),它就沒(méi)提供寫(xiě) test case 的地方,等我搞明白一堆配置文件,做出脫離 web 容器的 test 框架,都開(kāi)發(fā)一大半了,說(shuō)起 test 的好處,大家也表示不理解(或者表示理解但沒(méi)時(shí)間 = 沒(méi)理解),就讓他們慢慢 debug 吧!代碼的質(zhì)量也沒(méi)有保證,程序員不明白代碼的味道,更別說(shuō)理解重構(gòu)的意義以及進(jìn)行恰當(dāng)?shù)闹貥?gòu)了。一個(gè)函數(shù)寫(xiě)上 100 多行,什么邏輯都混在一塊,但由于時(shí)間較緊,我也只好睜一只眼閉一只眼“功能完成就行吧!也不是我一個(gè)人在管”,到現(xiàn)在很多代碼混成一團(tuán),展現(xiàn)層直接調(diào)用 dao (又是框架惹得禍),相同的邏輯 copy n 處,我也是后悔莫及。

    今天先寫(xiě)失誤,明天寫(xiě)從中學(xué)到的東西,從錯(cuò)誤中學(xué)到的也許更多!

    posted @ 2006-09-20 21:24 pesome 閱讀(890) | 評(píng)論 (1)編輯 收藏

    對(duì)領(lǐng)域模型的認(rèn)識(shí)

    最近看了看領(lǐng)域模型驅(qū)動(dòng)這本書(shū),只看了前面幾章,但也深切的感受到了模型的重要性。通過(guò)與代碼同步的模型,能夠維護(hù)一個(gè)很好的知識(shí)共享的空間,包括設(shè)計(jì)者與程序員之間,客戶(hù)與設(shè)計(jì)者之間 …… 而且模型應(yīng)該盡可能簡(jiǎn)單,讓不同背景的人都能夠很快學(xué)會(huì),并都能對(duì)模型有所增益。

    那么這個(gè)模型應(yīng)該是什么樣的?書(shū)我沒(méi)有細(xì)看,只說(shuō)說(shuō)自己的體會(huì)。關(guān)于設(shè)計(jì),很早就有數(shù)據(jù)驅(qū)動(dòng)和對(duì)象驅(qū)動(dòng)的提法。在 Without EJB 里, Rod 也有講:數(shù)據(jù)驅(qū)動(dòng)或者說(shuō)面向數(shù)據(jù)庫(kù)設(shè)計(jì)更成熟,工具更多;而對(duì)象驅(qū)動(dòng)更符合面向?qū)ο蟪绦虻奶匦裕捎谡莆盏娜溯^少,風(fēng)險(xiǎn)較大。而通過(guò)模型驅(qū)動(dòng),我認(rèn)為很大程度填補(bǔ)了 2 種方式的鴻溝,核心是模型,具體是對(duì)象模型還是數(shù)據(jù)模型并不重要,重要的是這個(gè)模型能夠與需求、代碼、數(shù)據(jù)庫(kù)保持一致。

    說(shuō)到這里,順便談一談我對(duì)文檔的理解。我一直是 XP 的堅(jiān)定支持者,甚至有點(diǎn)偏執(zhí)。而由于文檔不易閱讀和溝通,且經(jīng)常會(huì)出現(xiàn)與設(shè)計(jì)和代碼的脫節(jié),導(dǎo)致其可讀性更差,所以我一向?qū)ξ臋n不大感冒,更傾向于使用代碼說(shuō)話(huà)。但在目前的公司項(xiàng)目中,由于更多采用傳統(tǒng)的軟件過(guò)程,我也寫(xiě)了很多的文檔,包括需求規(guī)格說(shuō)明書(shū)、概要設(shè)計(jì)文檔、詳細(xì)設(shè)計(jì)文檔等等。從對(duì)項(xiàng)目的幫助來(lái)看,文檔作用并不太大,或者說(shuō)是付出收益比太低,更多的是給客戶(hù)寫(xiě)的,而不是給程序員寫(xiě)的。從程序員的需要來(lái)看,他關(guān)心的是每個(gè)實(shí)體的屬性和關(guān)聯(lián),核心的接口、輸入和輸出,頁(yè)面間的跳轉(zhuǎn)和數(shù)據(jù)流,然后有一個(gè)統(tǒng)一的框架和編程模式。我的體會(huì)是:如果以文檔為核心,很難描述清楚這些東西,且難以應(yīng)對(duì)變化。

    而通過(guò)以模型為核心(項(xiàng)目現(xiàn)在采用的 power designer 的概念模型為基礎(chǔ)),輔以適當(dāng)?shù)拿枋觯饶軌蚣涌齑蠹覍?duì)項(xiàng)目的認(rèn)識(shí)(程序員是后面才加入),又能夠節(jié)省一些寫(xiě)文檔的時(shí)間,更早投入開(kāi)發(fā)。

    說(shuō)到 power designer ,我也比較慚愧。用了好久,一直只是把它當(dāng)成看數(shù)據(jù)庫(kù)的工具。項(xiàng)目一開(kāi)始就是從物理模型入手,結(jié)果舉步維艱。后面從概念模型入手,就感受到了它的好處。使用概念模型,不用考慮太多關(guān)聯(lián)表、外鍵什么的,而是從實(shí)體出發(fā),然后確定相互間的關(guān)聯(lián),是一對(duì)一、一對(duì)多還是多對(duì)多。然后自動(dòng)轉(zhuǎn)成物理模型,并直接與相應(yīng)的數(shù)據(jù)庫(kù)掛鉤。從這點(diǎn)上看與從對(duì)象設(shè)計(jì)出發(fā)真的非常相似。其實(shí)這也是合情合理的,正體現(xiàn)了這個(gè)世界的統(tǒng)一性吧(物理學(xué)界不也在搞什么統(tǒng)一場(chǎng)理論的證明嗎)。 Power designer 也做了 conceptual model, physical model, object-oriented model xml model 的自動(dòng)轉(zhuǎn)換,我現(xiàn)在還沒(méi)全部摸熟。

    openfans 則是從對(duì)象入手,并通過(guò) hibernate 建立與數(shù)據(jù)庫(kù)的聯(lián)系,也體現(xiàn)了一定的方便靈活性。但比較糟糕的是,只有代碼和配置文件,沒(méi)有清晰的便于交流的模型,誰(shuí)要想?yún)⑴c只能先去慢慢看代碼。所以我先通過(guò) together reverse 出來(lái)一個(gè)類(lèi)圖,然后適當(dāng)加以文字進(jìn)行說(shuō)明。類(lèi)圖已經(jīng)做好,但比較亂,還需要更多的圖例加以說(shuō)明。文字說(shuō)明就是下一篇 blog 的工作了。也算是預(yù)告吧!

    posted @ 2006-08-13 17:41 pesome 閱讀(3643) | 評(píng)論 (3)編輯 收藏

    項(xiàng)目感悟

    近來(lái)在一個(gè)項(xiàng)目做 SA ,也是第一次做比較大的項(xiàng)目的設(shè)計(jì),感覺(jué)比較吃力。同時(shí)又要參與 spring 文檔的翻譯,一直沒(méi)時(shí)間寫(xiě) blog 。今天終于有點(diǎn)時(shí)間,就寫(xiě)一下最近的感悟。

    首先是不適應(yīng)。要參與需求階段,因?yàn)樾枨蟪跗诓⒉淮_定,客戶(hù)都不清楚他們需要什么東西,只是有一個(gè)很模糊的概念。我們得不斷調(diào)研、討論、出方案、出原型 …… 而這都是我比較不擅長(zhǎng)的。還好有個(gè)職務(wù)較高的老大帶著我們,才能逐漸把需求理順。我也從他身上學(xué)到不少,準(zhǔn)備寫(xiě)一篇“如何做需求”,但畢竟是第一次做較大的需求,理解還不很深刻,怕貽笑大方,所以只拿 MindManager 列了個(gè)提綱。

    其次還是不適應(yīng)。項(xiàng)目開(kāi)始好幾個(gè)月,沒(méi)寫(xiě)過(guò)一行代碼。項(xiàng)目沒(méi)有采用 XP 的方式,而是普通的瀑布。需求就做了幾個(gè)月,然后做概設(shè)、詳設(shè)。我是 XP 的支持者,所以對(duì)這種方式持反對(duì)態(tài)度,但老大不同意,沒(méi)辦法!寫(xiě)文檔,我也是很不情愿,但轉(zhuǎn)念一想: Rod 寫(xiě) Without EJB ,但他 ejb 的理解比誰(shuí)都深,什么方式都實(shí)踐下可能更好。由于同時(shí)在看 Joel on software ,他對(duì)需求規(guī)格說(shuō)明書(shū)卻很是強(qiáng)調(diào),我也就聽(tīng)聽(tīng)大師的話(huà),好好寫(xiě)需求,順便把他的一招用上了 ------- 寫(xiě)的有趣點(diǎn),就當(dāng)寫(xiě)故事吧。

    最后還是不適應(yīng)。以前做程序員,可以好好研究很多東西,現(xiàn)在不行了。有個(gè) xml bean 轉(zhuǎn)換的技術(shù)要解決,我能研究不?不行,我得寫(xiě)文檔,這種比較 detail 的事情得給程序員做。看著程序員興高采烈的比較各種開(kāi)源工具,最后選定 JIBX openfans 發(fā)揮了一定的作用),然后跟我講這個(gè)如何如何好,我只有附和的份。

    講到這里,讓我想到一則小故事:有一個(gè)學(xué)鋼琴的拜一個(gè)牛人為師。牛人交給他一個(gè)曲譜,說(shuō):“回去練好,一個(gè)月再過(guò)來(lái)。”他好歹把這個(gè)曲練熟了,還想展示一下,牛人又交給他一個(gè)更難的曲譜,又是同樣的話(huà)。他只好回去繼續(xù)苦練,每次都感覺(jué)不適應(yīng)。這樣往返多次,他忍不住了,問(wèn)牛人:“你是不是故意整我,每次都給我更難的,還不給我表現(xiàn)的機(jī)會(huì)”。牛人讓他把上次的曲彈彈,他感覺(jué)不錯(cuò),讓彈再上次的,更是輕松,最后彈第一次,他彈的是出神入化。他明白了!

    大家都明白沒(méi):只有不斷的感到不適應(yīng),才能進(jìn)步。如果一切感覺(jué)良好,沒(méi)什么挑戰(zhàn),就該考慮。。。。。。(此處省略 2 字)了。

    posted @ 2006-08-11 18:34 pesome 閱讀(1075) | 評(píng)論 (3)編輯 收藏

    僅列出標(biāo)題
    共5頁(yè): 上一頁(yè) 1 2 3 4 5 下一頁(yè) 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    主要記錄作者在學(xué)習(xí)java中的每一步足跡。除非特別說(shuō)明,所有文章均為本blog作者原創(chuàng),如需轉(zhuǎn)載請(qǐng)注明出處和原作者,如用于商業(yè)目的,需跟作者本人聯(lián)系。
    歡迎大家訪問(wèn):

    常用鏈接

    留言簿(16)

    隨筆分類(lèi)

    隨筆檔案

    文章分類(lèi)

    文章檔案

    相冊(cè)

    收藏夾

    java技術(shù)

    人間百態(tài)

    朋友們的blog

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 黄色网址免费大全| 亚洲XX00视频| 亚洲爽爽一区二区三区| 亚洲综合在线视频| 在线观看亚洲免费| 一级特黄aa毛片免费观看| 日韩一区二区三区免费体验| 亚洲国产美女精品久久久久∴| 亚洲乱码在线卡一卡二卡新区| 国产免费久久久久久无码| 国产1024精品视频专区免费 | 国产91免费视频| 亚洲精品尤物yw在线影院| 亚洲免费二区三区| 99精品免费视品| 日韩a在线观看免费观看| 久久久久亚洲AV片无码下载蜜桃 | 在线观看成人免费视频| 亚洲AV永久青草无码精品| 精品亚洲成A人在线观看青青| 日本黄色动图免费在线观看| 国产免费av一区二区三区| 亚洲狠狠狠一区二区三区| a在线视频免费观看在线视频三区| aa级一级天堂片免费观看| 久久精品国产亚洲夜色AV网站| 在线观看亚洲电影| 国产精品无码免费播放| 亚洲av无码乱码国产精品fc2| 爱情岛论坛免费视频| 91免费精品国自产拍在线不卡| 亚洲国产成人高清在线观看| 国产亚洲综合精品一区二区三区| 国产香蕉免费精品视频| 亚洲国产精品VA在线看黑人| 国产成人不卡亚洲精品91| 成人免费视频88| 亚洲同性男gay网站在线观看| 成全在线观看免费观看大全| 亚洲av午夜成人片精品电影| 亚洲av无码专区在线电影天堂|