锘??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲乱码中文字幕手机在线,国产亚洲精品bv在线观看,亚洲国产婷婷香蕉久久久久久http://www.tkk7.com/tbest/java鍏堬紙鎴戝簲璇ヤ負瀹冨啓鐐逛粈涔堜簡錛侊級zh-cnFri, 09 May 2025 21:56:17 GMTFri, 09 May 2025 21:56:17 GMT60鎵ц./startup.sh,鎴栬?/shutdown.sh鐨勬椂鍊欙紝鐖嗗嚭浜哖ermission deniedhttp://www.tkk7.com/tbest/archive/2014/12/30/421946.htmlliujgliujgTue, 30 Dec 2014 02:26:00 GMThttp://www.tkk7.com/tbest/archive/2014/12/30/421946.htmlhttp://www.tkk7.com/tbest/comments/421946.htmlhttp://www.tkk7.com/tbest/archive/2014/12/30/421946.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/421946.htmlhttp://www.tkk7.com/tbest/services/trackbacks/421946.html

鍏充簬LINUX鏉冮檺-bash: ./startup.sh: Permission denied

<script type="text/javascript"></script><script type="text/javascript"></script>

鍦ㄦ墽琛?/startup.sh,鎴栬?/shutdown.sh鐨勬椂鍊欙紝鐖嗗嚭浜哖ermission denied錛?/p>

鍏跺疄寰堢畝鍗曪紝灝辨槸浠婂ぉ鍦ㄦ墽琛宼omcat鐨勬椂鍊欙紝鐢ㄦ埛娌℃湁鏉冮檺錛岃屽鑷存棤娉曟墽琛岋紝

鐢ㄥ懡浠hmod 淇敼涓涓媌in鐩綍涓嬬殑.sh鏉冮檺灝卞彲浠ヤ簡

濡俢hmod u+x *.sh

鍦ㄦ鎵ц錛孫K浜嗐?/p>



liujg 2014-12-30 10:26 鍙戣〃璇勮
]]>
submit()鍜宱nsubmit()鐨勫尯鍒?杞?http://www.tkk7.com/tbest/archive/2011/09/28/359693.htmlliujgliujgWed, 28 Sep 2011 07:11:00 GMThttp://www.tkk7.com/tbest/archive/2011/09/28/359693.htmlhttp://www.tkk7.com/tbest/comments/359693.htmlhttp://www.tkk7.com/tbest/archive/2011/09/28/359693.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/359693.htmlhttp://www.tkk7.com/tbest/services/trackbacks/359693.html
2011-03-16 10:34

鏈榪戝湪寮鍙戜腑閬囧埌浜嗚〃鍗曟彁浜ゅ墠楠岃瘉鐨勯棶棰橈紝鐢ㄤ竴涓櫘閫氱殑button鎸夐挳浠f浛submit鎸夐挳錛?br />鍦ㄦ彁浜ゅ墠瑙﹀彂榪欎釜button鐨刼nclick浜嬩歡錛屽湪鍏朵簨浠朵腑瑙﹀彂form鐨剆ubmit浜嬩歡銆傞棶棰樺嚭鐜頒簡錛?br />浠ヤ笅鏄嚭鐜扮浉鍏充唬鐮侊細
<form action="http://www.baidu.com/s?wd=this.form.submit%28%29%3B&cl=3" method="post" name="form1" onsubmit="return alert('宸叉彁浜わ紒'); return false;"> 
    <table align="center" width="420px" cellPadding="2" cellSpacing="1" bgcolor="#A4B6D7"    style="word-wrap:Break-word;">                
        <tr style="cursor: hand;background:#d7e3f6" > 
            <td width="20%" align="right">鏉″瀷鐮?lt;/td> 
            <td><input style="width:90%" type="text" name="GOODSNUM"   size="30"  maxlength="8" ></td> 
        </tr> 
        <tr> 
            <td align="center" colspan="2"> 
                <input type="button" name="save" value="淇濆瓨" onclick="if((confirm('紜畾瑕佹彁浜ゅ悧錛?))) this.form.submit();"/> 
            </td> 
        </tr>  
    </table> 
</form> 


鍗村彂鐜板茍娌℃湁瑙﹀彂form鐨刼nsubmit鏂規硶錛岃屾槸鐩存帴鎻愪氦浜嗐傚鎬簡錛岄毦閬撴病鏈夎繖縐嶆柟寮忔棤娉曠粨鍚坒orm鐨刼nsubmit鏂規硶鍚楋紵
浠旂粏鎯充簡鎯籌紝鏃㈢劧this.form琛ㄧずform榪欎釜瀵硅薄錛岄偅涔堣偗瀹氳兘鑾峰彇鍒癴orm鐨勫睘鎬у拰鏂規硶鐨?br />錛屽氨鏀規垚this.form.onsubmit();  鎴愬姛錛?br />鎴戝張鏌ヤ簡鏌ユ墜鍐岋紝鍘熸潵submit鐨勬柟娉曟槸榪欐牱瑙i噴鐨勶細
  The submit method does not invoke the onsubmit event handler. Call the onsubmit event handler directly. When using Microsoft® Internet Explorer 5.5 and later, you can call the fireEvent method with a value of onsubmit in the sEvent parameter.

鎰忔濇槸璇磗ubmit榪欎釜鏂規硶鏄笉瑙﹀彂onsubmit鏃墮棿鐨勶紝濡傛灉鎯寵瑙﹀彂瀹冿紝闇瑕佽皟鐢?br />fireEvent鏂規硶銆傚皾璇曚竴涓嬶細this.form.fireEvent('onsubmit');鍝堝搱錛屾灉鐒朵篃鎴愬姛錛佷笉榪囪繖鏍蜂笉鏄姝や竴涓懼悧錛熷懙鍛碉紒

灝辮繖涓皬闂涔熸悶浜嗘垜灝嗚繎涓涓皬鏃訛紝涓嶈繃涓轟簡浠ュ悗涓嶄負榪欎釜闂鐑︽伡錛岃繖涔熸槸鍊煎緱鐨勩?br />this.form.submit(); //鐩存帴鎻愪氦琛ㄥ崟
this.form.onsubmit(); //璋冪敤form鐨刼nsubmit鏂規硶
this.form.fireEvent('onsubmit'); //鍚屼笂,
     PS:鍙堝鍒頒簡fireEvent榪欎釜鏂規硶錛?/p>

2.onsubmit()涓巗ubmit() 錛?/p>

<sCript>
funCtion fun()
{
   alert("form_submit");
}
</sCript>

<form onsubmit="fun()">
<input type="submit" id="aaa" value="submit">   <!--鑳藉脊鍑篺orm_submit-->
<input type="button" id="bbb" value="onCliCk_submit" onCliCk="doCument.forms[0].submit()">
<!--
琛ㄥ崟浼氭彁浜わ紝浣嗘槸涓嶄細榪愯fun() 鍘熷洜鏄?onsubmit浜嬩歡涓嶈兘閫氳繃姝ょ鏂瑰紡瑙﹀彂錛堝湪IE鐜錛?br />鐩存帴鐢ㄨ剼鏈琩oCumetn.formName.submit()鎻愪氦琛ㄥ崟鏄笉浼氳Е鍙戣〃鍗曠殑onsubmit()浜嬩歡鐨?br />-->
    <input type="button" id="bb1" value="onCliCk_onsubmit" onCliCk="doCument.forms[0].onsubmit()">

<!--浼氳Е鍙慺un()鍙傛暟-->
</form>



liujg 2011-09-28 15:11 鍙戣〃璇勮
]]>
doGet()鍜宒oPost()鐨勫尯鍒紙杞級http://www.tkk7.com/tbest/archive/2011/05/24/350955.htmlliujgliujgTue, 24 May 2011 15:58:00 GMThttp://www.tkk7.com/tbest/archive/2011/05/24/350955.htmlhttp://www.tkk7.com/tbest/comments/350955.htmlhttp://www.tkk7.com/tbest/archive/2011/05/24/350955.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/350955.htmlhttp://www.tkk7.com/tbest/services/trackbacks/350955.html

service()鏄湪javax.servlet.Servlet鎺ュ彛涓畾涔夌殑, 鍦?javax.servlet.GenericServlet 涓疄鐜頒簡榪欎釜鎺ュ彛, 鑰?doGet/doPost 鍒欐槸鍦?javax.servlet.http.HttpServlet 涓疄鐜扮殑, javax.servlet.http.HttpServlet 鏄?javax.servlet.GenericServlet 鐨勫瓙綾? 鎵鏈夊彲浠ヨ繖鏍風悊瑙? 鍏跺疄鎵鏈夌殑璇鋒眰鍧囬鍏堢敱 service() 榪涜澶勭悊, 鑰屽湪 javax.servlet.http.HttpServlet 鐨?service() 鏂規硶涓? 涓昏鍋氱殑浜嬫儏灝辨槸鍒ゆ柇璇鋒眰綾誨瀷鏄?Get 榪樻槸 Post, 鐒跺悗璋冪敤瀵瑰簲鐨?doGet/doPost 鎵ц.

doGet錛氬鐞咷ET璇鋒眰 doPost錛氬鐞哖OST璇鋒眰 doPut錛氬鐞哖UT璇鋒眰 doDelete錛氬鐞咲ELETE璇鋒眰 doHead錛氬鐞咹EAD璇鋒眰 doOptions錛氬鐞哋PTIONS璇鋒眰 doTrace錛氬鐞員RACE璇鋒眰 閫氬父鎯呭喌涓嬶紝鍦ㄥ紑鍙戝熀浜嶩TTP鐨剆ervlet鏃訛紝寮鍙戣呭彧闇瑕佸叧蹇僤oGet鍜宒oPost鏂規硶錛屽叾瀹冪殑鏂規硶闇瑕佸紑鍙戣呴潪甯哥殑鐔熸倝HTTP緙栫▼錛屽洜姝よ繖浜涙柟娉曡璁や負鏄珮綰ф柟娉曘?鑰岄氬父鎯呭喌涓嬶紝鎴戜滑瀹炵幇鐨剆ervlet閮芥槸浠嶩ttpServlet鎵╁睍鑰屾潵銆?doPut鍜宒oDelete鏂規硶鍏佽寮鍙戣呮敮鎸丠TTP/1.1鐨勫搴旂壒鎬э紱 doHead鏄竴涓凡緇忓疄鐜扮殑鏂規硶錛屽畠灝嗘墽琛宒oGet浣嗘槸浠呬粎鍚戝鎴風榪斿洖doGet搴旇鍚戝鎴風榪斿洖鐨勫ご閮ㄧ殑鍐呭錛?doOptions鏂規硶鑷姩鐨勮繑鍥瀞ervlet鎵鐩存帴鏀寔鐨凥TTP鏂規硶淇℃伅錛?doTrace鏂規硶榪斿洖TRACE璇鋒眰涓殑鎵鏈夊ご閮ㄤ俊鎭?瀵逛簬閭d簺浠呬粎鏀寔HTTP/1.0鐨勫鍣ㄨ岃█錛屽彧鏈塪oGet, doHead 鍜?doPost鏂規硶琚嬌鐢紝鍥犱負HTTP/1.

涓嬭竟鏄疌SDN閲岃竟鐨勪竴浜涜璁?
1.doGet鍜宒oPost鐨勫尯鍒紝鍦ㄤ粈涔堟椂鍊欒皟鐢紝涓轟粈涔堟湁鏃禿oPost涓鐢╠oGet
2.鎻愪氦鐨刦orm     method=Post灝辨墽琛孌OPOST錛屽惁鍒欐墽琛孏OGET 濂楃敤鏄笉綆ethod鏄痯ost榪樻槸get閮芥墽琛宒opost鏂規硶
3.get:浣犲彲浠ラ氳繃URL浼犲弬鏁般?/font>http://www.csdn.net/index.asp?user=1234    , Post涓嶈  
4.浣犵殑琛ㄥ崟鎻愪氦閮芥湁鏂規硶鐨?濡傛灉鎻愪氦涓篻et灝辮皟鐢╣et鏂規硶,鐢╬ost灝辮皟鐢╬ost鏂規硶.  
    get鏄劇ず浣犱紶榪囧幓鐨勫弬鏁?post鍒欎笉鏄劇ず.
5.閫氬父鐨勫啓娉曪細鍏堢敤doGet(),鐒跺悗鍦╠oPost()涓皟鐢╠oGet(),榪欐牱灝變竾鏃犱竴澶變簡
6. 綆鍗曠殑璇達紝get鏄氳繃http     header鏉ヤ紶杈撴暟鎹紝鏈夋暟閲忛檺鍒訛紝鑰宲ost鍒欐槸閫氳繃http     body鏉ヤ紶杈撴暟鎹紝娌℃湁鏁伴噺闄愬埗銆?br />7.榪樻湁涓鐐?get鍜宲ost鎻愪氦鐨勬暟鎹噺鏄笉涓鏍風殑.  
    get濂藉儚鏈澶氬彧鑳藉湪url鍚庤窡64K(?鍏蜂綋澶氬皯蹇樿浜?,  
    post濂藉儚娌¤繖涓檺鍒?鑷沖皯鎴憄ost榪?M浠ヤ笂鐨勬枃鏈?nbsp;   
    榪樻湁url鍒鋒柊鏃秅et濂藉儚鍙互涓嶇敤閲嶅鎻愪氦鍘熸潵鎻愪氦鐨勬暟鎹?  
    鑰宲ost鍒欎細璇村唴瀹瑰凡鎻愪氦,鎯沖埛鏂拌鍐嶆彁浜?


liujg 2011-05-24 23:58 鍙戣〃璇勮
]]>
杞澆 Vim 鍩烘湰鐢ㄦ硶http://www.tkk7.com/tbest/archive/2011/05/03/349425.htmlliujgliujgTue, 03 May 2011 06:25:00 GMThttp://www.tkk7.com/tbest/archive/2011/05/03/349425.htmlhttp://www.tkk7.com/tbest/comments/349425.htmlhttp://www.tkk7.com/tbest/archive/2011/05/03/349425.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/349425.htmlhttp://www.tkk7.com/tbest/services/trackbacks/349425.html榪欐槸鎴戞葷粨鐨勪竴浜涘熀鏈敤娉?鍙兘瀵瑰垵鐢ㄨ呬細鏈夊府鍔?鐙箰涔愪笉濡備紬涔愪箰,鏄惂!

璇存槑錛氫互涓嬮粦鑹蹭負vi鍜寁im鍧囨湁鐨勪竴鑸姛鑳斤紝鑰岀孩鑹蹭負Vim錛圴i Improved錛夋墍鐗規湁鍔熻兘銆俈im涓鑸殑Unix鍜孡inux涓嬪潎鏈夊畨瑁呫?br /> 飦?涓夌鐘舵?br /> Command錛?浠諱綍杈撳叆閮戒細浣滀負緙栬緫鍛戒護錛岃屼笉浼氬嚭鐜板湪灞忓箷涓婏紝浠諱綍杈撳叆閮藉紩璧風珛鍗沖弽鏄?br /> Insert錛?浠諱綍杈撳叆鐨勬暟鎹兘緗簬緙栬緫瀵勫瓨鍣紝鎸塃SC錛屽彲璺沖洖command鏂瑰紡
Escape錛?浠?#8220;錛?#8221;鎴栬?#8220;/”涓哄墠瀵肩殑鎸囦護錛屽嚭鐜板湪灞忓箷鐨勬渶涓嬩竴琛岋紝浠諱綍杈撳叆閮借褰撴垚鐗瑰埆鎸囦護銆?br /> 飦?紱誨紑vi
:q! 紱誨紑vi錛屽茍鏀懼純鍒氬湪緙撳啿鍖哄唴緙栬緫鐨勫唴瀹廣?br /> :wq 灝嗙紦鍐插尯鍐呯殑璧勬枡鍐欏叆紓佺洏涓紝騫剁寮vi銆?br /> :x 鍚寃q銆?br /> 錛堟敞鎰忊斺?:X 鏄枃浠跺姞瀵嗭紝涓瀹氳涓?x瀛樼洏閫鍑虹浉鍖哄埆錛?br /> 飦?榪涘叆杈撳叆妯″紡
a (append) 鐢辨父鏍囦箣鍚庡姞鍏ヨ祫鏂欍?br /> A 鐢辮琛屼箣鏈姞鍏ヨ祫鏂欍?br /> i (insert) 鐢辨父鏍囦箣鍓嶅姞鍏ヨ祫鏂欍?br /> I 鐢辮琛屼箣棣栧姞鍏ヨ祫鏂欍?br /> o (open) 鏂板涓琛屾柤璇ヨ涔嬩笅渚涜緭鍏ヨ祫鏂欎箣鐢ㄣ?br /> O 鏂板涓琛屾柤璇ヨ涔嬩笂渚涜緭鍏ヨ祫鏂欎箣鐢ㄣ?br /> 飦?鍒犻櫎涓庝慨鏀?br /> x 鍒犻櫎娓告爣鎵鍦ㄨ瀛楀厓銆?br /> X 鍒犻櫎娓告爣鎵鍦ㄤ箣鍓嶄竴瀛楀厓銆?br /> r 鐢ㄦ帴鏂兼鎸囦護涔嬪悗鐨勫瓧鍏冨彇浠?replace)娓告爣鎵鍦ㄥ瓧鍏冦傚錛歳a灝嗘父鏍囨墍鍦ㄥ瓧鍏冧互 a 鍙栦唬涔嬨?br /> R 榪涘叆鍙栦唬鐘舵侊紝鐩村埌銆奅SC銆嬩負姝€?br /> s 鍒犻櫎娓告爣鎵鍦ㄤ箣瀛楀厓錛屽茍榪涘叆杈撳叆妯″紡鐩村埌銆奅SC銆嬨?br /> S 鍒犻櫎娓告爣鎵鍦ㄤ箣璇ヨ璧勬枡錛屽茍榪涘叆杈撳叆妯″紡鐩村埌銆奅SC銆嬨?br /> 飦?鍏夋爣鐨勭Щ鍔?br /> m<a-z> 璁劇疆涔︾<a-z>
‘<a-z> 縐昏嚦涔︾<a-z>澶?br /> 0 縐昏嚦璇ヨ涔嬮
$ 縐昏嚦璇ヨ涔嬫湯銆?br /> e 縐誨姩鍒頒笅涓瓧鐨勬渶寰屼竴涓瓧姣?br /> w 縐誨姩鍒頒笅涓瓧鐨勭涓涓瓧姣嶃?br /> b 縐誨姩鍒頒笂涓瓧鐨勭涓涓瓧姣嶃?br /> ^ 縐昏嚦璇ヨ鐨勭涓涓瓧鍏冨銆?br /> H 縐昏嚦瑙嗙獥鐨勭涓琛屻?br /> M 縐昏嚦瑙嗙獥鐨勪腑闂撮偅琛屻?br /> L 縐昏嚦瑙嗙獥鐨勬渶鍚庝竴琛屻?br /> G 縐昏嚦璇ユ枃浠剁殑鏈鍚庝竴琛屻?br /> + 縐昏嚦涓嬩竴鍒楃殑絎竴涓瓧鍏冨銆?br /> - 縐昏嚦涓婁竴鍒楃殑絎竴涓瓧鍏冨銆?br /> :n 縐昏嚦璇ユ枃浠剁殑絎?n 鍒椼?br /> n+ 縐昏嚦娓告爣鎵鍦ㄤ綅緗箣鍚庣殑絎?n 鍒椼?br /> n- 縐昏嚦娓告爣鎵鍦ㄤ綅緗箣鍓嶇殑絎?n 鍒椼?br /> <Ctrl><g> 鏄劇ず璇ヨ涔嬭鍙楓佹枃浠跺悕縐般佹枃浠朵腑鏈鏈涔嬭鍙楓佹父鏍囨墍鍦ㄨ鍙峰崰鎬昏鍙蜂箣鐧懼垎姣斻?/p>

錛圴im錛?鍏夋爣縐誨姩鍩烘湰鐢ㄦ硶灝忚В錛?br /> (榪欏彧瑕佺粍鍚堜笂杈圭殑鍔熻兘灝卞彲浠ユ槑鐧戒簡錛屼笉鐢ㄥ啀涓涓璁茶В浜嗗惂錛?
ge b w e
← ← ---→ --→
This is-a line, with special/separated/words (and some more).
←- ←-- -----------------→ ---→
GE B W E

飦?瑙嗙獥鐨勭Щ鍔?br /> <Ctrl><f> 瑙嗙獥寰涓嬪嵎涓欏點?br /> <Ctrl><b> 瑙嗙獥寰涓婂嵎涓欏點?br /> <Ctrl><d> 瑙嗙獥寰涓嬪嵎鍗婇〉銆?br /> <Ctrl><u> 瑙嗙獥寰涓婂嵎鍗婇〉銆?br /> <Ctrl><e> 瑙嗙獥寰涓嬪嵎涓琛屻?br /> <Ctrl><y> 瑙嗙獥寰涓婂嵎涓琛屻?br /> 飦?鍓垏銆佸鍒躲佸垹闄?br /> Operator + Scope = command
飩?Operator
d 鍓垏
y 澶嶅埗銆?br /> p 綺樺笘錛屼笌 d 鍜?y 閰嶅拰浣跨敤銆傚彲灝嗘渶鍚巇鎴杫鐨勮祫鏂欐斁緗柤娓告爣鎵鍦ㄤ綅緗箣琛屽垪涓嬨?br /> c 淇敼錛岀被浼糳elete涓巌nsert鐨勭粍鍜屻傚垹闄や竴涓瓧緇勩佸彞瀛愮瓑涔嬭祫鏂欙紝騫舵彃鍏ユ柊寤鴻祫鏂欍?br /> 飩?Scope
e 鐢辨父鏍囨墍鍦ㄤ綅緗嚦璇ュ瓧涓茬殑鏈鍚庝竴涓瓧鍏冦?br /> w 鐢辨父鏍囨墍鍦ㄤ綅緗嚦涓嬩竴涓瓧涓茬殑絎竴涓瓧鍏冦?br /> b 鐢辨父鏍囨墍鍦ㄤ綅緗嚦鍓嶄竴涓瓧涓茬殑絎竴涓瓧鍏冦?br /> $ 鐢辨父鏍囨墍鍦ㄤ綅緗嚦璇ヨ鐨勬渶鍚庝竴涓瓧鍏冦?br /> 0 鐢辨父鏍囨墍鍦ㄤ綅緗嚦璇ヨ鐨勭涓涓瓧鍏冦?br /> 飩?鏁磋鍔ㄤ綔
dd 鍒犻櫎鏁磋銆?br /> D 浠ヨ涓哄崟浣嶏紝鍒犻櫎娓告爣鍚庝箣鎵鏈夊瓧鍏冦?br /> cc 淇敼鏁磋鐨勫唴瀹廣?br /> yy 浣挎父鏍囨墍鍦ㄨ琛屽鍒跺埌璁板繂浣撶紦鍐插尯銆?br /> 飦?鍙栨秷鍓嶄竴鍔ㄤ綔(Undo)
u 鎭㈠鏈鍚庝竴涓寚浠や箣鍓嶇殑緇撴灉銆?br /> U 鎭㈠娓告爣璇ヨ涔嬫墍鏈夋敼鍙樸?br /> (vim) u 鍙互澶氭鎾ゆ秷鎸囦護錛屼竴嬈℃挙娑堜竴涓搷浣滐紝鐩磋嚦鏈鎿嶄綔寮濮嬩負姝€?br /> (vim) Ctrl+r 鍙互鎭㈠鎾ゆ秷鍓嶅唴瀹癸紝鎸夊嬈″彲鎭㈠澶氭銆?br /> 飦?鏌ユ壘涓庢浛鎹?br /> /瀛椾覆 寰娓告爣涔嬪悗瀵繪壘璇ュ瓧涓層?br /> ?瀛椾覆 寰娓告爣涔嬪墠瀵繪壘璇ュ瓧涓層?br /> n 寰涓嬬戶緇鎵句笅涓涓浉鍚岀殑瀛椾覆銆?br /> N 寰涓婄戶緇鎵句笅涓涓浉鍚岀殑瀛椾覆銆?br /> % 鏌ユ壘“(”錛?#8220;)”錛?#8220;{”錛?#8220;}”鐨勯厤瀵圭銆?br /> s 鎼滃鏌愯鍒楄寖鍥淬?br /> g 鎼滃鏁翠釜緙栬緫緙撳啿鍖虹殑璧勬枡銆?br /> :1,$s/old/new/g 灝嗘枃浠朵腑鎵鏈夌殑銆巓ld銆忔敼鎴愩巒ew銆忋?br /> :10,20s/^/ / 灝嗙10琛岃嚦絎?0琛岃祫鏂欑殑鏈鍓嶉潰鎻掑叆5涓┖鐧姐?br /> (vim)
/瀛楃涓?鍚庤竟杈撳叆鏌ヨ鍐呭鍙繚瀛樿嚦緙撳啿鍖轟腑錛屽彲鐢?#8593;↓榪涜浠ュ線鍐呭閫夋嫨銆?br /> 鍙﹀錛氬皢鍏夋爣縐誨姩鍦ㄩ夊畾鍗曡瘝涓嬫柟鎸?錛屽垯鍙互閫変腑姝ゅ崟璇嶄綔涓烘煡璇㈠瓧絎︼紝鍙互閬垮厤杈撳叆涓闀夸覆瀛楃鐨勯夯鐑︺?br /> 飦?(vim) 澶у皬鍐欐浛鎹?br /> 棣栧厛鐢ㄦ寜v寮鍚夋嫨鍔熻兘錛岀劧鍚庣敤↑↓←→閿潵閫夊畾鎵瑕佹浛鎹㈢殑瀛楃錛岃嫢鏄皬鍐欏彉澶у啓錛屽垯鎸塙;鍙嶄箣鎸塽;
濡傛灉鏄夋嫨鍗曡瘝錛屽垯鍙互鍦ㄦ寜v鍚庯紝鎸墂錛屾渶鍚庢寜U/u,榪欐牱灝卞彲浠ュ皢瀛楃闅忔剰鐨勬敼鍙樺ぇ灝忓啓浜嗭紝鑰屼笉鐢ㄥ垹闄ゅ悗閲嶆柊鏁插叆銆?/p>

飦?璧勬枡鐨勮繛鎺?br /> J 鍙ュ瓙鐨勮繛鎺ャ傚皢娓告爣鎵鍦ㄤ箣涓嬩竴琛岃繛鎺ヨ嚦娓告爣璇ヨ鐨勫悗闈€?br /> 飦?鐜鐨勮瀹?br /> :set all 鍙緗殑鐜鍙橀噺鍒楄〃
:set 鐜鍙橀噺鐨勫綋鍓嶅?br /> :set nu 璁懼畾璧勬枡鐨勮鍙楓?br /> :set nonu 鍙栨秷琛屽彿璁懼畾銆?br /> :set ai 鑷姩鍐呯緝銆?br /> :set noai 鍙栨秷鑷姩鍐呯緝銆?br /> (vim)
:set ruler 浼氬湪灞忓箷鍙充笅瑙掓樉紺哄綋鍓嶅厜鏍囨墍澶勪綅緗紝騫墮殢鍏夌Щ鍔ㄨ屾敼鍙橈紝鍗犵敤灞忓箷絀洪棿杈冨皬錛屼嬌鐢ㄤ篃姣旇緝鏂逛究錛屾帹鑽愪嬌鐢ㄣ?br /> :set hlsearch 鍦ㄤ嬌鐢ㄦ煡鎵懼姛鑳芥椂錛屼細楂樹寒鏄劇ず鎵鏈夊尮閰嶇殑鍐呭銆?br /> :set nohlsearch 鍏抽棴姝ゅ姛鑳姐?br /> :set incsearch 浣縑im鍦ㄨ緭鍏ュ瓧絎︿覆鐨勮繃紼嬩腑錛屽厜鏍囧氨鍙畾浣嶆樉紺哄尮閰嶇偣銆?br /> :set nowrapscan 鍏抽棴鏌ユ壘鑷姩鍥炵幆鍔熻兘錛屽嵆鏌ユ壘鍒版枃浠剁粨灝懼錛岀粨鏉熸煡鎵撅紱榛樿鐘舵佹槸鑷姩鍥炵幆

飦?ex鎸囦護
飩?璇誨啓璧勬枡
:10,20w test 灝嗙10琛岃嚦絎?0琛岀殑璧勬枡鍐欏叆test鏂囦歡銆?br /> :10,20w>>test 灝嗙10琛岃嚦絎?0琛岀殑璧勬枡鍔犲湪test鏂囦歡涔嬪悗銆?br /> :r test 灝唗est鏂囦歡鐨勮祫鏂欒鍏ョ紪杈戠紦鍐插尯鐨勬渶鍚庛?br /> :e [filename] 緙栬緫鏂扮殑鏂囦歡銆?br /> :e! [filename] 鏀懼純褰撳墠淇敼鐨勬枃浠訛紝緙栬緫鏂扮殑鏂囦歡銆?br /> :sh 榪涘叆shell鐜錛屼嬌鐢╡xit閫鍑猴紝鍥炲埌緙栬緫鍣ㄤ腑銆?/p>

:!cmd 榪愯鍛戒護cmd鍚庯紝榪斿洖鍒扮紪杈戝櫒涓?br /> 飩?鍒犻櫎銆佸鍒跺強鎼Щ
:10,20d 鍒犻櫎絎?0琛岃嚦絎?0琛岀殑璧勬枡銆?br /> :10d 鍒犻櫎絎?0琛岀殑璧勬枡銆?br /> :%d 鍒犻櫎鏁翠釜緙栬緫緙撳啿鍖恒?br /> :10,20co30 灝嗙10琛岃嚦絎?0琛岀殑璧勬枡澶嶅埗鑷崇30琛屼箣鍚庛?br /> :10,20mo30 灝嗙10琛岃嚦絎?0琛岀殑璧勬枡鎼Щ鑷崇30琛屼箣鍚庛?/p>

鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛歨ttp://blog.csdn.net/jsufcz/archive/2009/02/11/3875956.aspx



liujg 2011-05-03 14:25 鍙戣〃璇勮
]]>
OERR: ORA-12519http://www.tkk7.com/tbest/archive/2011/01/30/343771.htmlliujgliujgSun, 30 Jan 2011 05:36:00 GMThttp://www.tkk7.com/tbest/archive/2011/01/30/343771.htmlhttp://www.tkk7.com/tbest/comments/343771.htmlhttp://www.tkk7.com/tbest/archive/2011/01/30/343771.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/343771.htmlhttp://www.tkk7.com/tbest/services/trackbacks/343771.html
OERR: ORA-12519鎶ラ敊  
1銆佹煡璇㈡暟鎹簱褰撳墠鐨勮繛鎺ユ暟錛?
select count(*) from v$process;
2銆佹煡璇㈡暟鎹簱鍏佽鐨勬渶澶ц繛鎺ユ暟錛?
select value from v$parameter where name = 'processes';
3銆佷慨鏀規暟鎹簱鍏佽鐨勬渶澶ц繛鎺ユ暟錛?
alter system set processes = 300 scope = spfile;
4銆侀噸鍚暟鎹簱錛?
shutdown immediate;
startup; 

 


鏂囩珷鍑哄錛氶璇虹綉(www.firnow.com):http://dev.firnow.com/course/7_databases/oracle/oraclejs/20091103/181042.html



liujg 2011-01-30 13:36 鍙戣〃璇勮
]]>
鍘熷艦璁捐妯″紡錛屾悶涓嶆噦http://www.tkk7.com/tbest/archive/2007/11/29/164023.htmlliujgliujgThu, 29 Nov 2007 08:23:00 GMThttp://www.tkk7.com/tbest/archive/2007/11/29/164023.htmlhttp://www.tkk7.com/tbest/comments/164023.htmlhttp://www.tkk7.com/tbest/archive/2007/11/29/164023.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/164023.htmlhttp://www.tkk7.com/tbest/services/trackbacks/164023.html


瀹氫箟:

鐢ㄥ師鍨嬪疄渚嬫寚瀹氬垱寤哄璞$殑縐嶇被,騫朵笖閫氳繃鎷瘋礉榪欎簺鍘熷瀷鍒涘緩鏂扮殑瀵硅薄. //閫氳繃鎷瘋礉鍒涘緩鏂扮殑瀵硅薄璺熼氳繃緇ф壙鍒涘緩鏈変粈涔堝尯鍒憿錛?br /> Prototype 妯″紡鍏佽涓涓璞″啀鍒涘緩鍙﹀涓涓彲瀹氬埗鐨勫璞★紝鏍規湰鏃犻渶鐭ラ亾浠諱綍濡備綍鍒涘緩鐨?

緇嗚妭,宸ヤ綔鍘熺悊鏄?閫氳繃灝嗕竴涓師鍨嬪璞′紶緇欓偅涓鍙戝姩鍒涘緩鐨勫璞★紝榪欎釜瑕佸彂鍔ㄥ垱寤虹殑瀵硅薄

閫氳繃璇鋒眰鍘熷瀷瀵硅薄鎷瘋礉瀹冧滑鑷繁鏉ュ疄鏂藉垱寤恒?

濡備綍浣跨敤?

鍥犱負Java 涓殑鎻愪緵clone()鏂規硶鏉ュ疄鐜板璞$殑鍏嬮殕(鍏蜂綋浜嗚В clone()鎸夎繖閲?,鎵浠?

Prototype 妯″紡瀹炵幇涓涓嬪瓙鍙樺緱寰堢畝鍗?

浠ュ嫼瀛愪負渚嬶細

public abstract class AbstractSpoon implements Cloneable
{

    String spoonName;

    public void setSpoonName(String spoonName) {this.spoonName = spoonName;}

    public String getSpoonName() {return this.spoonName;}

    public Object clone()

     {

        Object object = null;

        try {
            object = super.clone();

        } catch (CloneNotSupportedException exception) {

            System.err.println("AbstractSpoon is not Cloneable");

        }

        return object;
    }

}

鏈変袱涓叿浣撳疄鐜?ConcretePrototype):

public class SoupSpoon extends AbstractSpoon

{

    public SoupSpoon()
     {

        setSpoonName("Soup Spoon");

    }

}

public class SaladSpoon extends AbstractSpoon

{

     public SaladSpoon()

     {
         setSpoonName("Salad Spoon");

     }

}

璋冪敤 Prototype 妯″紡寰堢畝鍗?

AbstractSpoon spoon = new SoupSpoon();

AbstractSpoon spoon = new SaladSpoon();



liujg 2007-11-29 16:23 鍙戣〃璇勮
]]>
java 鍏抽棴IEhttp://www.tkk7.com/tbest/archive/2007/10/12/128366.htmlliujgliujgFri, 12 Oct 2007 02:06:00 GMThttp://www.tkk7.com/tbest/archive/2007/10/12/128366.htmlhttp://www.tkk7.com/tbest/comments/128366.htmlhttp://www.tkk7.com/tbest/archive/2007/10/12/128366.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/128366.htmlhttp://www.tkk7.com/tbest/services/trackbacks/128366.html鏈枃浠g爜鏉ヨ嚜浠ヤ笅榪炴帴銆?br>http://www.developer.com/java/other/article.php/10936_2212401_3錛?font face="Times New Roman" size=3>Introduction to the Java Robot Class in Java
錛?br>浠g爜綆鍗曡鏄庯細鍙互鍦?024*768鐨勫睆騫曞垎杈ㄧ巼涓嬪叧鎺変竴涓渶澶у寲鐨処E紿楀彛銆?br>

import java.awt.*;
import java.awt.event.*;

/**this class will close an maxmimum IE window in the 1024*768's screen resolution's machine.*/
public class Robot04{
   public static void main(String[] args)
                             throws AWTException{
  Robot robot = new Robot();
  robot.mouseMove(1005,10);
  robot.delay(2000);
  robot.mousePress(InputEvent.BUTTON1_MASK);
  robot.delay(2000);
  robot.mouseRelease(InputEvent.BUTTON1_MASK);
   }//end main

}//end class Robot04

榪欎釜紼嬪簭鐨凣UI鐗堟湰銆?br>Robot04GUI.java
/**
 * Robot04GUI.java
 * create by kin. 2004/11/07.
 * Please enjoy this.
 */

import javax.swing.*;
import javax.swing.event.*;

import java.awt.event.*;
import java.awt.*;

/**Robot04's GUI version.*/
public class Robot04GUI extends JFrame {
 
 private JButton b = new JButton("Close IE");
 
 public Robot04GUI() {
  super("Close IE");
  getContentPane().add(b,BorderLayout.CENTER);
  b.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    try {
     new Robot04().main(new String[]{}); 
    } catch (Exception ex) {
     ex.printStackTrace();
    }
   } 
  });
 } 
 
 public static void main(String[] args) {
  Robot04GUI r = new Robot04GUI();
  r.setSize(200,200);
  r.setVisible(true);
 } 



liujg 2007-10-12 10:06 鍙戣〃璇勮
]]>鐪嬩簡涓嬶綂锝侊綎锝佹牳蹇冩妧鏈腑鐨勪唬鐞嗭紝榪樻槸寰堟檿http://www.tkk7.com/tbest/archive/2007/05/24/119722.htmlliujgliujgThu, 24 May 2007 06:57:00 GMThttp://www.tkk7.com/tbest/archive/2007/05/24/119722.htmlhttp://www.tkk7.com/tbest/comments/119722.htmlhttp://www.tkk7.com/tbest/archive/2007/05/24/119722.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/119722.htmlhttp://www.tkk7.com/tbest/services/trackbacks/119722.html闇瑕佽浣忕殑涓滀笢錛?br>   錛戯紟浠g悊綾繪槸鍦ㄧ▼搴忚繍琛岃繃紼嬩腑鍒涘緩鐨勶紝涓鏃﹀垱寤哄氨鍙樻垚浜嗗父瑙勭被錛屼笌铏氭嫙鏈虹鐨勪換浣曞叾浠栫被娌℃湁浠涔堝尯鍒紟
  錛掞紟鎵鏈夌殑浠g悊綾婚兘鎵╁睍浜嶱roxy綾伙紝涓涓唬鐞嗙被鍙湁涓涓疄渚嬪彉閲忥紞錛嶈皟鐢ㄥ鐞嗗櫒錛屽畠瀹氫箟鍦≒roxy鐨勮秴綾諱腑錛屼負浜嗗飽琛屼唬鐞嗗璞$殑鑱岃矗錛屾墍闇瑕佺殑浠諱綍闄勫姞鏁版嵁閮藉繀欏誨瓨鍌ㄥ湪璋冪敤澶勭悊鍣ㄤ腑錛?br>   錛擄紟鎵鏈夌殑浠g悊綾婚兘瑕嗙洊浜哋bject涓殑toString,equals鍜宧ashCode,濡備綍鎵鏈夌殑浠g悊鏂規硶涓鏍鳳紝榪欎簺鏂規硶浠呬粎璋冪敤浜嗚皟鐢ㄥ鐞嗗櫒鐨刬nvoke.Object涓殑鍏朵粬鏂規硶clone,getClass娌℃湁琚噸鏂板畾涔夛紟

鎰熻灝辨槸鎶婂師鏉ョ殑鏂規硶錛屾嬁鍒頒唬鐞嗙被閲岄潰鎵ц錛屽湪鎵ц鍓嶅悗鍙互鍔犲叆鑷繁鐨勪唬鐮佽屽凡錛宻pring鐨勶緝錛跡灝辨槸榪欐牱鐨勶紟
渚嬪瓙錛?br>
import java.lang.reflect.*;
import java.util.*;

public class PorxyTest {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Object[] elements = new Object[1000];
  
  for (int i = 0; i < elements.length; i ++) {
   Integer value = i + 1;
   Class[] interfaces = value.getClass().getInterfaces();
   InvocationHandler handler = new TraceHandler(value);
   Object proxy = Proxy.newProxyInstance(null, interfaces, handler);
   elements[i] = proxy;
  }
  Integer key = new Random().nextInt(elements.length) + 1;
  int result = Arrays.binarySearch(elements, key);
  
  if (result >= 0)
   System.out.println(elements[result]);
 }

}

class TraceHandler implements InvocationHandler {
 private Object target;
 public TraceHandler(Object t) {
  target = t;
 }
 
 public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
  System.out.print(target);
  System.out.print("." + m.getName() + "(");
  if (args != null) {
   for (int i = 0; i < args.length; i ++) {
    System.out.print(args[i]);
    if (i < args.length - 1) {
     System.out.print(",");
    }
   }
  }
  System.out.println(")");
  return m.invoke(target, args);
 }
}



liujg 2007-05-24 14:57 鍙戣〃璇勮
]]>
java紼嬪簭鍛樼殑5涓ソ涔犳儻()http://www.tkk7.com/tbest/archive/2006/12/15/88004.htmlliujgliujgFri, 15 Dec 2006 09:27:00 GMThttp://www.tkk7.com/tbest/archive/2006/12/15/88004.htmlhttp://www.tkk7.com/tbest/comments/88004.htmlhttp://www.tkk7.com/tbest/archive/2006/12/15/88004.html#Feedback0http://www.tkk7.com/tbest/comments/commentRss/88004.htmlhttp://www.tkk7.com/tbest/services/trackbacks/88004.htmlhttp://today.java.net/pub/a/today/2006/08/24/five-habits-of-highly-profitable-developers.html


Five Habits of Highly Profitable Software Developers Five Habits of Highly Profitable Software Developers

by Robert J. Miller
08/24/2006

Software developers who have the ability to create and maintain quality software in a team environment are in high demand in today's technology-driven economy. The number one challenge facing developers working in a team environment is reading and understanding software written by another developer. This article strives to help software development teams overcome this challenge.

This article illustrates five habits of software development teams that make them more effective and therefore more profitable. It first will describe the demands the business team puts on its software development team and the software they create. Next it will explain the important differences between state-changing logic and behavior logic. Finally, it will illustrate the five habits using a customer account scenario as a case study.

Demands Placed on Developers by the Business

The business team's job is to determine what new value can be added to the software, while ensuring that the new value is most advantageous to the business. Here, "new value" refers to a fresh product or additional enhancement to an existing product. In other words, the team determines what new features will make the business the most money. A key factor in determining what the next new value will be is how much it will cost to implement. If the cost of implementation exceeds the potential revenue, then the new value will not be added.

The business team demands that the software development team be able to create new value at the lowest possible cost. It also demands that the software development team have the ability to add new value to a product without having the product's implementation costs increase over time. Furthermore, every time the business team requests new value, it demands that value be added without losing any existing value. Over time, the software will accrue enough value that the business team will demand documentation to describe the current value the software provides. Then the business team will use this documentation to help determine what the next new value will be.

Software development teams can best meet these demands by creating easy-to-understand software. Difficult-to-understand software results in inefficiencies throughout the development process. These inefficiencies increase the cost of software development and can include the unexpected loss of existing value, an increase in developer ramp-up time, and the delivery of incorrect software documentation. These inefficiencies can be reduced by converting the business team's demands, even if complex, into simple, easy-to-understand software.

Introducing Key Concepts: State and Behavior

Creating software that is easy to understand starts by creating objects that have state and behavior. "State" is an object's data that persists between method calls. A Java object can hold its state temporarily in its instance variables and can persist it indefinitely by saving it into a permanent data store. Here, a permanent data store can be a database or Web service. "State-changing methods" typically manage an object's data by retrieving it and persisting it to and from a remote data store. "Behavior" is an object's ability to answer questions based on state. "Behavior methods" answer questions consistently without modifying state and are often referred to as the business logic in an application.

Case Study: CustomerAccount object

The following ICustomerAccount interface defines methods an object must implement to manage a customer's account. It defines the ability to create a new active account, to load an existing customer's account status, to validate a prospective customer's username and password, and to validate that an existing account is active for purchasing products.

public interface ICustomerAccount {
//State-changing methods
public void createNewActiveAccount()
throws CustomerAccountsSystemOutageException;
public void loadAccountStatus()
throws CustomerAccountsSystemOutageException;
//Behavior methods
public boolean isRequestedUsernameValid();
public boolean isRequestedPasswordValid();
public boolean isActiveForPurchasing();
public String getPostLogonMessage();
}

Habit 1: Constructor Performs Minimal Work

The first habit is for an object's constructor to do as little work as possible. Ideally, its constructor will only load data into its instance variables using the constructor's parameters. In the following example, creating a constructor that performs minimal work makes the object easier to use and understand because the constructor performs only the simple task of loading data into the object's instance variables:

public class CustomerAccount implements ICustomerAccount{
//Instance variables.
private String username;
private String password;
protected String accountStatus;
//Constructor that performs minimal work.
public CustomerAccount(String username, String password) {
this.password = password;
this.username = username;
}
}

A constructor is used to create an instance of an object. A constructor's name is always the same as the object's name. Since a constructor's name is unchangeable, its name is unable to communicate the work it is performing. Therefore, it is best if it performs as little work as possible. On the other hand, state-changing and behavior method names use descriptive names to convey their more complex intent, as described in "Habit 2: Methods Clearly Convey Their Intent." As this next example illustrates, the readability of the software is high because the constructor simply creates an instance of the object, letting the behavior and state-changing methods do the rest.

Note: The use of "..." in the examples represents code that is necessary to run in a live scenario but is not relevant to the example's purpose.

String username = "robertmiller";
String password = "java.net";
ICustomerAccount ca = new CustomerAccount(username, password);
if(ca.isRequestedUsernameValid() && ca.isRequestedPasswordValid()) {
...
ca.createNewActiveAccount();
...
}

On the other hand, objects with constructors that do more than just load instance variables are harder to understand and more likely to be misused because their names do not convey their intent. For example, this constructor also calls a method that makes a remote call to a database or Web service in order to pre-load an account's status:

//Constructor that performs too much work!
public CustomerAccount(String username, String password)
throws CustomerAccountsSystemOutageException {
this.password = password;
this.username = username;
this.loadAccountStatus();//unnecessary work.
}
//Remote call to the database or web service.
public void loadAccountStatus()
throws CustomerAccountsSystemOutageException {
...
}

A developer can use this constructor and, not realizing it is making a remote call, end up making two remote calls:

String username = "robertmiller";
String password = "java.net";
try {
//makes a remote call
ICustomerAccount ca = new CustomerAccount(username, password);
//makes a second remote call
ca.loadAccountStatus();
} catch (CustomerAccountsSystemOutageException e) {
...
}

Or a developer can reuse this constructor to validate a prospective customer's desired username and password and be forced to make an unnecessary remote call since these behavior methods (isRequestedUsernameValid(), isRequestedPasswordValid()) don't need the account status:

String username = "robertmiller";
String password = "java.net";
try {
//makes unnecessary remote call
ICustomerAccount ca = new CustomerAccount(username, password);
if(ca.isRequestedUsernameValid() && ca.isRequestedPasswordValid()) {
...
ca.createNewActiveAccount();
...
}
} catch (CustomerAccountsSystemOutageException e){
...
}

Habit 2: Methods Clearly Convey Their Intent

The second habit is for all methods to clearly convey their intent through the names they are given. For example, isRequestedUsernameValid() lets the developer know that this method determines whether or not the requested username is valid. In contrast, isGoodUser() can have any number of uses: it can determine if the user's account is active, determine if the requested username and/or password are valid, or determine if the user is a nice person. Since this method is less descriptive, it is more difficult for a developer to figure out what its purpose is. In short, it is better for the method names to be long and descriptive than to be short and meaningless.

Long and descriptive method names help developer teams quickly understand the purpose and function of their software. Moreover, applying this technique to test method names allows the tests to convey the existing requirements of the software. For example, this software is required to validate that requested usernames and passwords are different. Using the method name testRequestedPasswordIsNotValidBecauseItMustBeDifferentThanTheUsername() clearly conveys the intent of the test and, therefore, the requirement of the software.

import junit.framework.TestCase;
public class CustomerAccountTest extends TestCase{
public void testRequestedPasswordIsNotValid
BecauseItMustBeDifferentThanTheUsername(){
String username = "robertmiller";
String password = "robertmiller";
ICustomerAccount ca = new CustomerAccount(username, password);
assertFalse(ca.isRequestedPasswordValid());
}
}

This test method could have easily been named testRequestedPasswordIsNotValid() or even worse testBadPassword(), both of which would make it hard to determine the precise intention of the test. Unclear or ambiguously named test methods result in a loss of productivity. The loss in productivity can be caused by an increase in ramp-up time used to understand the tests, the unnecessary creation of duplicated or conflicting tests, or the destruction of existing value in the object being tested.

Finally, descriptive method names reduce the need for both formal documentation and Javadoc comments.

Habit 3: An Object Performs a Focused Set of Services

The third habit is for each object in the software to be focused on performing a small and unique set of services. Objects that perform a small amount of work are easier to read and more likely to be used correctly because there is less code to digest. Moreover, each object in the software should perform a unique set of services because duplicating logic wastes development time and increases maintenance costs. Suppose in the future, the business team requests an update to the isRequestedPasswordValid() logic and two different objects have similar methods that perform the same work. In this case, the software development team would spend more time updating both objects than they would have had to spend updating just one.

As the case study illustrates, the purpose of the CustomerAccount object is to manage an individual customer's account. It first creates the account and later can validate that the account is still active for purchasing products. Suppose in the future, this software will need to give discounts to customers who have purchased more than ten items. Creating a new interface, ICustomerTransactions, and object, CustomerTransactions, to implement these new features will facilitate the ongoing goal of working with easy-to-understand software:

public interface ICustomerTransactions {
//State-changing methods
public void createPurchaseRecordForProduct(Long productId)
throws CustomerTransactionsSystemException;
public void loadAllPurchaseRecords()
throws CustomerTransactionsSystemException;
//Behavior method
public void isCustomerEligibleForDiscount();
}

This new object holds state-changing and behavior methods that store customer transactions and determine when a customer gets its ten-product discount. It should be easy to create, test, and maintain since it has a simple and focused purpose. The less effective approach is to add these new methods to the existing ICustomerAccount interface and CustomerAccount object, as seen below:

public interface ICustomerAccount {
//State-changing methods
public void createNewActiveAccount()
throws CustomerAccountsSystemOutageException;
public void loadAccountStatus()
throws CustomerAccountsSystemOutageException;
public void createPurchaseRecordForProduct(Long productId)
throws CustomerAccountsSystemOutageException;
public void loadAllPurchaseRecords()
throws CustomerAccountsSystemOutageException;
//Behavior methods
public boolean isRequestedUsernameValid();
public boolean isRequestedPasswordValid();
public boolean isActiveForPurchasing();
public String getPostLogonMessage();
public void isCustomerEligibleForDiscount();
}

As seen above, allowing objects to become large repositories of responsibility and purpose makes them harder to read and more likely to be misunderstood. Misunderstandings result in a loss in productivity, costing the business team time and money. In short, it is better for objects and their methods to be focused on performing a small unit of work.

Habit 4: State-Changing Methods Contain Minimal Behavior Logic

The fourth habit is for state-changing methods to contain a minimal amount of behavior logic. Intermixing state-changing logic with behavior logic makes the software more difficult to understand because it increases the amount of work happening in one place. State-changing methods typically retrieve or send data to a remote data store and, therefore, are prone to have problems in the production system. Diagnosing a system problem within a state-changing method is easier when the remote call is isolated and it has zero behavior logic. Intermixing also inhibits the development process because it makes it harder to unit test the behavior logic. For example, getPostLogonMessage() is a behavior method with logic based on the accountStatus's value:

public String getPostLogonMessage() {
if("A".equals(this.accountStatus)){
return "Your purchasing account is active.";
} else if("E".equals(this.accountStatus)) {
return "Your purchasing account has " +
"expired due to a lack of activity.";
} else {
return "Your purchasing account cannot be " +
"found, please call customer service "+
"for assistance.";
}
}

loadAccountStatus() is a state-changing method that loads the accountStatus's value from a remote data store:

public void loadAccountStatus()
throws CustomerAccountsSystemOutageException {
Connection c = null;
try {
c = DriverManager.getConnection("databaseUrl", "databaseUser",
"databasePassword");
PreparedStatement ps = c.prepareStatement(
"SELECT status FROM customer_account "
+ "WHERE username = ? AND password = ? ");
ps.setString(1, this.username);
ps.setString(2, this.password);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
this.accountStatus=rs.getString("status");
}
rs.close();
ps.close();
c.close();
} catch (SQLException e) {
throw new CustomerAccountsSystemOutageException(e);
} finally {
if (c != null) {
try {
c.close();
} catch (SQLException e) {}
}
}
}

Unit testing the getPostLogonMessage() method can easily be done by mocking the loadAccountStatus() method. Each scenario can then be tested without making a remote call to a database. For example, if the accountStatus is "E" for expired, then getPostLogonMessage() should return "Your purchasing account has expired due to a lack of activity," as follows:

public void testPostLogonMessageWhenStatusIsExpired(){
String username = "robertmiller";
String password = "java.net";
class CustomerAccountMock extends CustomerAccount{
...
public void loadAccountStatus() {
this.accountStatus = "E";
}
}
ICustomerAccount ca = new CustomerAccountMock(username, password);
try {
ca.loadAccountStatus();
}
catch (CustomerAccountsSystemOutageException e){
fail(""+e);
}
assertEquals("Your purchasing account has " +
"expired due to a lack of activity.",
ca.getPostLogonMessage());
}

The inverse approach is to put both the getPostLogonMessage() behavior logic and the loadAccountStatus() state-changing work into one method. The following example illustrates what not to do:

public String getPostLogonMessage() {
return this.postLogonMessage;
}
public void loadAccountStatus()
throws CustomerAccountsSystemOutageException {
Connection c = null;
try {
c = DriverManager.getConnection("databaseUrl", "databaseUser",
"databasePassword");
PreparedStatement ps = c.prepareStatement(
"SELECT status FROM customer_account "
+ "WHERE username = ? AND password = ? ");
ps.setString(1, this.username);
ps.setString(2, this.password);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
this.accountStatus=rs.getString("status");
}
rs.close();
ps.close();
c.close();
} catch (SQLException e) {
throw new CustomerAccountsSystemOutageException(e);
} finally {
if (c != null) {
try {
c.close();
} catch (SQLException e) {}
}
}
if("A".equals(this.accountStatus)){
this.postLogonMessage = "Your purchasing account is active.";
} else if("E".equals(this.accountStatus)) {
this.postLogonMessage = "Your purchasing account has " +
"expired due to a lack of activity.";
} else {
this.postLogonMessage = "Your purchasing account cannot be " +
"found, please call customer service "+
"for assistance.";
}
}

In this implementation the behavior method getPostLogonMessage() contains zero behavior logic and simply returns the instance variable this.postLogonMessage. This implementation creates three problems. First, it makes it more difficult to understand how the "post logon message" logic works since it is embedded in a method performing two tasks. Second, the getPostLogonMessage() method's reuse is limited because it must always be used in conjunction with the loadAccountStatus() method. Finally, in the event of a system problem the CustomerAccountsSystemOutageException will be thrown, causing the method to exit before it sets this.postLogonMessage's value.

This implementation also creates negative side effects in the test because the only way to unit test this getPostLogonMessage() logic is to create a CustomerAccount object with a username and password for an account in the database with an accountStatus set to "E" for expired. The result is a test that makes a remote call to a database. This causes the test to run slower and to be prone to unexpected failures due to changes in the database. This test has to make a remote call to a database because the loadAccountStatus() method also contains the behavior logic. If the behavior logic is mocked, then the test is testing the mocked object's behavior instead of the real object's behavior.

Habit 5: Behavior Methods Can Be Called in Any Order

The fifth habit is to ensure that each behavior method provides value independent of any other behavior method. In other words, an object's behavior methods can be called repeatedly and in any order. This habit allows the object to deliver consistent behavior. For example, CustomerAccount's isActiveForPurchasing() and getPostLogonMessage() behavior methods both use the accountStatus's value in their logic. Each of these methods should be able to function independently of the other. For instance, one scenario can require that isActiveForPurchasing() be called, followed by a call to getPostLogonMessage():

ICustomerAccount ca = new CustomerAccount(username, password);
ca.loadAccountStatus();
if(ca.isActiveForPurchasing()){
//go to "begin purchasing" display
...
//show post logon message.
ca.getPostLogonMessage();
} else {
//go to "activate account" display
...
//show post logon message.
ca.getPostLogonMessage();
}

A second scenario can require that getPostLogonMessage() is called without isActiveForPurchasing() ever being called:

ICustomerAccount ca = new CustomerAccount(username, password);
ca.loadAccountStatus();
//go to "welcome back" display
...
//show post logon message.
ca.getPostLogonMessage();

The CustomerAccount object will not support the second scenario if getPostLogonMessage() requires isActiveForPurchasing() to be called first. For example, creating the two methods to use a postLogonMessage instance variable so that its value can persist between method calls supports the first scenario but not the second:

public boolean isActiveForPurchasing() {
boolean returnValue = false;
if("A".equals(this.accountStatus)){
this.postLogonMessage = "Your purchasing account is active.";
returnValue = true;
} else if("E".equals(this.accountStatus)) {
this.postLogonMessage = "Your purchasing account has " +
"expired due to a lack of activity.";
returnValue = false;
} else {
this.postLogonMessage = "Your purchasing account cannot be " +
"found, please call customer service "+
"for assistance.";
returnValue = false;
}
return returnValue;
}
public String getPostLogonMessage() {
return this.postLogonMessage;
}

On the other hand, if both methods derive their logic independently of each other, then they will support both scenarios. In this preferred example, postLogonMessage is a local variable created exclusively by the getPostLogonMessage() method:

public boolean isActiveForPurchasing() {
return this.accountStatus != null && this.accountStatus.equals("A");
}
public String getPostLogonMessage() {
if("A".equals(this.accountStatus)){
return "Your purchasing account is active.";
} else if("E".equals(this.accountStatus)) {
return "Your purchasing account has " +
"expired due to a lack of activity.";
} else {
return "Your purchasing account cannot be " +
"found, please call customer service "+
"for assistance.";
}
}

An added benefit of making these two methods independent of each other is that the methods are easier to comprehend. For example, isActiveForPurchasing() is more readable when it is only trying to answer the "is active for purchasing" question as opposed to when it is also trying to set the "post logon message". Another added benefit is that each method can be tested in isolation, which also makes the tests easier to comprehend:

public class CustomerAccountTest extends TestCase{
public void testAccountIsActiveForPurchasing(){
String username = "robertmiller";
String password = "java.net";
class CustomerAccountMock extends CustomerAccount{
...
public void loadAccountStatus() {
this.accountStatus = "A";
}
}
ICustomerAccount ca = new CustomerAccountMock(username, password);
try {
ca.loadAccountStatus();
} catch (CustomerAccountsSystemOutageException e) {
fail(""+e);
}
assertTrue(ca.isActiveForPurchasing());
}
public void testGetPostLogonMessageWhenAccountIsActiveForPurchasing(){
String username = "robertmiller";
String password = "java.net";
class CustomerAccountMock extends CustomerAccount{
...
public void loadAccountStatus() {
this.accountStatus = "A";
}
}
ICustomerAccount ca = new CustomerAccountMock(username, password);
try {
ca.loadAccountStatus();
} catch (CustomerAccountsSystemOutageException e) {
fail(""+e);
}
assertEquals("Your purchasing account is active.",
ca.getPostLogonMessage());
}
}

Conclusion

Following these five habits will help development teams create software that everyone on the team can read, understand, and modify. When software development teams create new value too quickly and without consideration for the future, they tend to create software with increasingly high implementation costs. Inevitably, bad practices will catch up to these teams when they have to revisit the software for future comprehension and modification. Adding new value to existing software can be very expensive if the software is difficult to comprehend. However, when development teams apply these best practices, they will provide new value at the lowest possible cost to their business team.

 




liujg 2006-12-15 17:27 鍙戣〃璇勮
]]>
主站蜘蛛池模板: 国产乱辈通伦影片在线播放亚洲 | 在线视频观看免费视频18| 亚洲丰满熟女一区二区v| 日韩在线看片免费人成视频播放 | 三年片在线观看免费大全| 亚洲日韩在线中文字幕综合| 亚洲熟妇无码八AV在线播放| 美女视频黄的全免费视频网站| 看全免费的一级毛片| 亚洲自偷自偷精品| 小小影视日本动漫观看免费| 暖暖在线视频免费视频| 亚洲一卡2卡三卡4卡无卡下载| 国产亚洲精品免费视频播放| 可以免费看的卡一卡二| 中文字幕在线视频免费| 亚洲Av高清一区二区三区| 亚洲中文字幕在线乱码| 女人18毛片特级一级免费视频 | 国产午夜成人免费看片无遮挡| 一本天堂ⅴ无码亚洲道久久| 亚洲色大成网站WWW久久九九 | 亚洲成在人天堂一区二区| 国产在线19禁免费观看| 3344永久在线观看视频免费首页| 色屁屁www影院免费观看视频| 91在线精品亚洲一区二区| 亚洲日韩在线第一页| 最近免费中文字幕大全视频| 久久狠狠躁免费观看| 国产成人亚洲综合a∨| 亚洲一区无码中文字幕乱码| 日韩亚洲欧洲在线com91tv| 亚洲成a人片在线播放| 无码免费午夜福利片在线 | jizz免费观看视频| 亚洲欧美成人一区二区三区| 亚洲美免无码中文字幕在线| 最新国产AV无码专区亚洲| 四虎在线播放免费永久视频| 成人a视频片在线观看免费|