ã³ãŒãã®èãã¯ãã°ã§ã¯ãããŸããããã°ã®ããããã°ã©ã ã¯ã¯ã©ãã·ã¥ãããã誀ã£ãçµæãè¿ãããããã¹ãã«å€±æãããããŸããã³ãŒãã®èããããããã°ã©ã ã¯äœå¹Žãåé¡ãªãåäœãããããããŸãããã倿Žãå ãããã³ã«ã³ã¹ããããã¿ãæ°æ©èœã远å ãããã³ã«äºæãã¬ãªã¹ã¯ãçãããªãã¡ã¯ã¿ãªã³ã°ã詊ã¿ããã³ã«èª°ãç¥ããªãã£ãäŸåé¢ä¿ãæããã«ãªããŸããã³ãŒãã®èãã¯ãå°æ¥ã®åé¡ãäºæž¬ããã³ãŒãã®æ§é çç¹åŸŽã§ããããã«é害ãåŒãèµ·ããããã§ã¯ãããŸããããå°æ¥ã®ãããã倿Žãå¿ èŠä»¥äžã«å°é£ãé å»¶ããããŠå±éºãªãã®ã«ããŸãã
ãã®çšèªã¯ãããŒãã£ã³ã»ãã¡ãŠã©ãŒãšã±ã³ãã»ããã¯ããã¡ãŠã©ãŒã®èæžããªãã¡ã¯ã¿ãªã³ã°ïŒæ¢åã³ãŒãã®èšèšæ¹åãïŒ1999幎ïŒã§åºãããã®ã§ãåæžã§ã¯22çš®é¡ã®ã³ãŒãã¹ã¡ã«ãåæãããããããã«å¯Ÿå¿ãããªãã¡ã¯ã¿ãªã³ã°ææ³ã瀺ãããŸããããã®ã«ã¿ãã°ã¯ä»ã§ãæšæºçãªåèè³æãšãªã£ãŠããããã¡ãŠã©ãŒãåä»ãããé·ãã¡ãœããããç¥ã¯ã©ã¹ããéè€ã³ãŒãããæ©èœãžã®çŸšæããåå²å€æŽããã·ã§ããã¬ã³æè¡ããªã©ã®ã³ãŒãã¹ã¡ã«ã¯ãçŸåšã§ãæ¥çå šäœã®SonarQubeã«ãŒã«ã»ãããéçè§£æããŒã«ãã³ãŒãã¬ãã¥ãŒãã§ãã¯ãªã¹ãã«ç»å ŽããŠããŸãã
ã³ãŒãã®èããæ¶ã
SMART TS XL è€éãªã·ã¹ãã å šäœã§ãããããããã³ã°ããŠä¿®æ£ããã®ã«åœ¹ç«ã¡ãŸãã
詳现æ å ±ã³ãŒãã®æªèãšã¯äœã§ããïŒ
ã³ãŒãã®èããšã¯ããœãŒã¹ã³ãŒãã®è¡šé¢çãªç¹åŸŽã§ãããããæ·±ãæ§é çãŸãã¯èšèšäžã®åé¡ã瀺åãããã®ã§ããã³ãŒãã¯ã³ã³ãã€ã«ããããã¹ãã«åæ Œããæ£ããåºåãçæããŸããããã®æ§é äžã®äœããã®åé¡ã«ãããæ¬æ¥ãããèªã¿ã«ãããæ¡åŒµãã«ãããå®å šã«ä¿®æ£ããããšãå°é£ã«ãªã£ãŠããŸãããã¡ãŠã©ãŒã®å®çŸ©ã¯ããéåžžãã·ã¹ãã å ã®ããæ·±ãåé¡ã«å¯Ÿå¿ãã衚é¢çãªå åãã§ãã
ã³ãŒãã®èãã¯ãæ§æãšã©ãŒãã¢ãµãŒã·ã§ã³ã®å€±æãšãã£ãæå³ã§ã®éåã§ã¯ãããŸããããããã¯ãããšãç®ã«èŠããäžå ·åããªããŠããçµéšè±å¯ãªéçºè ãèŠåãµã€ã³ãšããŠèªèããææšãã€ãŸããã¿ãŒã³ã§ããå±éºãªã®ã¯ããããã环ç©ããŠããããšã§ãã1äžè¡ã®ã³ãŒãããŒã¹ã®äžã«é·ãã¡ãœããã1ã€ããã ãã§ã¯ãäºçްãªäžäŸ¿ãã§æžã¿ãŸããããããäœçŸãã®é·ãã¡ãœãããæ°åã®ã¢ãžã¥ãŒã«ã«ãŸãããéè€ããããžãã¯ããããŠäŸåé¢ä¿ã°ã©ãã®äžå¿ã«ãã巚倧ãªã¯ã©ã¹ãšãã£ããã®ããå®å šãªå€æŽãçã«å°é£ã«ããã·ã¹ãã ã«ãªã£ãŠããŸãã®ã§ãã
ã³ãŒãã®æªè vs. ãã° vs. æè¡çè² åµ
ããã3ã€ã®æŠå¿µã¯é¢é£ããŠãããã®ã®ãããããç°ãªããã®ã§ãããæ··åãããšåªå é äœä»ããäžé©åã«ãªãã
| æŠå¿µ | å³åº§ã«å€±æããïŒ | èŠã€ãæ¹ | |
|---|---|---|---|
| ãã° | 誀ã£ãåäœãåŒãèµ·ããã³ãŒã | ã¯ãããã¹ãã¯å€±æãããŠãŒã¶ãŒã¯ãšã©ãŒãå ±åããŸãã | ãã¹ããç£èŠããšã©ãŒãã° |
| ã³ãŒãã®èã | å°æ¥ã®åé¡ãäºæž¬ããæ§é ãã¿ãŒã³ | ããããã³ãŒãã¯æ£ããå®è¡ãããŸã | ã³ãŒãã¬ãã¥ãŒãéçè§£æ |
| æè¡çè² åµ | éå»ã®è¿éã誀ã£ã倿ã®çޝç©ã³ã¹ã | ãããããããæéã®çµéãšãšãã«è€å©çã« | ææšãè€éæ§åæããªãã¡ã¯ã¿ãªã³ã°å·¥æ°èŠç©ãã |
ã³ãŒãã®æªèã¯ãæè¡çè² åµãèç©ãããã¡ã«ããºã ã§ããã³ãŒãããŒã¹ã«è¿œå ãããé·ãã¡ãœããã¯ãããããæè¡çè² åµã®åäœã§ããããã®å©æ¯ã¯ãå°æ¥ã®ãã¹ãŠã®éçºè ããã®ã¡ãœãããçè§£ããããã«è²»ããäœåãªæéãšãå°æ¥ã®ãã¹ãŠã®å€æŽããã®ã¡ãœããã®ãµã€ãºã«ããå¯äœçšãåé¿ããããã«è²»ããæéã§ãã
SonarQubeã«ãããã³ãŒãã¹ã¡ã«ãšã¯äœã§ããïŒ
SonarQubeã¯ãã³ãŒãã®åé¡ããã°ïŒæããã«ééã£ãŠããã³ãŒãïŒãè匱æ§ïŒã»ãã¥ãªãã£äžã®åé¡ïŒãã³ãŒãã¹ã¡ã«ïŒä¿å®æ§ã®åé¡ïŒã®3ã€ã®ã«ããŽãªã«åé¡ããŸããSonarQubeã®ã³ãŒãã¹ã¡ã«ã¯ãFowlerã®åé¡äœç³»ã«çŽæ¥å¯Ÿå¿ããŠãããé·ãã¡ãœããïŒèšå®å¯èœãªè¡æ°ã®ãããå€ãè¶ ãããã®ïŒãéè€ãããããã¯ããã©ã¡ãŒã¿ãå€ããããã®ãèªç¥è€é床ã¹ã³ã¢ãé«ããã®ããšã©ãŒåŠçãæ¬ èœããŠãããã®ãã¢ãŒããã¯ãã£äžã®çµåéåãªã©ã«é¢ããã«ãŒã«ãå«ãŸããŠããŸããSonarQubeã®ã³ãŒãã¹ã¡ã«ã«ãŒã«ã¯ãFowlerã®ãªãªãžãã«ã®åé¡äœç³»ãèªååããŠéçšãããæ¥çã§æãåºãå©çšãããŠããææ³ã§ãã
ããŒãã£ã³ã»ãã¡ãŠã©ãŒèãã³ãŒãã®èãïŒå€å žçãªå顿³ã
ãã¡ãŠã©ãŒãæåã«æå±ãããã«ããŽãªå¥ã«æŽçããã22çš®é¡ã®ã³ãŒãã¹ã¡ã«ã¯ãçŸåšã§ãæšæºçãªåç §åºæºãšãªã£ãŠãããäž»èŠãªéçè§£æããŒã«ã®ã«ãŒã«ã»ããã¯ãã¹ãŠããã®å顿³ã«åºã¥ããŠããã
| ã«ããŽãªãŒ | ã³ãŒãã®èã |
|---|---|
| ãããŠã¿ãŒæ±ãã«ããã»ã©å€§ãããªã£ãã³ãŒã | é·ãã¡ãœããã倧ããªã¯ã©ã¹ãããªããã£ãåãžã®å·çãé·ããã©ã¡ãŒã¿ãªã¹ããããŒã¿ã®å¡ |
| ãªããžã§ã¯ãæåãæªçšãã人ã ãªããžã§ã¯ãæåååã®èª€çš | switchæãäžæãã£ãŒã«ããæåŠãããç¶æ¿ãç°ãªãã€ã³ã¿ãŒãã§ãŒã¹ãæã€ä»£æ¿ã¯ã©ã¹ |
| å€åã®é»å®³è å€åãå°é£ã«ãã | åå²çãªå€åãã·ã§ããã¬ã³æè¡ã䞊åç¶æ¿éå±€ |
| æ¶èåäžèŠãªã³ãŒã | ã³ã¡ã³ãïŒéå°ïŒãéè€ã³ãŒããé å»¶ã¯ã©ã¹ãããŒã¿ã¯ã©ã¹ããããã³ãŒããææ©çäžè¬æ§ |
| ã«ãã©éå°ãªçµå | æ©èœãžã®çŸšæãäžé©åãªèŠªå¯ããã¡ãã»ãŒãžã®é£éã仲ä»è |
èããã©ã®ã«ããŽãªã«å±ããââããçè§£ããããšã§ã修埩ã®åªå é äœä»ãã«åœ¹ç«ã¡ãŸããèšåŒµããèããšå€æŽãé»å®³ããèãã¯ããªãã¡ã¯ã¿ãªã³ã°ã³ã¹ãã®é«ããšçŽæ¥çžé¢ããŠããŸããçµåããèãã¯ãã¢ãŒããã¯ãã£ã®è匱æ§ãšçŽæ¥çžé¢ããŠããŸããäžèŠãªèãã¯ãæãå®å šã«åé€ã§ããŸãã
ããããã³ãŒãã®èãïŒã¯ã€ãã¯ãªãã¡ã¬ã³ã¹
| ã³ãŒãã®èã | ããã¯ã©ã®ãããªãã®ã | äž»ãªãªã¹ã¯ |
|---|---|---|
| éè€ã³ãŒã | åãããžãã¯ãè€æ°ã®ç®æã«çŸãã | ãã°ä¿®æ£ã¯ããããç®æã«é©çšããå¿ èŠããããã³ããŒã¯æéã®çµéãšãšãã«ä¹é¢ããŠããã |
| ãã³ã°ã¡ãœãã | è€æ°ã®è²¬ä»»ã䌎ãã20ïœ30è¡ãè¶ ããã¡ãœãã | èªç¥è² è·ãé«ããåã ã®è¡åããã¹ãããã®ãé£ããã |
| ç¥ã¯ã©ã¹ïŒå€§èŠæš¡ã¯ã©ã¹ | ãã¹ãŠãããªãã¯ã©ã¹ | ãã¹ãŠã®æ©èœå€æŽãåãã¯ã©ã¹ã«åœ±é¿ãäžãããããããŒãžã®ç«¶åãè匱æ§ãçºçããå¯èœæ§ããããŸãã |
| é·ããã©ã¡ãŒã¿ãªã¹ã | 4ã€ä»¥äžã®ãã©ã¡ãŒã¿ãåãã¡ãœãã | 誀ã£ãå€ãæž¡ãããããåŒã³åºãç®æãèªã¿ã«ããã |
| æ©èœãžã®æ§ã | èªèº«ã®ããŒã¿ãããä»ã®ã¯ã©ã¹ã®ããŒã¿ãå€ã䜿çšããã¡ãœãã | 坿¥ãªçµåãäžæ¹ã®ã¯ã©ã¹ã®å€åãããäžæ¹ã®ã¯ã©ã¹ãå£ãã |
| åå²å€å | ããŸããŸãªçç±ã§å€æŽãããã¯ã©ã¹ã1ã€ãããŸãã | åç¬è²¬ä»»ã®ååã«éåãããäºæž¬äžå¯èœãªå¯äœçšãããã |
| ã·ã§ããã¬ã³æè¡ | 1ã€ã®å€æŽã§ãå€ãã®ã¯ã©ã¹ã«ãããç·šéãå¿ èŠã«ãªããŸãã | 倿Žã³ã¹ããé«ããã€ã³ã¹ã¿ã³ã¹ãèŠèœãšããããã |
| ãããã³ãŒã | 決ããŠåŒã³åºãããªãããŸãã¯å°éããªãã³ãŒã | éçºè ãæ··ä¹±ããããé·å¹Žã«ããã£ãŠèç©ããããç§»è¡ãè€éã«ããã |
| åå§çãªå·ç | ãã¡ã€ã³ãªããžã§ã¯ãã®ä»£ããã«åºæ¬åïŒæååãæŽæ°ïŒã䜿çšãã | æ€èšŒãè³ãæã«æ£åšããŠããã衚çŸåã«ä¹ããã |
| ããŒã¿å¡ | åããã£ãŒã«ã矀ãç¹°ãè¿ãäžç·ã«æž¡ããã | ãã¡ã€ã³ãªããžã§ã¯ãã§ããã¹ããæœè±¡åãæ¬ ããŠããããšã瀺ããŠããã |
| æšæž¬çäžè¬æ§ | å°æ¥ã®ããŒãºãæ³å®ããŠæžãããã³ãŒã | äžå¿ èŠãªè€éãããªããããããã«ããã®ã誰ãçè§£ããŠããªãã |
| äžè²«æ§ã®ãªããšã©ãŒåŠç | ãµã€ã¬ã³ããã£ãããããŸããŸãªäŸå€æŠç¥ | éå®³ãæ€åºãããªãããããããã°ã«éåžžã«æéããããã |
ã³ãŒãã®æªèã®å®çŸ©ãšäŸ
éè€ã³ãŒã
å€§èŠæš¡ã·ã¹ãã ã«ãããŠæãäžè¬çã§ãæãã³ã¹ãã®ãããã³ãŒãã®æªèãéè€ã¯ãã³ããŒïŒããŒã¹ãã«ããéçºãæéçå¶çŽããããŠåãåé¡ãããããç¬ç«ããŠè§£æ±ºããããšããããŒã ãå€ç«ããŠäœæ¥ããããšã«ãã£ãŠçºçããããã®çŽæ¥çãªçµæãšããŠãä¿å®ã³ã¹ããå¢å€§ãããå ±æããžãã¯ãžã®å€æŽã¯ãã¹ãŠããã¹ãŠã®ã³ããŒã«é©çšããå¿ èŠãããããã ã
ãžã£ã¯
// ServiceA -- discount calculation
double calculateDiscount(double amount) {
if (amount > 1000) return amount * 0.1;
return 0;
}
// ServiceB -- same logic, copied and forgotten
double computeDiscount(double value) {
if (value > 1000) return value * 0.1;
return 0;
}
ããžãã¹ã«ãŒã«ã倿ŽããããšïŒãããå€ã1500ãã¬ãŒãã12%ã«ãªããªã©ïŒãäžæ¹ã®ã³ããŒã¯æŽæ°ãããŸãããããäžæ¹ã¯æŽæ°ãããŸããããã®çµæã2ã€ã®ã¢ãžã¥ãŒã«éã§åºæ¬çãªããžãã¹ããžãã¯ã«ççŸãçãããã¹ã段éã§ã¯ãªããç£æ»æã«æ¬çªç°å¢ã§ãã®äžäžèŽãé¡åšåããŸãã
ä¿®æ£æ¹æ³ïŒå ±éã®ããžãã¯ããäž¡æ¹ã®åŒã³åºãå ãåç §ããåäžã®é¢æ°ããŠãŒãã£ãªãã£ã¯ã©ã¹ããŸãã¯å ±æã©ã€ãã©ãªã«æœåºããŸãã
ãã³ã°ã¡ãœãã
æéã®çµéãšãšãã«æ°ããªè²¬ä»»ãåžåããæ¬æ¥ã®ç®çãè¶ ããŠçºå±ããŠããã¡ãœããã200è¡ã®ã¡ãœãããèªãéã®èªç¥è² è·ã¯ã10è¡ã®ã¡ãœããã20åèªãå Žåãšã¯ãéçãªéãã ãã§ãªã質çãªéãããããé·ãã¡ãœããã¯ãåå¥ã«ãã¹ãããã«ã¯åŠçãå€ããããããã¹ããé£ããããŸããå®è¡ã³ã³ããã¹ãå šäœãã¯ãŒãã³ã°ã¡ã¢ãªã«ä¿æããå¿ èŠãããããçè§£ãé£ããã
æ€åºéŸå€ïŒ20ïœ30è¡ãè¶ ããã¡ãœããã¯ã¬ãã¥ãŒãå¿ èŠã§ããã50è¡ãè¶ ããå Žåã¯ã»ãŒç¢ºå®ã«ãªãã¡ã¯ã¿ãªã³ã°ãæ£åœåãããŸããCOBOLã§ã¯ã100æãè¶ ããæ®µèœãããã«çžåœããŸãã
ãã€ãœã³
class OrderProcessor:
def process_order(self, order):
# Validate order -- 40 lines
# Calculate discounts -- 30 lines
# Update inventory -- 25 lines
# Send notification emails -- 20 lines
# Generate invoice -- 35 lines
# 150+ lines total
pass
ãã®ã¡ãœããã«ãããå責任ã¯ãããããç¬ç«ããã¯ã©ã¹ãŸãã¯é¢æ°ãšããŠå®çŸ©ãããã¹ãã§ãããããããŸãšããŠç®¡çãããšãè«æ±æžçºè¡ãåšåº«ç®¡çãéç¥ãªã©ã®ä»åŸã®æŽæ°ã®ãã³ã«ã泚æåŠçãããŒå šäœãäžå®å®ã«ãªããªã¹ã¯ãçããŸãã
ç¥çŽ
è€æ°ã®ãã¡ã€ã³ã«ãŸããã責任ãèç©ããåäžè²¬ä»»ã®ååã«èããéåããŠããã¯ã©ã¹ããã®çµæãã³ãŒãããŒã¹ã®éå¿ãšãªãããã¹ãŠãããã«äŸåãããã®äžã®äœãã倿Žããã«ã¯ãããã«é¢ãããã¹ãŠãçè§£ããå¿ èŠãçããã
æ€åºã·ã°ãã«ïŒ20ïœ30å以äžã®å ¬éã¡ãœãããæã€ã¯ã©ã¹ããŸãã¯ååã«ãManagerãããProcessorãããHandlerãããUtilsãããHelperããå«ãŸããã¯ã©ã¹ããè€æ°ã®ç¡é¢ä¿ãªãã¡ã€ã³ã«é©çšãããŠããå Žåã
åå²å€å
ããŸããŸãªãäºãã«é¢é£æ§ã®ãªãçç±ã§å€æŽãããã¯ã©ã¹ãããŒã¿ããŒã¹ã¹ããŒãã倿Žããããã³ã«ããã®ã¯ã©ã¹ãç·šéããå¿ èŠããããŸããäŸ¡æ Œèšå®ã«ãŒã«ã倿Žããããã³ã«ããã®ã¯ã©ã¹ãç·šéããå¿ èŠããããŸããéç¥ãã©ãŒãããã倿Žããããã³ã«ããã®ã¯ã©ã¹ãç·šéããå¿ èŠããããŸãããã®ã¯ã©ã¹ã¯è²¬ä»»ãå€ããããããåå²ããå¿ èŠããããŸãã
å®çŸ©ïŒæ§ã ãªçç±ã§åžžã«å€åãç¶ããã¯ã©ã¹ãã·ã§ããã¬ã³æè¡ã®éã
ã·ã§ããã¬ã³æè¡
æŠå¿µçãªå€æŽãäžã€ããã ãã§ãå€ãã®ç°ãªãã¯ã©ã¹ã«ãããç·šéãå¿ èŠã«ãªããŸããçšçã倿Žããã«ã¯ãããã¯ãšã³ãã®èšç®ãããã³ããšã³ãã®æ€èšŒãããŒã¿ããŒã¹ã®ããªã¬ãŒãããããžã§ããã¬ããŒãã¯ãšãªã®5ã€ã®ç°ãªãç®æãä¿®æ£ããå¿ èŠããããŸããã©ããäžã€ã§ãèŠèœãšããšãåäœãäžå®å®ã«ãªããŸãã
SQL
-- Tax logic duplicated across queries
SELECT amount * 0.05 FROM invoices;
SELECT amount * 0.05 FROM payments;
SELECT amount * 0.05 FROM reports;
0.05ã0.07ã«å€æŽããã«ã¯ãSQLãã¡ã€ã«ãã¹ãã¢ãããã·ãŒãžã£ãããã³ã¢ããªã±ãŒã·ã§ã³ã³ãŒãå šäœã«ããã£ãŠããã®å€æŽç®æããã¹ãŠèŠã€ãåºãå¿ èŠããããŸãã
æ©èœãžã®æ§ã
èªèº«ã®ããŒã¿ãã¡ãœããããããå¥ã®ã¯ã©ã¹ã®ããŒã¿ãã¡ãœãããå€ã䜿çšããã¡ãœãããããã¯ããã®åäœãæ¬æ¥ã¯å¥ã®ã¯ã©ã¹ã«å±ããã¹ãã§ããããšã瀺åããŠããŸãã
ãžã£ã¯
// In ReportGenerator -- envious of Customer's data
double calculateCustomerRating(Customer customer) {
return customer.getOrderCount() * customer.getAverageOrderValue()
/ customer.getDaysSinceRegistration();
}
// This logic belongs in Customer, not ReportGenerator
ãããã³ãŒã
ãªããžããªã«ã¯ååšãããã®ã®ãæ¬çªç°å¢ã§ã¯ã©ã®å®è¡ãã¹ãããåŒã³åºãããªãã³ãŒãããããã³ãŒãã¯ãæ©èœãåé€ã眮æããŸãã¯åæ§ç¯ãããéã«å€ãã³ãŒããåé€ãããªããŸãŸæŸçœ®ããããšãé·å¹Žã«ããã£ãŠèç©ãããŸããã³ãŒãã¬ãã¥ãŒã®åŠšããšãªããéçºè ãã³ãŒãããŒã¹ã«æ £ããéã®æ··ä¹±ãæããç§»è¡åæãè€éåãããå Žåã«ãã£ãŠã¯æå³ããåã¢ã¯ãã£ãåãããããšããããŸãã
æ€åº: SonarQubeãKnip (TypeScript/JavaScriptçš)ãããã³ SMART TS XL ã³ãŒãããŒã¹å šäœã§ãå°éäžèœãªé¢æ°ãåŒã³åºãããŠããªãã¡ãœãããããã³æªäœ¿çšã®å€æ°ãç¹å®ããŸãã
DRYååéå
DRYïŒDon't Repeat YourselfïŒååãšã¯ãã·ã¹ãã å ã®ããããç¥èã¯ãåäžã®æç¢ºãªè¡šçŸã§ãªããã°ãªããªããšããååã§ããDRYååã«éåãããšãã³ãŒãã®éè€ãããŒã¿ã®å¡ããããŠå€ãã®ãã·ã§ããã¬ã³ã»ãµãŒãžã§ãªãŒãã·ããªãªã®æ ¹æ¬åå ãšãªããŸããããžãã¹ããžãã¯ãè€æ°ã®å Žæã«è¡šçŸãããŠããå Žåããããã®è¡šçŸã¯å¿ ç¶çã«ä¹é¢ããŸããDRYã¯ååã§ãããã³ãŒãã®éè€ã¯ãã®éåã瀺ãå åã§ãã
ãã€ãœã³
# DRY violation: same validation logic in three places
def validate_email_in_registration(email):
return "@" in email and "." in email
def validate_email_in_profile_update(email):
return "@" in email and "." in email
def validate_email_in_checkout(email):
return "@" in email and "." in email
# DRY-compliant: one function, three callers
def is_valid_email(email):
return "@" in email and "." in email
æ€åºéŸå€ïŒã³ãŒãã¯ãã€ãèãããšãªãã®ãïŒ
ã³ãŒãã®èããæ€åºããã«ã¯ã枬å®å¯èœãªéŸå€ãå¿ èŠã§ãã以äžã«ãäžè¬çã«äœ¿çšãããææšãšã泚æãå¿ èŠãªèãã瀺ãå€ã瀺ããŸãã
| ã¡ããªã㯠| 枬å®å¯Ÿè±¡ | èŠåãããå€ | ã¯ãªãã£ã«ã«ãããå€ |
|---|---|---|---|
| 埪ç°çè€éæ§ | ã¡ãœããå ã®æ±ºå®åå²ã®æ° | 10äžèš | 20äžèš |
| ã¡ãœããã®é·ãïŒè¡æ°ïŒ | ã¡ãœãã/颿°å ã®è¡æ° | 20äžèš | 50äžèš |
| ãã©ã¡ãŒã¿æ° | ã¡ãœãããåãå ¥ãããã©ã¡ãŒã¿ã®æ° | 4äžèš | 7äžèš |
| ææ¥æé | ã¯ã©ã¹å ã®è¡æ° | 200äžèš | 500äžèš |
| éè€ç | éè€ããŠããã³ãŒãã®å²å | 3ïŒ ä»¥äž | 10ïŒ ä»¥äž |
| èªç¥è€éæ§ | ã³ãŒãã®çè§£ã®é£ãã | 15äžèš | 25äžèš |
| æ±å¿æ§çµåïŒCaïŒ | ãã®ã¯ã©ã¹ã«äŸåããã¯ã©ã¹ã®æ° | 15äžèš | 30äžèš |
| é å¿æ§çµåïŒCeïŒ | ãã®ã¯ã©ã¹ãäŸåããã¯ã©ã¹ã®æ° | 15äžèš | 30äžèš |
ãããã®ãããå€ã¯SonarQubeã§èšå®å¯èœã§ãããã»ãšãã©ã®éçè§£æãã©ãããã©ãŒã ã§ã¯ããããã®ææšã«åºã¥ããã«ã¹ã¿ã ã«ãŒã«ãèšå®ã§ããŸããã¯ãªãã£ã«ã«ãããå€ã«è©²åœããã¯ã©ã¹ãšã¡ãœããã¯ããªãã¡ã¯ã¿ãªã³ã°ã®åªå é äœãæãé«ã察象ã§ãããããã¯å°æ¥çã«äžå ·åãçºçããå¯èœæ§ãæãé«ããä¿å®ã³ã¹ããæãé«ãã³ã³ããŒãã³ãã ããã§ãã
ã³ãŒãã¹ã¡ã«æ€åºããŒã«
å€§èŠæš¡ãªã³ãŒãããŒã¹å šäœã«ããã£ãŠã³ãŒãã®äžå ·åãç¹å®ããã«ã¯ãèªåæ€åºãå¯äžã®æ¡åŒµå¯èœãªã¢ãããŒãã§ããæåã¬ãã¥ãŒã§ã¯ãèªåããŒã«ãæ€åºã§ããäžå ·åã®ããäžéšããæ€åºã§ãããæ°çŸäžè¡ãã®ã³ãŒããå«ãã¬ã¬ã·ãŒã·ã¹ãã ã«ã¯å¯Ÿå¿ã§ããŸããã
| ããŒã« | 第äžèšèª | æ€åºãããã® |
|---|---|---|
| SonarQube / SonarCloud | JavaãPythonãJS/TSãC#ãªã© | ãã¡ãŠã©ãŒã®å®å šãªåãåé¡ãã»ãã¥ãªãã£äžã®ãããã¹ããããéè€ |
| Checkstyle + PMD | Java | ã¹ã¿ã€ã«éåãéè€ãè€éæ§ææš |
| ESLint + typescript-eslint | JavaScriptãTypeScript | é·ã颿°ãè€éæ§ãæªäœ¿çšã³ãŒã |
| ããªã³ãïŒã©ãã³ | Python | è€éæ§ãã¹ã¿ã€ã«ãä¿å®æ§ææš |
| ãªã·ã£ãŒããŒïŒã©ã€ã㌠| C# | åé·ãªã³ãŒããé·ãã¡ãœãããçµåã®åé¡ |
| ã¯ãªã | Rust | Rustã«ãããæ £çšè¡šçŸã®éåãã³ãŒãã®èããšãªãäžè¬çãªãã¿ãŒã³ |
| ã³ãŒãã¯ã©ã€ã¡ãŒã | å€èšèª | è€éæ§ãéè€æ§ãä¿å®æ§ã¹ã³ã¢ |
| SMART TS XL | COBOLãJCLãJavaãPythonãRPGãSQLã.NET | èšèªéã®éè€ããããã³ãŒããçµåãäŸåé¢ä¿ã®ãã |
Rustã«ãããã³ãŒãã®èã ãããã¯äž»ã«Clippyã«ãã£ãŠæ€åºãããæ
£çšçãªRustãã¿ãŒã³ã匷å¶ããŸããæãäžè¬çãªRustç¹æã®èãã«ã¯ãäžå¿
èŠãªã¯ããŒã³ã unwrap() çç£ãã¹ãé床ã«ãã¹ãããããããåŒãããã³å€ãè¿ã颿° Result ãããã代ããã«ãããã¯ã䜿çšããŠãã ããã
ã³ãŒãã®æªèãšæè¡çè² åµïŒãã®é¢é£æ§
æè¡çè² åµãšã¯ãå質ãããã¹ããŒããåªå ããéå»ã®æææ±ºå®ã«ãã£ãŠèç©ãããã³ã¹ãã®ããšã§ããã³ãŒãã®èãã¯ããã®è² åµãã³ãŒãæ§é ã«çŸããã¡ã«ããºã ã§ããäž¡è ã®é¢ä¿ã¯çŽæ¥çã§ã察åŠãããŠããªãã³ãŒãã®èãã¯æè¡çè² åµã®åäœã§ããããã®å©æ¯ã¯ãå°æ¥ã®å€æŽã§åé¿ããªããã°ãªããªãäœåãªæéã§ãã
ãœãããŠã§ã¢å€æŽç®¡çã«ããã圱é¿åæã®æèã§èª¬æãããŠããããã«ãã³ãŒãã®èããç€ºãæ§é çãªåé¡ãã€ãŸãéå°ãªçµåãéè€ããããžãã¯ããããã³ãŒãã®èç©ã¯ãç¹å®ã®å€æŽãäœã«åœ±é¿ãäžããããç¹å®ããããšãå°é£ã«ããããããããã倿Žã®ç¯å²ãçŽæ¥çã«æ¡å€§ããŸãã
æè¡çè² åµãã³ãŒãã®æªèãšãã芳ç¹ãã説æããŸããããã³ãŒãããŒã¹ã«40%ã®éè€ãããå Žåããã°ä¿®æ£ã«ãããã³ã¹ãã¯æ¬æ¥ã®1.4åã«ãªããŸããã³ã¢åŠçã¯ã©ã¹ããã¹ãŠã®æ©èœã®äŸåå ãšãªããç¥ã¯ã©ã¹ãã§ããå Žåãæ©èœã远å ãããã³ã«ã¯ã©ã¹å šäœãçè§£ãããã¹ãããå¿ èŠããããŸãããšã©ãŒåŠçã«äžè²«æ§ããªãå Žåãé害ã·ã°ãã«ãä¿¡é Œã§ããªããããæ¬çªç°å¢ã§çºçããã€ã³ã·ãã³ãããšã«èª¿æ»æéãé·ããªããŸããæè¡çè² åµã¯æœè±¡çãªãã®ã§ã¯ãªããããããéå¹çæ§ãç©ã¿éãªã£ãŠçãããã®ã§ãã
CISQã®èª¿æ»ã«ãããšãéçºè ã¯æ°ããæ©èœã®éçºããããæè¡çè² åµã®åé¿ã«æéã®30ïœ40%ãè²»ãããŠããããšãäžè²«ããŠæããã«ãªã£ãŠããŸããã³ãŒãã®èãã®å¯åºŠã¯ãã©ãã ãã®è² åµãèç©ãããŠããããæãçŽæ¥çã«æž¬å®ããææšã§ãã
èªå®æ¡ä»¶ SMART TS XL ãšã³ã¿ãŒãã©ã€ãºèŠæš¡ã§ã³ãŒãã®æªèãæ€åºããŸã
SonarQubeãClippyãšãã£ãåã ã®ããŒã«ã¯ãåäžã®èšèªå ã§åäœããŸããããããCOBOLããã°ã©ã ãJavaãµãŒãã¹ãèªã¿èŸŒãããŒã¿ã»ããã«æžã蟌ã¿ãè¡ããJCLãžã§ãã¹ããªãŒã ãè€æ°ã®èšèªã§æžãããããã°ã©ã ãåŒã³åºããåãããžãã¹ããžãã¯ã3ã€ã®ç°ãªãå¹Žä»£ã«æžããã3ã€ã®ç°ãªãã·ã¹ãã ã«ããããç¬ç«ããŠè€è£œãããŠãããããªãšã³ã¿ãŒãã©ã€ãºç°å¢ã§ã¯ãåäžèšèªããŒã«ã§ã¯å šäœåãææ¡ã§ããŸããã
SMART TS XLãã éçã³ãŒãåæ ç°å¢å ã®ãã¹ãŠã®èšèªã«ãããã³ãŒãã®èããåæã«æ€åºããŸããäŸãã°ãCOBOL ã³ããŒããã¯ãš Java ãŠãŒãã£ãªã㣠ã¯ã©ã¹éã®éè€ããããžãã¯ãJCL ãžã§ããåŒã³åºããªã RPG ããã°ã©ã ã®ããã ã³ãŒãã1 ã€ã®æ®µèœã§ 50 ã®äœæ¥ãè¡ã COBOL ããã°ã©ã ã®ãŽãã ã¯ã©ã¹ ãã¿ãŒã³ãèšèªå¢çãè¶ããäžè²«æ§ã®ãªããšã©ãŒåŠçãã¿ãŒã³ãªã©ã§ãã
ã¢ããªã±ãŒã·ã§ã³ã®äŸåé¢ä¿ãããã³ã°æ©èœã¯ãåã ã®ãã¡ã€ã«ã¬ãã«ã®ããŒã«ã§ã¯æ€åºã§ããªãã¢ãŒããã¯ãã£äžã®åé¡ç¹ãç¹å®ããŸããäŸãã°ãæãé«ãçµååºŠïŒæãäŸå床ãé«ãã倿޿ã«ç Žæãããªã¹ã¯ãæãé«ãïŒãæã€ã³ã³ããŒãã³ããç¬ç«ããŠããã¹ãã¢ãžã¥ãŒã«éã«åŸªç°äŸåé¢ä¿ãååšããç®æãéè€ããããžãã¹ããžãã¯ãç°ãªãã·ã¹ãã ã§ç¬ç«ããŠç¶æãããŠããã«ãããããããã©ã¡ãã®ã³ããŒãäºãã®ååšãèªèããŠããªãç®æãªã©ã§ãã
圱é¿åææ©èœã«ãããã³ãŒãã®äžå ·åãå ·äœçãªå¯Ÿçã«çµã³ã€ããããšãã§ããŸããçµå床ã®é«ãã³ã³ããŒãã³ãããªãã¡ã¯ã¿ãªã³ã°ããåã«ã圱é¿åæã«ãã£ãŠãã¹ããæ€èšŒããŸãã¯æŽæ°ãå¿ èŠãªäŸåã³ã³ããŒãã³ãããã¹ãŠåæãããŸããããã«ãããå€§èŠæš¡ã§ã³ãŒãã®äžå ·åãå€ãã³ãŒãããŒã¹ã§ããŒã ãçµéšããããªãã¡ã¯ã¿ãªã³ã°éº»çºããè§£æ¶ãããå倿Žã«æç¢ºãªç¯å²ãèšå®ããããæ§é åãããæ¯æ£ããã°ã©ã ãžãšç§»è¡ããŸãããªã¹ã¯ãäžæçãªãŸãŸã§ã¯ã倿Žå 容ãæç¢ºã«å®çŸ©ããããªã¹ã¯ãäžæçãªãŸãŸã§ã¯ãªããªããŸãã
ã¬ã¬ã·ãŒã·ã¹ãã ã®è¿ä»£åããã°ã©ã ã宿œããããŒã ã«ãšã£ãŠãã³ãŒãã¹ã¡ã«åæã¯è¿ä»£åèšç»ã®åºç€ãšãªããŸããç§»è¡ãéå§ããåã«ãããã³ãŒããåé€ãïŒç¯å²ãçž®å°ïŒãéè€ããããžãã¯ãæšæºçãªå®è£ ã«çµ±åããæãçµå床ã®é«ãã³ã³ããŒãã³ããæåŸã«è¿ä»£åãïŒãããã«äŸåãããã¹ãŠã®ãã®ã察åŠãããåŸïŒããŽããã¯ã©ã¹ãæ°ããèšèªã«å€æããåã«åè§£ããŸãããªããªãããŽããã¯ã©ã¹ãJavaã«å€æãããšãJavaã§ããŽããã¯ã©ã¹ãçæãããããã§ãã
ã³ãŒãã®æªèã«å¯ŸåŠããïŒåªå é äœä»ããã¬ãŒã ã¯ãŒã¯
ãã¹ãŠã®ã³ãŒãã®æªèãå³åº§ã«ãªãã¡ã¯ã¿ãªã³ã°ãå¿ èŠãšããããã§ã¯ãããŸãããé©åãªã¢ãããŒãã¯ããªã¹ã¯ã«åºã¥ããåªå é äœä»ãã§ãã
åªå 床1ïŒå€æŽé »åºŠã®é«ãã³ã³ããŒãã³ãã«ãããã³ãŒãã®äžå ·åãé »ç¹ã«å€æŽãããè€éæ§ãçµå床ãé«ãã³ãŒãã¯ãæãå€ãã®äžå ·åãçºçãããŸãããããã®ã³ã³ããŒãã³ãã¯å€æŽã³ã¹ããæãé«ããæ¬çªç°å¢ã§ã®ã€ã³ã·ãã³ãçºçä»¶æ°ãæãå€ããªããŸãããŸãã¯ãããã®äžå ·åãä¿®æ£ããŠãã ããã
åªå 床2ïŒã¢ãŒããã¯ãã£å¢çã«ãããåé¡ç¹ããã¹ãŠã®èŠçŽ ãäŸåããããããããç¥ã¯ã©ã¹ããé«çµåã³ã³ããŒãã³ãã¯ã倿Žãããšæãå±éºã§ãããšåæã«ãä¿®æ£ããã«æŸçœ®ãããšæãã³ã¹ãããããããããã®ãªãã¡ã¯ã¿ãªã³ã°ãè¡ãåã«ãæãæ éãªåœ±é¿åæãå¿ èŠãšãªãã
åªå 床3ïŒã·ã¹ãã å¢çããŸããã ã³ãŒãã®éè€ãåãããžãã¹ããžãã¯ãè€æ°ã®ã·ã¹ãã ã«ååšããå Žåã倿Žã¯ãã¹ãŠã®ã³ããŒéã§åæã«èª¿æŽããå¿ èŠããããŸãããã®éè€ãçµ±åããããšã§ã調æŽã®ãªãŒããŒããããåæžãããä¹é¢ãé²ãããšãã§ããŸãã
åªå 床4ïŒäžèŠã³ãŒãã®åé€ãäžèŠã³ãŒãã¯æãå®å šã«å¯ŸåŠã§ããã«ããŽãªã§ããåé€ããŠãåäœãæãªãããããšã¯ãªãããããŸã§é ãããŠããäŸåé¢ä¿ãæããã«ãªãã ãã§ããåŒã³åºãããããšã®ãªãã³ãŒãã倿ããç¡é§ãªåŽåãé¿ãããããç§»è¡ã倿ãè¡ãåã«åé€ããå¿ èŠããããŸãã
åªå 床5ïŒãªã¹ã¯ã®äœãé åã«ãããã¹ã¿ã€ã«ãšæ§é äžã®åé¡ç¹ãå®å®ããŠããŠå€æŽé »åºŠã®äœãã³ãŒãå ã®é·ãã¡ãœããããã©ã¡ãŒã¿ãªã¹ãã¯ãè¿ãã®ã³ãŒããä»ã®çç±ã§å€æŽããå¿ èŠãçããéã«ãæ©äŒãæããŠå¯ŸåŠããåæã«åšå²ã®åé¡ç¹ããªãã¡ã¯ã¿ãªã³ã°ããããšãã§ããŸãã
ã³ãŒãã®äžå ·åãããããæ¢ã«æ¬çªç°å¢ã§ã®é害ãåŒãèµ·ãããŠããäºåŸçã«å¯ŸåŠããã®ã§ã¯ãªããäœç³»çã«æ€åºã枬å®ã察åŠããèŠåŸããããéçºããŒã ãé·æã«ããã£ãŠéçºé床ãç¶æã§ãããã©ããããããŠã·ã¹ãã ã倧ãããªãã«ã€ããŠåŸã ã«éçºé床ãäœäžããŠãããã©ãããåããæ±ºå®çãªèŠçŽ ãšãªãã