Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Èÿª·¢×Ô¶¯»¯³ÖÐøÖØ¹¹ --ʹÓþ²Ì¬·ÖÎö¹¤¾ßʶ±ð´úÂëζµÀ
 
  3849  次浏览      28
 2018-1-2  
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚibm£¬ÎÄÖÐÍÆ³çµÄ¾ÍÊÇЧÂÊ£¬ÈçºÎ¼õÉÙºÄʱ¹ý³ÌµÄÈßÓà¶È£¬¸ü¿ìËÙµØÖ´ÐÐËüÃÇ£¬²¢ÇÒ½«ÂÛÊöÔõÑù¸ü ÓÐЧµØÖ´ÐÐËüÃÇ¡£

 

ÔÚ¹ýÈ¥µÄ¼¸ÄêÀÎÒÔø¿´¹ýºÜ¶àÏîÄ¿µÄ´óÁ¿Ô´´úÂ룬´Ó¾«ÃÀµÄÉè¼Æµ½ÏñÊÇÓýº´ø°ó¶¨µ½Ò»ÆðµÄ´úÂë¡£ÎÒд¹ýеĴúÂëҲά»¤¹ýÆäËû¿ª·¢ÈËÔ±µÄÔ´´úÂë¡£ÎÒϲ»¶±àдеĴúÂ룬µ«Ò²Ï²»¶²ÉÓÃһЩÏÖÓеĴúÂ룬ÒÔijÖÖ·½·¨½«Æä¼ò»¯»ò½«Öظ´µÄ´úÂëÌáÈ¡µ½Ò»¸ö¹«¹²ÀàÖС£ÔÚÎÒÔçÆÚµÄ¹¤×÷ÉúÑÄÖУ¬Ðí¶àÈ˶¼ÈÏΪÈç¹û²»±àдеĴúÂë¾Í²»»áÓкõÄЧÂÊ¡£ÐҺã¬ÔÚ 20 ÊÀ¼Í 90 Äê´úÄ©£¬Martin Fowler ±àдÁË RefactoringÒ»Ê飨²Î¼û ²Î¿¼×ÊÁÏ£©£¬ËüʹµÃÔÚ²»¸Ä±äÍⲿÐÐΪµÄǰÌáϸĽøÏÖÓдúÂë³ÉΪ¿ÉÄÜ¡£

¹ØÓÚ±¾ÏµÁÐ

×÷Ϊ¿ª·¢ÈËÔ±£¬ÎÒÃÇÖÂÁ¦ÓÚΪÓû§×Ô¶¯»¯Á÷³Ì£»µ«Ðí¶à¿ª·¢ÈËÔ±ÊèºöÁË×Ô¶¯»¯ÎÒÃÇ×Ô¼ºµÄ¿ª·¢Á÷³ÌµÄ»ú»á¡£Îª´Ë£¬ÎÒÃDZàдÁË Èÿª·¢×Ô¶¯»¯ÏµÁÐÎÄÕ£¬×¨ÃÅ̽ÌÖÈí¼þ¿ª·¢Á÷³Ì×Ô¶¯»¯µÄʵ¼ùÓ¦Óã¬ÎªÄú½éÉÜ ºÎʱÒÔ¼° ÈçºÎ³É¹¦Ó¦ÓÃ×Ô¶¯»¯¡£

ÖØ¹¹µÄÒ»¸öµäÐÍ·½·¨ÊÇÔÚÒýÈëдúÂë»ò¸ü¸Ä·½·¨Ê±¶ÔÏÖÓдúÂë×ö³öССµÄ±ä¶¯¡£¸Ã¼¼ÇÉÃæÁÙµÄÌôÕ½ÔÚÓÚÒ»¸ö¿ª·¢ÍŶӵĿª·¢ÈËÔ±µÄÓ¦Ó÷½·¨²»Ò»Ö£¬²¢ÇÒºÜÈÝÒ×´íÊ§ÖØ¹¹µÄ»ú»á¡£ÕâÒ²ÕýÊÇÎÒÌᳫʹÓþ²Ì¬·ÖÎö¹¤¾ßʶ±ð±àÂëÎ¥¹æµÄÔ­ÒòËùÔÚ¡£ÓÐÁËÕâЩ¹¤¾ß£¬Äú¾ÍÄܹ»´Ó×ÜÌåÉÏÁ˽â´úÂë¿â£¬²¢ÇÒ´¦ÓÚÀà»ò·½·¨µÄ¼¶±ð¡£ÐÒÔ˵ÄÊÇ£¬ÔÚ Java?³ÌÐòÉè¼ÆÖУ¬Äú¿ÉÒÔÑ¡ÔñµÄ¿ÉÃâ·ÑÏÂÔØµÄ¿ªÔ´¾²Ì¬·ÖÎö¹¤¾ßºÜ¶à£ºCheckStyle¡¢PMD¡¢FindBugs¡¢JavaNCSS¡¢JDepend µÈµÈ¡£

ÔÚ±¾ÎÄÖУ¬Äú½«Ñ§Ï°ÈçºÎ£º

ʹÓà CheckStyle ¶ÈÁ¿ Ȧ¸´ÔÓ¶È£¨cyclomatic complexity£©£¬²¢ÌṩÖîÈç Replace Conditional with PolymorphismÖ®ÀàµÄÖØ¹¹£¬ÒÔ´ËÀ´¼õÉÙ Ìõ¼þ¸´ÔÓ¶È´úÂëζµÀ

ʹÓà CheckStyle ÆÀ¹À ´úÂëÖØ¸´ÂÊ£¬²¢ÌṩÖîÈç Pull Up MethodÖ®ÀàµÄÖØ¹¹£¬ÒÔ´ËÀ´ÒƳý ÖØ¸´´úÂë

ʹÓà PMD£¨»ò JavaNCSS£©¼ÆËã Ô´´úÂëÐУ¬²¢ÌṩÖîÈç Extract MethodÖ®ÀàµÄÖØ¹¹£¬ÒÔ´ËÀ´µ­»¯ ´óÀà´úÂëζµÀ

ʹÓà CheckStyle£¨»ò JDepend£©È·¶¨Ò»¸öÀàµÄ ´«³öñîºÏ¶È£¨efferent coupling£©£¬²¢ÌṩÖîÈç Move MethodÖ®ÀàµÄÖØ¹¹£¬ÒÔ´ËÀ´³ýµô ¹ý¶àµÄµ¼Èë´úÂëζµÀ

ÎÒ½«Ê¹ÓÃÈçϵÄͨÓøñʽÀ´¼ì²éÿһÖÖ´úÂëζµÀ£º

ÃèÊö¿ÉÒÔָʾ³ö´úÂëÀïÃæµÄÎÊÌâµÄζµÀ

¶¨Òå¿ÉÒÔÕÒµ½¸ÃζµÀµÄ¶ÈÁ¿·½·¨

չʾ¿ÉÒÔ¶ÈÁ¿´úÂëζµÀµÄ¹¤¾ß

ÌṩÓÃÓÚÐÞ¸´´úÂëζµÀµÄÖØ¹¹ºÍģʽ£¨ÔÚijЩÇé¿öÏ£©

ʵÖÊÉÏ£¬Õâ¸ö·½·¨ÌṩÁËÒ»¸öÕÒµ½ºÍÐÞ¸´Õû¸ö´úÂë¿âÖеĴúÂëζµÀµÄÒ»¸ö¿ò¼Ü¡£ÕâÑùÄú¾Í¿ÉÒÔ¸üºÃµØÁ˽⵽´úÂë¿âÖнÏΣÏյIJ¿·Ö£¬È»ºóÔÙ×ö³ö¸ü¸Ä¡£¸üºÃµÄÊÇ£¬ÎÒ»¹»áÏòÄúչʾÈçºÎ½«Õâ¸ö·½·¨¼¯³Éµ½×Ô¶¯¹¹½¨ÖС£

ÄúµÄ´úÂëÓРô£¿

Ëùν´úÂëζµÀÆäʵֻÊÇÒ»ÖÖ Ìáʾ£¬ÌáʾһЩÄÚÈÝ¿ÉÄÜ´æÔÚ´íÎ󡣺ÍģʽÀàËÆ£¬´úÂëζµÀÌṩÁËÒ»¸öͨÓôʻã±í£¬Äú¿ÉÒÔÓÃËüÀ´¿ìËÙʶ±ðÕâЩÀàÐ͵ÄDZÔÚÎÊÌâ¡£ÔÚÎÄÕÂÖÐ ÕæÊµµØÊ¾·¶´úÂëζµÀÊǺÜÓÐÄѶȵģ¬ÒòΪËü¿ÉÄܰüÀ¨ºÜ¶àÐдúÂ룬ÕâÑù¾Í¹ý·ÖµØ¼Ó´óÁËÎÄÕÂµÄÆª·ù¡£Òò´Ë£¬ÎÒ»áÖ»Õë¶ÔÆäÖеÄһЩζµÀ½øÐÐʾ·¶£¬È»ºóÄú¾Í¿ÉÒÔ¸ù¾Ý²é¿´Ìض¨´úÂëζµÀµÄ¾­Ñé½øÐÐÍÆ¶Ï£¬Ê¶±ð³öÊ£ÓàµÄ´úÂëζµÀ¡£

Ìõ¼þ¸´ÔÓ¶È

ζµÀ£ºÌõ¼þ¸´ÔÓ¶È

¶ÈÁ¿£ºÈ¦¸´ÔÓ¶È

¹¤¾ß£ºCheckStyle¡¢JavaNCSS ÒÔ¼° PMD

ÖØ¹¹£ºReplace Conditional with Polymorphism¡¢Extract Method

ζµÀ

Ìõ¼þ¸´ÔÓ¶È¿ÉÒÔÒÔ¼¸ÖÖ²»Í¬µÄ·½Ê½³öÏÖÔÚÔ´´úÂëÖС£ÕâÖÖ´úÂëζµÀµÄÒ»¸öÀý×Ó¾ÍÊǺ¬Óжà¸öÌõ¼þÓï¾ä£¬Èç if¡¢while»òÕß forÓï¾ä¡£ÁíÒ»ÖÖÌõ¼þ¸´ÔÓ¶ÈÊÇÒÔ switchÓï¾äµÄÐÎʽ³ÊÏÖ³öÀ´µÄ£¬ÈçÇåµ¥ 1 Ëùʾ£º

Çåµ¥ 1. ʹÓà switchÓï¾äÀ´Ö´ÐÐÌõ¼þÐÐΪ

...

switch
(beerType) {

case
LAGER:

System.out.println("Ingredients
are...");

...

break;

case
BROWNALE:

System.out.println("Ingredients
are...");

...

break;

case
PORTER

System.out.println("Ingredients
are...");

...

break;

case
STOUT:

System.out.println("Ingredients
are...");

...

break;

case
PALELAGER:

System.out.println("Ingredients
are...");

...

break;

...

default:

System.out.println("INVALID.");

...

break;

}

...

switchÓï¾ä±¾Éí²¢Ã»Óв»Íס£µ«µ±Ò»¸öÓï¾ä°üº¬Ì«¶àµÄÑ¡ÔñºÍ´úÂëʱ£¬Ëü¾Í¿ÉÄܰµÊ¾ÓÐÐèÒªÖØ¹¹µÄ´úÂë¡£

¶ÈÁ¿

Ҫȷ¶¨Ìõ¼þ¸´ÔÓ¶È´úÂëζµÀ£¬ÐèҪȷ¶¨·½·¨µÄ Ȧ¸´ÔÓ¶È¡£È¦¸´ÔÓ¶ÈÊÇÒ»ÖÖ¶ÈÁ¿·½·¨£¬ÓÉ Thomas McCabe ÓÚ 1975 Ä궨Ò塣Ȧ¸´ÔÓ¶ÈÊý£¨Cyclomatic Complexity Number£¬CCN£©¶ÈÁ¿Ò»¸ö·½·¨ÖÐijһ·¾¶µÄÊýÁ¿¡£ÎÞÂÛÒ»¸ö·½·¨ÖÐÓжàÉÙÌõ·¾¶£¬ËüµÄÆðʼ CNN ¶¼´Ó 1 ¿ªÊ¼¡£Ã¿Ò»¸öÌõ¼þ¹¹Ô죬Èç if¡¢switch¡¢whileºÍ forÓï¾ä£¬¶¼±»·ÖÅäÒ»¸ö 1 ÖµºÍÒ쳣·¾¶¡£Ò»¸ö·½·¨µÄ×ÜµÄ CCN ±íÃ÷ÁËËüµÄ¸´ÔÓ¶È¡£ºÜ¶àÈËÈÏΪµ± CCN Ϊ 10 »ò³¬¹ý 10 ʱ£¬¾Í±íÃ÷¸Ã·½·¨¹ýÓÚ¸´ÔÓ¡£

¹¤¾ß

CheckStyle¡¢JavaNCSS¡¢ÒÔ¼° PMD ¶¼ÊǶÈÁ¿È¦¸´ÔӶȵĿªÔ´¹¤¾ß¡£Çåµ¥ 2 չʾÁËÓà XML ¶¨ÒåµÄ CheckStyle ¹æÔòÎļþµÄÒ»¸ö´úÂëÆ¬¶Ï¡£CyclomaticComplexityÄ£¿é¶¨ÒåÁËÒ»¸ö·½·¨µÄ CCN µÄ×î´óÏÞ¶È¡£

Çåµ¥ 2. ÅäÖà CheckStyle£¬²éÕÒȦ¸´ÔÓ¶ÈΪ 10 »ò´óÓÚ 10 µÄ·½·¨

<module

name="CyclomaticComplexity">

<property

name="max"

value="10"/>

</module>

ÓÃÇåµ¥ 2 µÄ CheckStyle ¹æÔòÎļþ¡¢Çåµ¥ 3 µÄ Gant Àý×ÓÀ´Ê¾·¶ÈçºÎ½« CheckStyle ×÷Ϊһ¸ö×Ô¶¯¹¹½¨µÄÒ»²¿·ÖÀ´ÔËÐС££¨²Î¼û ʲôÊÇ Gant £¿²à±ßÀ¸£©£º

Çåµ¥ 3. ʹÓà Gant ½Å±¾À´Ö´ÐÐ CheckStyle ¼ì²é

target(findHighCcn:"Finds
method with a high cyclomatic complexity number"){

Ant.mkdir(dir:"target/reports")

Ant.taskdef(name:"checkstyle",

classname:"com.puppycrawl.tools.checkstyle.CheckStyleTask",

classpathref:"build.classpath")

Ant.checkstyle(shortFilenames:"true",
config:"config/checkstyle/cs_checks.xml",

failOnViolation:"false",
failureProperty:"checks.failed", classpathref:"libdir") {

formatter(type:"xml",
tofile:"target/reports/checkstyle_report.xml")

formatter(type:"html",
tofile:"target/reports/checkstyle_report.html")

fileset(dir:"src"){

include(name:"**/*.java")

}

}

}

ʲôÊÇ Gant £¿

Gant ÊÇÒ»¸ö×Ô¶¯¹¹½¨¹¤¾ß£¬ËüÌṩÁËÒ»¸öÖ§³Ö¹¹½¨ÒÀÀµ¹ØÏµµÄ±í´ïÄÜÁ¦Ç¿µÄ±à³ÌÓïÑÔ¡£¿ª·¢ÈËÔ±ÀûÓà Groovy ±à³ÌÓïÑÔµÄÇ¿´ó¹¦Äܱàд Gant ½Å±¾¡£ÓÉÓÚ Gant Ìṩ¶Ô Ant µÄ API µÄÍêÈ«·ÃÎÊ£¬ËùÒÔÈκοÉÒÔÔËÐÐÓÚ Ant µÄ¶«Î÷¶¼¿ÉÒÔ´Ó Gant ½Å±¾ÔËÐС££¨²Î¼û ¡°Óà Gant ¹¹½¨Èí¼þ¡± ½Ì³Ì£¬Á˽â Gant¡££©

Çåµ¥ 3 ÖÐµÄ Gant ½Å±¾´´½¨ÁËͼ 1 ÖÐչʾµÄ CheckStyle ±¨¸æ¡£¸ÃͼÏÂÃæµÄ²¿·Öָʾ³öÁËÒ»¸ö·½·¨µÄ CheckStyle Ȧ¸´ÔÓ¶ÈÎ¥¹æ¡£

ͼ 1. CheckStyle ±¨¸æ¸ù¾Ý¹ý¸ßµÄ CCN À´Ö¸Ê¾Ò»ÖÖ·½·¨Ê§°Ü

ÖØ¹¹

ͼ 2 ΪÓà UML ±íʾµÄ Replace Conditional with PolymorphismÖØ¹¹£º

ͼ 2. ÓöàÌ¬Ìæ´úÌõ¼þÓï¾ä

ÔÚͼ 2 ÖУ¬ÎÒ£º

´´½¨ÁËÒ»¸ö½Ð×ö BeerTypeµÄ Java ½çÃæ

¶¨ÒåÁËÒ»¸öͨÓÃµÄ showIngredients()·½·¨

Ϊÿһ¸ö BeerType´´½¨ÁËÒ»¸öʵÏÖÀà

ΪÁËʹÎÄÕ±£³Ö¼ò½à£¬ÎÒ½öΪÿһ¸öÀàÌṩһ¸ö·½·¨µÄʵÏÖ¡£ÏÔÈ»£¬´´½¨Ò»¸ö½çÃæµÄ·½·¨¿ÉÄܲ»Ö»Ò»¸ö¡£Öع¹Äܹ»Ê¹´úÂë¸üÒ×ÓÚά»¤£¬Èç Replace Conditional with Polymorphism ºÍ Extract Method£¨±¾ÎÄÉԺ󽫻áÌÖÂÛ£©¡£

ÖØ¸´´úÂë

ζµÀ£ºÖظ´´úÂë

¶ÈÁ¿£º´úÂëÖØ¸´ÂÊ

¹¤¾ß£ºCheckStyle¡¢PMD

ÖØ¹¹£ºExtract Method¡¢Pull Up Method¡¢Form Template Method¡¢Substitute Algorithm

ζµÀ

ÖØ¸´´úÂë¿ÉÄÜÔÚ´úÂë¿âÖÐÇÄÈ»·¢Éú¡£ÓÐʱ£¬¸´ÖÆÕ³ÌùijЩ´úÂëÒª±È½«¸ÃÐÐΪ·º»¯µ½ÁíÒ»¸öÀà¸ü¼òµ¥¡£µ«¸´ÖÆÕ³ÌùµÄ·½·¨´æÔÚÒ»¸öÎÊÌ⣬¼´ËüÇ¿ÖÆ½«´úÂë¸´ÖÆ¶à·Ý£¬²¢ÇÒÐèҪά»¤¡£¶øÇÒµ±¸´ÖƳöµÄ´úÂë·¢ÉúÇá΢µÄ±ä»¯¶øÒý·¢ÐÐΪ²»Ò»ÖÂʱ£¬¾Í»á·¢Éú¸ü²»Òײì¾õµÄÎÊÌ⣬¾ßÌåÈ¡¾öÓÚÄĸö·½·¨ÔÚÖ´ÐиÃÐÐΪ¡£Çåµ¥ 4 ÊÇÒ»¸ö¹Ø±Õ´úÂë¿âÁ¬½ÓµÄ´úÂëʾÀý£¬ÏàͬµÄ´úÂë³öÏÖÔÚÁ½ÖÖ·½·¨ÖУº

Çåµ¥ 4. ÖØ¸´´úÂë

public
Collection findAllStates(String sql) {

...

try
{

if
(resultSet != null) {

resultSet.close();

}

if
(stmt != null) {

stmt.close();

}

if
(conn != null) {

conn.close();

}

catch
(SQLException se) {

throw
new RuntimeException(se);

}

}

...

}

...

public
int create(String sql, Beer beer) {

...

try
{

if
(resultSet != null) {

resultSet.close();

}

if
(stmt != null) {

stmt.close();

}

if
(conn != null) {

conn.close();

}

catch
(SQLException se) {

throw
new RuntimeException(se);

}

}

...

}

ÎÒÓÐÐÔÄܸüºÃµÄ IDE

ËäÈ»ÔÚ±¾ÎĵÄÀý×ÓÖÐÎÒʹÓà Gant À´ÔËÐвéÕÒÌØ¶¨Î¶µÀµÄ¹¤¾ß£¬µ«ÊÇʹÓà IDE ҲͬÑù¿ÉÒÔ½â¾öÕâЩÎÊÌâ¡£Eclipse IDE ¾ÍÓкܶྲ̬·ÖÎö¹¤¾ßµÄ²å¼þ¡£µ«ÎÒÈÔÈ»ÍÆ¼öʹÓÃ×Ô¶¯¹¹½¨¹¤¾ß£¬ÒòΪÕâÑù¿ÉÒÔÔÚÆäËû»·¾³ÖÐÔËÐм¯³É¹¹½¨£¬ÎÞÐèʹÓà IDE¡£

¶ÈÁ¿

²éÕÒÖØ¸´´úÂëµÄ¶ÈÁ¿·½·¨ÊÇÔÚ´úÂë¿âÖеÄÀàµÄÄÚ²¿ºÍÆäËûÀàÖ®¼äËÑË÷´úÂëÖØ¸´¡£Ã»Óй¤¾ßµÄ»°£¬Àà¼äµÄÖØ¸´¾Í¸üÄÑÆÀ¹À¡£ÓÉÓÚ¸´ÖƵĴúÂëͨ³£¶¼»á·¢ÉúһЩÇá΢µÄ±ä»¯£¬Òò´Ë²»½öÒª¶ÈÁ¿ÍêÈ«ÏàͬµÄ´úÂ룬¶øÇÒÒª¶ÈÁ¿ ÏàËÆµÄ´úÂ룬Á½Õß¶¼ºÜÖØÒª¡£

¹¤¾ß

PMD µÄ Copy/Paste Detector£¨CPD£©Óë CheckStyle ÕâÁ½ÖÖ¿ªÔ´¹¤¾ß¿ÉÒÔÓÃÓÚÔÚÕû¸ö Java ´úÂë¿âÖвéÕÒÏàËÆµÄ´úÂë¡£Çåµ¥ 5 ÖÐµÄ CheckStyle ÅäÖÃÎļþÀý×Óʾ·¶ÁËÈçºÎʹÓà StrictDuplicateCodeÄ£¿é£º

Çåµ¥ 5. ʹÓà CheckStyle ÕÒµ½ÖÁÉÙ 10 ÐÐÖØ¸´´úÂë

<module

name="StrictDuplicateCode">

<property

name="min"

value="10"/>

</module>

Çåµ¥ 5 ÖÐµÄ minÊôÐÔÉèÖÃÁË CheckStyle ½«»á±ê¼Ç³öµÄ×îÐ¡ÖØ¸´ÐÐÊý£¬ÒÔ¹©²éÔÄ¡£ÔÚÕâÑùµÄÇé¿öÏ£¬Ëü½«Ö»Ö¸Ê¾³öÄÇЩÖÁÉÙÓÐ 10 ÐÐÀàËÆ»òÖØ¸´µÄ´úÂë¿é¡£

ͼ 3 չʾÁË×Ô¶¯¹¹½¨ÔËÐкó£¬Çåµ¥ 5 ÖеÄÄ£¿éÉèÖõĽá¹û£º

ͼ 3. CheckStyle ±¨¸æÖ¸Ê¾´úÂëÖØ¸´¶È¹ý¸ß

CheckStyle ±¨¸æÖ¸Ê¾´úÂëÖØ¸´¶È¹ý¸ß

ÖØ¹¹

ÔÚÇåµ¥ 6 ÖУ¬ÎÒÓÃÁË Çåµ¥ 4ÖеÄÖØ¸´´úÂ룬ʹÓÃÁË Pull Up MethodÖØ¹¹À´½µµÍÖØ¸´¶È ¡ª½«ÐÐΪ´Ó½Ï´ó·½·¨ÌáÈ¡µ½Ò»¸ö³éÏóÀà·½·¨ÖУº

Çåµ¥ 6. Pull Up Method

...

}
finally {

closeDbConnection(rs,
stmt, conn);

}

...

²»ÒªÍü¼Ç±àд²âÊÔ³ÌÐò

ÈκÎʱºò¸Ä±äÏÖÓдúÂ룬Äú¶¼ÐèÒªÓÃÖîÈç JUnit ÕâÑùµÄ¿ò¼Ü±àдÏàÓ¦µÄ×Ô¶¯²âÊÔ³ÌÐò¡£ÐÞ¸ÄÏÖÓдúÂëÊÇ´æÔÚ·çÏյģ»¶ø½«Õâ¸ö·çÏÕ½µµ½×îµÍµÄÒ»ÖÖ·½·¨¾ÍÊÇͨ¹ý²âÊÔÀ´ÑéÖ¤¸ÃÐÐΪÔÚÏÖÔںͽ«À´¶¼ÓÐЧ¡£

ÖØ¸´´úÂëÊÇÄÑÒÔ±ÜÃâµÄ¡£ÎÒÓÀÔ¶²»»á½¨ÒéÒ»¸öÍŶÓȥŬÁ¦ÊµÏÖʲô ÎÞÖØ¸´Ö®ÀàµÄÄ¿±ê£¬ÕâÊDz»ÇÐʵ¼ÊµÄ¡£È»¶ø£¬È·±£´úÂë¿âÖеÄÖØ¸´´úÂë²»»áÔö¶àÕâÑùµÄÄ¿±êÊÇ¿ÉÒÔʵÏֵġ£Ê¹ÓÃÖîÈç PMD µÄ CPD »ò CheckStyle ÕâÑùµÄ¾²Ì¬·ÖÎö¹¤¾ß£¬ÄúÄܹ»½«Õû¸ö·ÖÎö¹ý³Ì×÷Ϊ×Ô¶¯¹¹½¨µÄÒ»²¿·Ö£¬³ÖÐø·ÖÎö£¬È·¶¨´úÂëÖØ¸´¶È¸ßµÄÇøÓò¡£

³¤·½·¨£¨´óÀࣩ

ζµÀ£º³¤·½·¨£¨´óÀࣩ

¶ÈÁ¿£ºÔ´´úÂëÐÐÊý£¨SLOC£©

¹¤¾ß£ºPMD¡¢JavaNCSS¡¢CheckStyle

ÖØ¹¹: Extract Method¡¢Replace Temp with Query¡¢Introduce Parameter Object¡¢Preserve Whole Object¡¢Replace Method with Method Object

ζµÀ

ÎÒÒ»Ö±ÔÚ³¢ÊÔ¼á³ÖµÄÒ»Ìõ¾­Ñé·¨ÔòÊǽ«·½·¨ÏÞÖÆÔÚ 20 Ðлò 20 ÐÐÒÔÄÚ¡£µ±È»£¬Õâ¸öÔ­ÔòÒ²¿ÉÄÜ»áÓÐÀýÍ⣬µ«Èç¹ûÎҵķ½·¨³¬¹ý 20 Ðеϰ£¬ÎҾͻá¸ü×ÐϸµØÈ¥Á˽âËü¡£Í¨³£Çé¿öÏ£¬³¤·½·¨ºÍÌõ¼þ¸´ÔÓ¶ÈÊÇϢϢÏà¹ØµÄ¡£¶ø´óÀàÓ볤·½·¨Ö®¼äÓÖÓÐ×űØÈ»µÄÁªÏµ¡£ÎÒ¿ÉÒÔ¸øÄúչʾһ¸ö 2200 Ðеķ½·¨£¬Õâ¸ö·½·¨ÊÇÎÒÔÚÐèҪά»¤µÄÒ»¸öÏîÄ¿ÉÏ·¢Ïֵġ£ÎÒ½«Õû¸öº¬ÓÐ 25000 ÐеĴúÂëµÄÀà´òÓ¡Á˳öÀ´£¬ÈÃÎÒµÄͬÊÂÀ´ÕÒ³öÀïÃæµÄ´íÎó¡£Õâô˵°É£¬µ±ÎÒ°Ñ´òÓ¡³öÀ´µÄ´úÂëÑØ×Å×ßÀȾíÆðÀ´µÄʱºò£¬ËûÃǾÍÒѾ­Í¬ÒâÎҵĿ´·¨ÁË¡£

Çåµ¥ 7 ÖиßÁÁÏÔʾµÄ²¿·ÖչʾÁËÒ»¸ö³¤·½·¨´úÂëζµÀʾÀýµÄһС²¿·Ö£º

Çåµ¥ 7. ³¤·½·¨´úÂëζµÀ

public
void saveLedgerInformation() {

...

try
{

if
(ledger.getId() != null && filename == null) {

getLedgerService().saveLedger(ledger);

}
else {

accessFiles().decompressFiles(files,
filenames);

}

if
(!files.get(0).equals(upload)) {

upload
= files.get(0);

filename
= filenames.get(0);

}

if
(invalidFiles.isUnsupported(filename)) {

setError(fileName,
message.getMessage());

}
else {

LedgerFile
entryFile = accessFiles().add(upload, filename);

if
(fileType != null && FileType.valueOf(fileType) != null) {

entryFile.setFileType(FileType.valueOf(fileType));

}

getFileManagementService().saveLedger(ledger,
entryFile);

if
(!FileStatus.OPENED.equals(entryFile.getFileStatus())) {

getFileManagementService().importLedgerDetails(ledger);

}

if
(uncompressedFiles.size() > 1) {

Helper.saveMessage(getText("ledger.file"));

}

if
(user.getLastName() != null) {

SearchInfo
searchInfo = ServiceLocator.getSearchInfo();

searchInfo.setLedgerInfo(null);

isValid
= false;

setDefaultValues();

resetSearchInfo();

if
(searchInfoValid && ledger != null) {

isValid
= true;

}

}

}
catch (InvalidDataFileException e) {

ResultType
result = e.getResultType();

for
(ValidationMessage message : result.getMessages()) {

setError(fileName,
message.getMessage());

}

ledger.setEntryFile(null);

}
...

¶ÈÁ¿

ÔÚ¹ýÈ¥µÄ¼¸ÄêÀSLOC ¶ÈÁ¿·½·¨±»ÎóÈÏΪÊǸßЧÂʵÄÏóÕ÷¡£¾¡¹ÜÎÒÃǶ¼ÖªµÀ£¬²¢²»Ò»¶¨ÊÇÐÐÊýÔ½¶àÔ½ºÃ¡£µ«Ëµµ½¸´ÔÓ¶È£¬SLOC ¿ÉÊÇÒ»¸öÓÐÓõĶÈÁ¿·½·¨¡£Ò»¸ö·½·¨£¨»òÀࣩµÄÐÐÊýÔ½¶à£¬½«À´Î¬»¤Æä´úÂë¾Í¿ÉÄÜÔ½ÄÑ¡£

¹¤¾ß

Çåµ¥ 8 ÖеĽű¾Îª³¤·½·¨£¨´óÀࣩÕÒµ½ÁË SLOC ¶ÈÁ¿·½·¨£º

Çåµ¥ 8. ʶ±ð¹ý´óµÄÀàºÍ·½·¨µÄ Gant ½Å±¾

target(findLongMethods:"runs
static code analysis"){

Ant.mkdir(dir:"target/reports")

Ant.taskdef(name:"pmd",
classname:"net.sourceforge.pmd.ant.PMDTask",

classpathref:"build.classpath")

Ant.pmd(shortFilenames:"true"){

codeSizeRules.each{
rfile ->

ruleset(rfile)

}

formatter(type:"xml",
tofile:"target/reports/pmd_report.xml")

formatter(type:"html",
tofile:"target/reports/pmd_report.html")

fileset(dir:"src"){

include(name:"**/*.java")

}

}

}

ÎÒÓÖʹÓÃÁË Gant ·ÃÎÊ Ant API À´Ö´ÐÐ Ant ÈÎÎñ¡£ÔÚÇåµ¥ 8 ÖУ¬ÎÒµ÷Óà PMD ¾²Ì¬·ÖÎö¹¤¾ßÀ´ËÑË÷´úÂë¿âÖеij¤·½·¨¡£PMD£¨Á¬Í¬ JavaNCSS Óë CheckStyle£©Ò²¿ÉÒÔÓÃÓÚ²éÕÒ³¤·½·¨¡¢´óÀàÒÔ¼°ÆäËû´úÂëζµÀ¡£

ÖØ¹¹

Çåµ¥ 9 չʾÁËÓà Extract MethodÖØ¹¹À´¼õÉÙ Çåµ¥ 7Öеij¤·½·¨´úÂëζµÀµÄÒ»¸öÀý×Ó¡£½«Çåµ¥ 7 µÄ·½·¨ÖеÄÐÐΪÌáÈ¡µ½Çåµ¥ 9 µÄ´úÂëÖÐÒÔºó£¬ÎҾͿÉÒÔ´ÓÇåµ¥ 7 µÄ saveLedgerInformation()·½·¨Öе÷ÓÃн¨µÄ isUserValid()·½·¨ÁË£º

Çåµ¥ 9. Extract Method ÖØ¹¹

private
boolean isUserValid(User user) {

boolean
isValid = false;

if
(user.getLastName() != null) {

SearchInfo
searchInfo = ServiceLocator.getSearchInfo();

searchInfo.setLedgerInfo(null);

setDefaultValues();

resetSearchInfo();

if
(searchInfoValid && ledger != null) {

isValid
= true;

}

}

return
isValid;

}

ͨ³££¬³¤·½·¨ºÍ´óÀàÒ²°µÊ¾×Å´æÔÚÆäËû´úÂëζµÀ£¬ÈçÌõ¼þ¸´ÔӶȺÍÖØ¸´´úÂë¡£Òò´Ë£¬ÕÒµ½ÕâЩ³¤·½·¨ºÍ´óÀàÒ²¾Í¿ÉÒÔÐÞ¸´ÆäËûµÄÎÊÌâÁË¡£

Ì«¶àµ¼Èë

ζµÀ£ºÌ«¶àµ¼Èë

¶ÈÁ¿£º´«³öñîºÏ£¨Ã¿¸öÀàµÄÉȳö£¨fan-out£©£©

¹¤¾ß£ºCheckStyle

ÖØ¹¹£ºMove Method¡¢Extract Class

ζµÀ

Ì«¶àµ¼Èë±íÃ÷Ò»¸öÀà¹ý¶àµØÒÀÀµÓÚÆäËûµÄÀà¡£Äú»á×¢Òâµ½£¬ÓÉÓÚÒ»¸öÀàÓëºÜ¶àÆäËûµÄÀàñîºÏµÃÌ«½ôÃÜ£¬ÐÞ¸ÄÕâ¸öÀà»áµ¼Ö±ØÐë¶ÔºÜ¶àÆäËûµÄÀà½øÐÐÐ޸ģ¬Õâʱ¾Í˵Ã÷Õâ¸öÀà´æÔÚÕâÖÖ´úÂëζµÀÁË¡£Çåµ¥ 10 ÖеĶà¸öµ¼Èë¾ÍÊÇÒ»¸öÀý×Ó£º

Çåµ¥ 10. Ò»¸öÀàÖеĶà¸öµ¼Èë

import
com.integratebutton.search.SiteQuery;

import
com.integratebutton.search.OptionsQuery;

import
com.integratebutton.search.UserQuery;

import
com.integratebutton.search.VisitsQuery;

import
com.integratebutton.search.SiteQuery;

import
com.integratebutton.search.DateQuery;

import
com.integratebutton.search.EvaluationQuery;

import
com.integratebutton.search.RangeQuery

import
com.integratebutton.search.BuildingQuery;

import
com.integratebutton.search.IPQuery;

import
com.integratebutton.search.SiteDTO;

import
com.integratebutton.search.UrlParams;

import
com.integratebutton.search.SiteUtil;

import
java.text.DateFormat;

import
java.text.ParseException;

import
java.text.SimpleDateFormat;

import
java.util.ArrayList;

import
java.util.Calendar;

import
java.util.Collection;

import
java.util.Collections;

import
java.util.Date;

import
java.util.HashMap;

import
java.util.List;

import
java.util.Map;

import
org.apache.log4j.Logger;

...

¶ÈÁ¿

ÕÒµ½´øÓÐÌ«¶àÔðÈεÄÀàµÄÒ»¸ö·½·¨¾ÍÊÇͨ¹ý ´«³öñîºÏ¶ÈÁ¿·½·¨£¬ÒàÖ¸ Éȳö¸´ÔÓ¶È¡£Éȳö¸´ÔӶȸø±»·ÖÎöµÄÀàËùÒÀ¸½µÄÿһ¸öÀำֵ 1¡£

¹¤¾ß

Çåµ¥ 11 չʾÁËÒ»¸öÓà CheckStyle ÉèÖÃ×î´óÉȳö¸´ÔÓ¶ÈÊýµÄÀý×Ó£º

Çåµ¥ 11. ʹÓà CheckStyle ÉèÖÃ×î´óÉȳö¸´ÔÓ¶È

<module

name="ClassFanOutComplexity">

<property

name="max"

value="10"/>

</module>

Refactoring to Patterns

¹¤³§·½·¨Ä£Ê½ÊÇÓ¦ÓÃÖØ¹¹Ê±¿ÉÒÔʵÏֵĶàÖÖÉè¼ÆÄ£Ê½Ö®Ò»¡£Óù¤³§·½·¨´´½¨ÀàÎÞÐèÏÔʽ¶¨ÒåÕýÔÚ´´½¨µÄʵ¼ÊµÄÀà¡£Õâ¸öģʽ¿ÉÒÔʹ½çÃæ±ÈʵÏÖÀà¸ü¼òµ¥¡£µ±¸ù¾Ý´úÂëζµÀʵÏÖÖØ¹¹Ê±£¬ÄúÒ²¿ÉÒÔʹÓÃÆäËûµÄÉè¼ÆÄ£Ê½£»²Î¼û ²Î¿¼×ÊÁϲ鿴רÃÅÑо¿Õâ¸ö¸ÅÄîµÄÊé¼®µÄÁ´½Ó¡£

ÖØ¹¹

ÐÞ¸´ÓÉÓÚÌ«¶àµ¼Èë¶øÒý·¢µÄñîºÏ¹ý½ôµÄ·½·¨ÓкܶàÖÖ¡£¶ÔÓÚÖîÈç Çåµ¥ 10ÖÐÄÇÑùµÄ´úÂëÀ´Ëµ£¬¿ÉÓõÄÖØ¹¹¾Í°üÀ¨ Move MethodÖØ¹¹£º½«·½·¨´Óµ¥¶ÀµÄ *QueryÀàÒÆ¶¯µ½ Java ½çÃæ£¬²¢¶¨ÒåËùÓÐ QueryÀà±ØÐëʵÏÖµÄͨÓ÷½·¨¡£È»ºóÔÙʹÓà ¹¤³§·½·¨Ä£Ê½£¬ÕâÑùñîºÏ¶È¾ÍÓë½çÃæÏà¹ØÁªÁË¡£

ͨ¹ýʹÓà Gant ×Ô¶¯¹¹½¨½Å±¾Ö´ÐÐ CheckStyle Ant ÈÎÎñ£¬ÎÒ¿ÉÒÔËÑË÷´úÂë¿â£¬²éÕÒ¹ý¶àÒÀÀµÓÚÆäËûÀàµÄÀà¡£µ±ÐÞ¸ÄÕâЩÀàÖеĴúÂëʱ£¬¾ÍÄܹ»ÊµÏÖÌØ¶¨µÄÖØ¹¹£¨±ÈÈç Move Method£©ºÍÌØ¶¨µÄÉè¼ÆÄ£Ê½£¬ÒÔÖ𲽸Ľø¿Éά»¤ÐÔ¡£

ÖØ¹¹¡­¡­Òª¾¡ÔçÇÒÒª¾­³£½øÐÐ

³ÖÐø¼¯³É£¨Continuous Integration£¬CI£©¾ÍÊǾ­³£¼¯³É±ä¸ü¡£ÕýÈçÆäµäÐ͵ÄʵÏÖ·½Ê½Ò»Ñù£¬Ã¿µ±¶ÔÏîÄ¿µÄ°æ±¾¿ØÖÆ´¢´æ¿â×ö³öÒ»¸ö¸ü¸Äʱ£¬ÔËÐÐÓÚ¶ÀÁ¢»úÆ÷ÉϵÄ×Ô¶¯ CI ·þÎñÆ÷¾Í»á´¥·¢Ò»¸ö×Ô¶¯¹¹½¨¡£ÎªÁËÈ·±£ Çåµ¥ 3ºÍ Çåµ¥ 8ÖеĽű¾¿ÉÒÔÔÚ¶ÔÊý¾Ý¿â×ö³ö¸ü¸ÄʱһÖµØÔËÐУ¬ÄúÐèÒªÅäÖÃÒ»¸öÖîÈç Hudsona ÕâÑùµÄ CI ·þÎñÆ÷£¨²Î¼û ²Î¿¼×ÊÁÏ£©¡£Hudson ÊÇÒÔ WAR ÎļþµÄÐÎʽ·¢²¼µÄ£¬Äú¿ÉÒÔ½«Ëü·ÅÈëÈκΠJava Web ÈÝÆ÷ÖС£

ÓÉÓÚ Çåµ¥ 3ºÍ Çåµ¥ 8ÖеÄÀý×ÓʹÓÃÁË Gant£¬ÏÂÃæÎҾͼòÒª½éÉÜÒ»ÏÂÅäÖà Hudson CI ·þÎñÆ÷ÒÔÔËÐÐ Gant ½Å±¾µÄ²½Ö裺

ÔÚ Hudson µÄÒDZí°åÉÏΪ Hudson °²×° Gant ²å¼þ£ºÊ×ÏÈÑ¡Ôñ Manage Hudson£¬ÔÙÑ¡Ôñ Manage Plugins£¬È»ºóÑ¡Ôñ AvailableÑ¡Ï¡£ÔÚÕâ¸öÑ¡ÏÉÏÑ¡ÖÐ Gant ²å¼þ¸´Ñ¡¿ò£¬È»ºóµ¥»÷ Install°´Å¥¡£

ÖØÐÂÆô¶¯ Web ÈÝÆ÷£¨ÀýÈ磬Tomcat£©¡£

Ñ¡Ôñ Manage Hudson£¬È»ºóÑ¡Ôñ Configure System¡£ÔÚ Gant installation²¿·Ö£¬¼üÈëÒ»¸öΩһµÄÃû³ÆÒÔ¼° Groovy °²×°µ½ÔËÐÐ Hudson µÄ»úÆ÷ÉϵÄλÖᣱ£´æËù×÷¸ü¸Ä¡£

·µ»Øµ½ÒDZí°å£¨Ñ¡Ôñ HudsonÁ´½Ó£©£¬Ñ¡ÔñÒ»¸ö existing Hudson Job£¬ÔÙÑ¡Ôñ Configure£¬È»ºóµ¥»÷ Add build step°´Å¥£¬Ñ¡Ôñ Invoke Gant scriptÑ¡Ïî¡£

ÅäÖà Hudson£¬Ê¹ÆäÔËÐÐʹÓà Gant ±àдµÄ×Ô¶¯¹¹½¨½Å±¾¡£Ò»µ©ÖîÈ糤·½·¨ºÍÌõ¼þ¸´ÔÓ¶ÈÕâÑùµÄ´úÂëζµÀ±»ÒýÈëµ½´úÂë¿âÖУ¬ÄúÁ¢¿Ì¾Í»áµÃµ½ÓëËüÃÇÏà¹ØµÄ¶ÈÁ¿·½·¨µÄ·´À¡¡£

ÆäËûζµÀÓëÖØ¹¹

²¢·ÇËùÓеÄζµÀ¶¼ÓÐÏà¹ØµÄ¶ÈÁ¿·½·¨¡£µ«ÊÇ£¬¾²Ì¬·ÖÎö¹¤¾ßÄܹ»½Ò¶µÄζµÀ²»Ö¹ÎÒËùʾ·¶µÄÕâЩ¡£±í 1 ÁоÙÁËÆäËûµÄ´úÂëζµÀ¡¢¹¤¾ß¡¢ÒÔ¼°¿ÉÄܵÄÖØ¹¹Àý×Ó£º

±í 1. ÆäËûζµÀÓëÖØ¹¹

±¾ÎÄÌṩÁËÒ»ÖÖʹ´úÂëζµÀÓëÒ»ÖÖ¶ÈÁ¿·½·¨Ïà¹ØµÄģʽ£¬ÕâÖÖ¶ÈÁ¿·½·¨¿ÉÒÔÅäÖÃΪͨ¹ý×Ô¶¯¾²Ì¬·ÖÎö¹¤¾ß±ê¼Ç¡£Äú¿ÉÒÔʹÓûò²»Ê¹ÓÃÌØ¶¨µÄÉè¼ÆÄ£Ê½À´½øÐÐÖØ¹¹¡£ÕâΪÄúÌṩÁËÒ»¸öÒÔ¿ÉÖØ¸´µÄ·½Ê½Ò»ÖµزéÕÒºÍÐÞ¸´´úÂëζµÀµÄ¿ò¼Ü¡£ÎÒ¼áÐű¾ÎĵÄÀý×ÓÒ²ÓÐÖúÓÚÄúʹÓþ²Ì¬·ÖÎö¹¤¾ßÀ´²éÕÒ±¾ÎÄÎ´Éæ¼°µ½´úÂëζµÀ¡£

 

   
3849 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì