ãã®èšäºã¯ã
Growing Object-Oriented SoftwareãGuided by Tests ïŒç¥ããŠGOOSïŒã®ã¬ãã¥ãŒã§ãã ãã®äžã§ãã¢ãã¯ã䜿çšããã«æ¬ãããããžã§ã¯ãäŸãå®è£
ããæ¹æ³ã瀺ããŸãã
ãã®èšäºã®ç®çã¯ãmokã䜿çšãããšã³ãŒããã©ã®ããã«å®³ãåããããmokãåé€ãããšåãã³ãŒããã©ãã ãç°¡åã«ãªããã瀺ãããšã§ãã å¯æ¬¡çãªç®æšã¯ãç§ã«ãšã£ãŠå人çã«åççã§ãããšæãããæ¬ãšãããã©ããããåããã害ãåãŒãæ¬ããã¢ããã€ã¹ãéžæããããšã§ãã ãã®æ¬ã«ã¯äž¡æ¹ãšãããªããããããããŸãã
è±èªçïŒ
ãªã³ã¯è¯ãéšå
è¯ããã®ããå§ããŸãããã ãããã®ã»ãšãã©ã¯ãæ¬ã®æåã®2ã€ã®ã»ã¯ã·ã§ã³ã«ãããŸãã
èè
ã¯ãèªåãã¹ãã®ç®æšããã³ãŒãã®ãªã°ã¬ãã·ã§ã³ã®æ€åºã«åœ¹ç«ã€ãã»ãŒããã£ããããã®äœæãšå®çŸ©ããŠããŸãã ç§ã®æèŠã§ã¯ãããã¯ãã¹ããç§ãã¡ã«äžããæãéèŠãªå©ç¹ã§ãã ã»ãŒããã£ãããã¯ãã³ãŒããæåŸ
ã©ããã«æ©èœãããšãã確信ãåŸãã®ã«åœ¹ç«ã¡ãŸããããã«ãããæ°ããæ©èœããã°ããè¿œå ããæ¢åã®æ©èœããªãã¡ã¯ã¿ãªã³ã°ã§ããŸãã ã³ãŒãã®å€æŽãæ
éã«ã€ãªãããªããšç¢ºä¿¡ããŠããå ŽåãããŒã ã®çç£æ§ã¯å€§å¹
ã«åäžããŸãã
ãŸããåæã®æ®µéã§å±éç°å¢ãã»ããã¢ããããããšã®éèŠæ§ã«ã€ããŠã説æããŠããŸãã ããã¯ãæ°ãããããžã§ã¯ãã®æåªå
äºé
ã§ããå¿
èŠããããŸãã 倧éã®ã³ãŒããèšè¿°ããåã«ãæœåšçãªçµ±åãšã©ãŒãåæ段éã§ç¹å®ã§ããŸãã
ãã®ããã«ãèè
ã¯ãã¢ããªã±ãŒã·ã§ã³ã®æãåçŽãªããŒãžã§ã³ã§ãããŠã©ãŒãã³ã°ã¹ã±ã«ãã³ã®æ§ç¯ããå§ããããšãææ¡ããŸããããã¯åæã«ããã®å®è£
ã®ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ã¬ã€ã€ãŒã«åœ±é¿ããŸãã ããšãã°ãWebã¢ããªã±ãŒã·ã§ã³ã®å Žåãã¹ã±ã«ãã³ã¯å®éã®ããŒã¿ããŒã¹ããæååãèŠæ±ããåçŽãªHTMLããŒãžã衚瀺ã§ããŸãã ãã®ã¹ã±ã«ãã³ã¯ããã¹ãã¹ã€ãŒãã®äœæãéå§ãããšã³ãããŒãšã³ããã¹ãã§ã«ããŒããå¿
èŠããããŸãã
ãã®ææ³ã«ãããã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã«çŠç¹ãåœãŠãããšãªããå±éãã€ãã©ã€ã³ã®å±éã«éäžããããšãã§ããŸãã
ãã®æ¬ã¯ã2ã¬ãã«ã®TDDãµã€ã¯ã«ãæäŸããŸãã
ã€ãŸããåæ°æ©èœããšã³ãããŒãšã³ãã®ãã¹ãã§éå§ããéåžžã®èµ€ç·ãªãã¡ã¯ã¿ãªã³ã°ã«ãŒããä»ããŠãã®ãã¹ããå®è¡ããŸãã
ããã§ã®ãšã³ãããŒãšã³ãã¯ãé²è¡ç¶æ³ã®å°ºåºŠã®ãããªãã®ã§ãã ãããã®ãã¹ãã®äžéšã¯ã次ã®ããã«ãèµ€ãç¶æ
ã§ããå ŽåããããŸã ãã®æ©èœã¯ãŸã å®è£
ãããŠããŸãããããã¯æ£åžžã§ãã ãŠããããã¹ãã¯åæã«ã»ãŒããã£ããããšããŠæ©èœããåžžã«ç·è²ã§ããå¿
èŠããããŸãã
ãšã³ãããŒãšã³ãã®ãã¹ããã§ããã ãå€ãã®å€éšã·ã¹ãã ã«åœ±é¿ãäžããããšãéèŠã§ããããã¯çµ±åãšã©ãŒã®ç¹å®ã«åœ¹ç«ã¡ãŸãã åæã«ãèè
ã¯å€éšã·ã¹ãã ã®äžéšãã¹ã¿ãã«çœ®ãæããå¿
èŠãããããšãèªããŠããŸãã ãšã³ãããŒãšã³ãã®ãã¹ãã«äœãå«ããããšããåé¡ã¯ããããžã§ã¯ãããšã«åå¥ã«æ±ºå®ããå¿
èŠããããŸããæ®éçãªçãã¯ãããŸããã
ãã®æ¬ã¯ããšã©ãŒã¡ãã»ãŒãžãããç解ããããããããã«ã4çªç®ã®ã¹ããããè¿œå ããããšã«ãããå€å
žçãª3ã¹ãããTDDãµã€ã¯ã«ãæ¡åŒµããããšãææ¡ããŠããŸãã
ããã«ããããã¹ããã¯ã©ãã·ã¥ããå Žåã«ããããã¬ãŒãèµ·åããã«ãšã©ãŒã¡ãã»ãŒãžãèŠãã®ã¯ããã»ã©ç°¡åã§ã¯ãªãããšã確èªã§ããŸãã
èè
ã¯ãæåãããåçŽæ¹åãã«ã¢ããªã±ãŒã·ã§ã³ãéçºããããšããå§ãããŸãïŒãšã³ãããŒãšã³ãïŒã ã¢ãŒããã¯ãã£ã®ç 磚ã«æéãããããããå€éšïŒUIãªã©ïŒããã®ãªã¯ãšã¹ãã§éå§ããæå°éã®ã³ãŒãã§ã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ã¬ã€ã€ãŒïŒUIãããžãã¯ãããŒã¿ããŒã¹ïŒãå«ããã®ãªã¯ãšã¹ããå®å
šã«åŠçããŸãã ã€ãŸããäºåã«ã¢ãŒããã¯ãã£ãæ§ç¯ããªãã§ãã ããã
ãã1ã€ã®çŽ æŽããããã³ãã¯ãã¡ãœããã§ã¯ãªãåäœããã¹ãããããšã§ãã å€ãã®å Žåãããã¯åããã®ã§ã¯ãããŸããã åäœã®åäœã¯ãããã€ãã®ã¡ãœãããŸãã¯ã¯ã©ã¹ã«ãã圱é¿ãåãŒãå¯èœæ§ããããŸãã
ãã1ã€ã®èå³æ·±ãç¹ã¯ããã¹ã察象ã·ã¹ãã ïŒSUTïŒãã³ã³ããã¹ãéäŸåã«ããããšã®æšå¥šäºé
ã§ãã
ãã©ã®ãªããžã§ã¯ããããããå®è¡ãããŠããã·ã¹ãã ã®æŠå¿µãæã€ã¹ãã§ã¯ãããŸããããããã¯ãæ¬è³ªçã«ãã¡ã€ã³ã¢ãã«åé¢ã®æŠå¿µã§ãã ãã¡ã€ã³ã¯ã©ã¹ã¯å€éšã·ã¹ãã ã«äŸåããªãã§ãã ããã çæ³çã«ã¯ãçŸåšã®ç°å¢ããããããå®å
šã«åãé¢ããäœåãªåŽåãªãã§å®è¡ã§ããå¿
èŠããããŸãã ã³ãŒãã®ãã¹ã容ææ§ãšããæãããªå©ç¹ã«å ããŠããã®æ¹æ³ã¯ã³ãŒããåçŽåããŸãã ãã¡ã€ã³ã«é¢ä¿ã®ãªãåŽé¢ïŒããŒã¿ããŒã¹ããããã¯ãŒã¯ãªã©ïŒã«æ³šæãæãããšãªãããµããžã§ã¯ãé åã«éäžã§ããŸãã
ãã®æ¬ã¯ããããªããææããã¢ãã¯ã¿ã€ãã®ã¿ããšããããªãããç¥ãããŠããã«ãŒã«ã®ãœãŒã¹ã§ãã ã€ãŸããèªåã§æžããã¿ã€ãã«ã®ã¿mokiã䜿çšããŸãã ããããªããšãmokiããããã®ã¿ã€ãã®åäœãæ£ããã¢ãã«åããããšãä¿èšŒã§ããŸããã
èå³æ·±ãããšã«ãæ¬ã®äžã§ãèè
èªèº«ããã®ã«ãŒã«ã«æ°åéåããå€éšã©ã€ãã©ãªã®åã«mokiã䜿çšããŠããŸãã ãããã®åã¯éåžžã«åçŽãªã®ã§ãå®éã«ç¬èªã®ã©ãããŒãäœæããŠãããŸãæå³ããããŸããã
äžè¯éšå
å€ãã®è²Žéãªãã³ãã«ããããããããã®æ¬ã¯æœåšçã«æ害ãªæšå¥šäºé
ã瀺ããŠããããã®ãããªæšå¥šäºé
ã¯ããªããããŸãã
èè
ã¯ããã¡ã€ã³ã¢ãã«å
ã®åã
ã®ãªããžã§ã¯ãéã®éä¿¡ã«é¢ããŠãããŠããããã¹ããžã®ã¢ãã¯ã¹ãã¢ãããŒãã®æ¯æè
ã§ãïŒããã§ã¯ã
ã¢ãã¯ã¹ããšã¯ã©ã·ãã¯äž»çŸ©ã®éãã«ã€ããŠè©³ãã説æããŸãïŒã ç§ã®æèŠã§ã¯ãããã¯æ¬ã®æ倧ã®æ¬ ç¹ã§ãããæ®ãã¯ãã¹ãŠæ¬ã®çµæã§ãã
圌ãã®ã¢ãããŒããå®èšŒããããã«ãèè
ã¯ã¢ã©ã³ã»ã±ã€ã«ãã£ãŠäžããããOOPã®å®çŸ©ãæäŸããŸãïŒ
ãäž»ãªã¢ã€ãã¢ã¯ã¡ãã»ãŒãžã³ã°ã§ãã åªããæ¡åŒµå¯èœãªã¢ããªã±ãŒã·ã§ã³ãäœæããããã®éµã¯ãããŸããŸãªã¢ãžã¥ãŒã«ãçžäºã«éä¿¡ããæ¹æ³ãèšèšããããšã§ãããããããå
éšçã«é
眮ãããæ¹æ³ã§ã¯ãããŸããããããŠããªããžã§ã¯ãéã®çžäºäœçšã¯ãåäœãã¹ãäžã«äœãããéèŠãã¹ããã®ã§ãããšçµè«ä»ããŠããŸãã ãã®ããžãã¯ã«ããã°ãã¯ã©ã¹éã®éä¿¡ã¯ãæçµçã«ã·ã¹ãã ãæ¬æ¥ã®ãã®ã«ãããã®ã§ãã
ãã®ãã¥ãŒã«ã¯2ã€ã®åé¡ããããŸãã ãŸããAlan Kayã«ãã£ãŠäžããããOOPã®å®çŸ©ã¯ããã§ã¯äžé©åã§ãã ãã®ãããªåºç¯å²ã«ãããçµè«ããã®æ ¹æ ã«åºã¥ããŠæãããšã¯ããªãææ§ã§ãããçŸä»£ã®OOPèšèªãšã¯ã»ãšãã©å
±éç¹ããããŸããã
ããã«åœŒããã®ããäžã€ã®æåãªåŒçšããããŸãïŒ
ãããªããžã§ã¯ãæåããšãããã¬ãŒãºãæãä»ããŸããããC ++ãæå³ãããã®ã§ã¯ãããŸããã§ãããããããŠãã¡ãããããã§C ++ãå®å
šã«CïŒãŸãã¯Javaã«çœ®ãæããããšãã§ããŸãã
ãã®ã¢ãããŒãã®2çªç®ã®åé¡ã¯ãåã
ã®ã¯ã©ã¹ããã现ããããŠç¬ç«ããã³ãã¥ãã±ãŒã¿ãŒãšèŠãªãããªãããšã§ãã ããããäºãã«éä¿¡ããæ¹æ³ã¯ãã°ãã°å€æŽãããæçµçµæãšã¯ã»ãšãã©é¢ä¿ããããŸãããæçµçµæã¯ãã¹ãã§æ€èšŒããå¿
èŠããããŸãã ãªããžã§ã¯ãéã®éä¿¡ãã¿ãŒã³ã¯å®è£
ã®è©³çŽ°ã§ãããéä¿¡ãã·ã¹ãã ã®å¢çãè¶ãããšããã€ãŸããã¡ã€ã³ã¢ãã«ãå€éšãµãŒãã¹ãšã®éä¿¡ãéå§ãããšãã«ã®ã¿APIã®äžéšã«ãªããŸãã æ®å¿µãªãããæ¬ã¯ãããã®éããçã¿ãŸããã
æ¬ã§ææ¡ãããŠããã¢ãããŒãã®æ¬ ç¹ã¯ã第3ç« ã®ãããžã§ã¯ãã³ãŒããèŠããšæããã«ãªããŸãã ãªããžã§ã¯ãéã®éä¿¡ã«çŠç¹ãåããããšãå®è£
ã®è©³çŽ°ã«é¢äžããããã«ãã¹ããè匱ã«ãªãã ãã§ãªãã埪ç°äŸåé¢ä¿ãããããŒã€ã³ã¿ãŒãã§ã€ã¹ãããã³æœè±¡åã®å±€ãéå°ã«ãªããæŽç·Žãããèšèšã«ãªããŸãã
ãã®èšäºã®æ®ãã®éšåã§ã¯ãæ¬ã®ãããžã§ã¯ããã©ã®ããã«å€æŽã§ãããããããŠãããåäœãã¹ãã«ã©ã®ãããªåœ±é¿ãäžãããã瀺ããŸãã
å
ã®ã³ãŒãããŒã¹ã¯Javaã§èšè¿°ãããä¿®ââæ£ããŒãžã§ã³ã¯CïŒã§èšè¿°ãããŠããŸãã ãŠããããã¹ãããšã³ãããŒãšã³ããã¹ããUIãXMPPãµãŒããŒã®ãšãã¥ã¬ãŒã¿ãªã©ããããžã§ã¯ããå®å
šã«æžãçŽããŸããã
ãããžã§ã¯ã
ã³ãŒãã«çªå
¥ããåã«ããµããžã§ã¯ãé åãèŠãŠã¿ãŸãããã ãã®æ¬ã®ãããžã§ã¯ãã¯ãAuction Sniperã§ãã ãŠãŒã¶ãŒã«ä»£ãã£ãŠãªãŒã¯ã·ã§ã³ã«åå ãããããã ã€ã³ã¿ãŒãã§ã€ã¹ã¯æ¬¡ã®ãšããã§ãã
ã¢ã€ãã ID-çŸåšè²©å£²ãããŠããã¢ã€ãã ã®èå¥åã ã¹ãããäŸ¡æ Œ-ãŠãŒã¶ãŒãšããŠããªããããã«å¯ŸããŠæ¯æãææãããæé«äŸ¡æ Œã æçµäŸ¡æ Œ-ããªããŸãã¯ä»ã®å
¥æè
ããã®ã¢ã€ãã ã«å
¥æããæçµäŸ¡æ Œã æåŸã®å
¥æã¯ãæåŸã«è¡ã£ãäŸ¡æ Œã§ãã ç¶æ
-ãªãŒã¯ã·ã§ã³ã®ç¶æ
ã äžèšã®ã¹ã¯ãªãŒã³ã·ã§ããã§ã¯ãã¢ããªã±ãŒã·ã§ã³ãäž¡æ¹ã®ã¢ã€ãã ãç²åŸããããšãããããŸããããã¯ãäž¡æ¹ã®äŸ¡æ Œãäž¡æ¹ã®ã±ãŒã¹ã§åãã§ããçç±ã§ãã
ãªã¹ãã®åè¡ã¯ããµãŒããŒããã®ã¡ãã»ãŒãžããªãã¹ã³ããå¿çãšããŠã³ãã³ããéä¿¡ããããšã§å¿çããåå¥ã®ãšãŒãžã§ã³ããè¡šããŸãã ããžãã¹ã«ãŒã«ã¯æ¬¡ã®å³ã«èŠçŽã§ããŸãã
åãšãŒãžã§ã³ãïŒãªãŒã¯ã·ã§ã³ã¹ãã€ããŒãšãåŒã°ããŸãïŒã¯ãç»åã®äžéšããåå ç¶æ
ã«ãªããŸãã ãã®åŸããµãŒããŒããªãŒã¯ã·ã§ã³ã®çŸåšã®ç¶æ
ïŒæåŸã®äŸ¡æ Œãå
¥æè
ã®ãŠãŒã¶ãŒåãæåŸã®å
¥æãäžæããããã«å¿
èŠãªæäœäŸ¡æ Œã®äžæïŒãå«ãã€ãã³ããéä¿¡ãããŸã§åŸ
æ©ããŸãã ãã®ã¿ã€ãã®ã€ãã³ãã¯äŸ¡æ ŒãšåŒã°ããŸãã
å¿
èŠãªå
¥æããŠãŒã¶ãŒãã¢ã€ãã ã«èšå®ããã¹ãããäŸ¡æ Œããäœãå Žåãã¢ããªã±ãŒã·ã§ã³ã¯ãã®å
¥æïŒå
¥æïŒãéä¿¡ããå
¥æç¶æ
ã«å
¥ããŸãã æ°ããäŸ¡æ Œã€ãã³ãã§å
¥æãå
è¡ããŠããããšã瀺ãããå Žåãã¹ãã€ããŒã¯äœãããã«åã¡ç¶æ
ã«ãªããŸãã æåŸã«ããµãŒããŒã«ãã£ãŠéåºããã2çªç®ã®ã€ãã³ãã¯Closeã€ãã³ãã§ãã å°çãããšãã¢ããªã±ãŒã·ã§ã³ã¯ãã®ã¢ã€ãã ã®çŸåšã®ã¹ããŒã¿ã¹ã確èªããŸãã åã£ãŠããå Žåã¯åã¡ã«ãªããä»ã®ãã¹ãŠã®ã¹ããŒã¿ã¹ã¯å€±ãããŸãã
ã€ãŸããå®éã«ã¯ããµãŒããŒã«ã³ãã³ããéä¿¡ããå
éšç¶æ
ãã·ã³ããµããŒããããããããããŸãã
ãã®æ¬ã§ææ¡ãããŠããã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ãèŠãŠã¿ãŸãããã ããã圌女ã®å³ã§ãïŒã¯ãªãã¯ããŠæ¡å€§ïŒïŒ
ãã®ãããªåçŽãªã¿ã¹ã¯ã®æž¬å®ãè¶
ããŠè€éããããšæãå Žåãããã¯ããã§ãã ããã§ãã©ã®ãããªåé¡ãèŠãããŸããïŒ
ç®ãåŒãæåã®èŠ³å¯çµæã¯ãå€æ°ã®ããããŒã€ã³ã¿ãŒãã§ã€ã¹ã§ãã ãã®çšèªã¯ããã®ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããåäžã®ã¯ã©ã¹ãå®å
šã«ã³ããŒããã€ã³ã¿ãŒãã§ãŒã¹ãæããŸãã ããšãã°ãXMPPAuctionã¯ãAuctionã€ã³ã¿ãŒãã§ã€ã¹ãš1察1ã§å¯Ÿå¿ããAcutionSniperã¯AuctionEventListenerãšå¯Ÿå¿ããŠããŸãã åäžã®å®è£
ãåããã€ã³ã¿ãŒãã§ãŒã¹ã¯æœè±¡åã§ã¯ãªãã
èšèšèãšèŠãªãããŸãã
以äžã¯ãã€ã³ã¿ãŒãã§ãŒã¹ãªãã®åãå³ã§ãã ãã€ã¢ã°ã©ã ã®æ§é ãããç解ããããããããã«ãããããåé€ããŸããã
ããã§ã®2çªç®ã®åé¡ã¯ã埪ç°äŸåé¢ä¿ã§ãã ãããã®äžã§æãæçœãªã®ã¯XMPPAuctionãšAuctionSniperã®éã§ãããããã ãã§ã¯ãããŸããã ããšãã°ãAuctionSniperã¯SnipersTableModelãåç
§ããæ¥ç¶ã¯AuctionSniperã«æ»ããŸã§SniperLauncherãªã©ãé çªã«åç
§ããŸãã
ãã®ã³ãŒããèªãã§ç解ããããšãããšãã³ãŒãã®åŸªç°çãªäŸåé¢ä¿ãè³ã«è² è·ããããŸãã ãã®çç±ã¯ããã®ãããªäŸåé¢ä¿ã§ã¯ãã©ãããå§ããã°ãããããããªãããã§ãã ã¯ã©ã¹ã®1ã€ã®ç®çãç解ããã«ã¯ã埪ç°çã«çžäºã«æ¥ç¶ãããã¯ã©ã¹ã®ã°ã©ãå
šäœãé ã«å
¥ããå¿
èŠããããŸãã
ãããžã§ã¯ãã³ãŒããå®å
šã«æžãçŽããåŸã§ããããŸããŸãªã¯ã©ã¹ãšã€ã³ã¿ãŒãã§ã€ã¹ãäºãã«ã©ã®ããã«é¢é£ããŠããããç解ããããã«ãããªãé »ç¹ã«å³ã«ç®ãåããå¿
èŠããããŸããã ç§ãã¡äººéã¯éå±€ãããç解ããŠããã埪ç°ã°ã©ãã§ã¯ãã°ãã°å°é£ãæ±ããŠããŸãã Scott Wlaschinã¯ããã®ããŒãã«é¢ããåªããèšäºãæžããŠããŸãã
åšæçãªäŸåé¢ä¿ã¯æªã§ãã
3çªç®ã®åé¡ã¯ããã¡ã€ã³ã¢ãã«ã®åé¢ã®æ¬ åŠã§ãã DDDããèŠãã¢ãŒããã¯ãã£ã¯æ¬¡ã®ãšããã§ãã
äžéã®ã¯ã©ã¹ã¯ãã¡ã€ã³ã¢ãã«ãæ§æããŸãã åæã«ããªãŒã¯ã·ã§ã³ãµãŒããŒïŒå·ŠïŒãšUIïŒå³ïŒãšéä¿¡ããŸãã ããšãã°ãSniperLauncherã¯XMPPAuctionHouseãšéä¿¡ããAuctionSniperã¯XMPPAcutionãšSnipersTableModelãšéä¿¡ããŸãã
ãã¡ãããå®éã®ã¯ã©ã¹ã§ã¯ãªãã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãããè¡ããŸãããããã§ããã¢ãã«ã«ããããŒã€ã³ã¿ãŒãã§ã€ã¹ãè¿œå ããŠããäŸåé¢ä¿å転ã®ååã«åŸã£ãŠèªåçã«éå§ãããããã§ã¯ãããŸããã
çæ³çã«ã¯ããã¡ã€ã³ã¢ãã«ã¯èªçµŠèªè¶³ã§ããå¿
èŠãããããã®å
éšã®ã¯ã©ã¹ã¯å€éšã®ã¯ã©ã¹ãšéä¿¡ããããç¹å®ã®å®è£
ãã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããããŠã¯ãªããŸããã é©åãªåé¢ãšã¯ãã¢ãã䜿çšããã«æ©èœçãªã¢ãããŒãã䜿çšããŠãã¡ã€ã³ã¢ãã«ããã¹ãã§ããããšãæå³ããŸãã
ããããã¹ãŠã®æ¬ ç¹ã¯ãéçºè
ããããªãã¯APIã§ã¯ãªãããã¡ã€ã³ã¢ãã«å
ã®ã¯ã©ã¹éã®çžäºäœçšã®ãã¹ãã«éäžããŠããç¶æ³ã®äžè¬çãªçµæã§ãã ãã®ã¢ãããŒãã«ãããããããŒã€ã³ã¿ãŒãã§ã€ã¹ãäœæãããŸãã ããããªããšãè¿é£ã®ã¯ã©ã¹ãã殺ããããšãã§ããªããªããå€æ°ã®åŸªç°äŸåé¢ä¿ããã¡ã€ã³ã¯ã©ã¹ãå€éšãšçŽæ¥éä¿¡ã§ããªããªããŸãã
åäœãã¹ãèªäœãèŠãŠã¿ãŸãããã ãããã®1ã€ã®äŸã次ã«ç€ºããŸãã
@Test public void reportsLostIfAuctionClosesWhenBidding() { allowingSniperBidding(); ignoringAuction(); context.checking(new Expectations() {{ atLeast(1).of(sniperListener).sniperStateChanged( new SniperSnapshot(ITEM_ID, 123, 168, LOST)); when(sniperState.is(âbiddingâ)); }}); sniper.currentPrice(123, 45, PriceSource.FromOtherBidder); sniper.auctionClosed(); }
ãŸãããã®ãã¹ãã¯ã¯ã©ã¹éã®éä¿¡ã«çŠç¹ãåœãŠãŠãããããã¢ãã¯ã®äœæã«é¢é£ãã倧éã®ã³ãŒããäœæããã³ç¶æããå¿
èŠããããŸãããããã¯ããã§ã¯æãéèŠãªããšã§ã¯ãããŸããã ããã§ã®äž»ãªæ¬ ç¹ã¯ããã®ãã¹ãã«ãã¹ããªããžã§ã¯ãã®å®è£
ã®è©³çŽ°ã«é¢ããæ
å ±ãå«ãŸããŠããããšã§ãã ããã§ã®whenæã¯ããã¹ããã·ã¹ãã ã®å
éšç¶æ
ãèªèãããã®ç¶æ
ãã·ãã¥ã¬ãŒãããŠãã¹ãããããšãæå³ããŸãã
å¥ã®äŸã次ã«ç€ºããŸãã
private final Mockery context = new Mockery(); private final SniperLauncher launcher = new SniperLauncher(auctionHouse, sniperCollector); private final States auctionState = context.states(âauction stateâ).startsAs(ânot joinedâ); @Test public void addsNewSniperToCollectorAndThenJoinsAuction() { final Item item = new Item(âitem 123â, 456); context.checking(new Expectations() {{ allowing(auctionHouse).auctionFor(item); will(returnValue(auction)); oneOf(auction).addAuctionEventListener(with(sniperForItem(item))); when(auctionState.is(ânot joinedâ)); oneOf(sniperCollector).addSniper(with(sniperForItem(item))); when(auctionState.is(ânot joinedâ)); one(auction).join(); then(auctionState.is(âjoinedâ)); }}); launcher.joinAuction(item); }
ãã®ã³ãŒãã¯ãã·ã¹ãã ã®å®è£
ã®è©³çŽ°ã«é¢ããç¥èã®æŒãã®æ確ãªäŸã§ãã ãã®äŸã®ãã¹ãã§ã¯ãæ¬æ Œçãªã¹ããŒããã·ã³ãå®è£
ããŠããã¹ããããã¯ã©ã¹ããã®ç¹å®ã®é åºïŒæåŸã®3è¡ïŒã§è¿é£ã®ã¡ãœãããåŒã³åºãããšã確èªããŸãã
public class SniperLauncher implements UserRequestListener { public void joinAuction(Item item) { Auction auction = auctionHouse.auctionFor(item); AuctionSniper sniper = new AuctionSniper(item, auction); auction.addAuctionEventListener(sniper);
ãã¹ã察象ã·ã¹ãã ã®å
éšãšã®æ¥ç¶æ§ãé«ãããããã®ãããªãã¹ãã¯éåžžã«è匱ã§ãã ãã®ãªãã¡ã¯ã¿ãªã³ã°ãäœããå£ãããã©ããã«é¢ä¿ãªããäºçŽ°ã§ãªããªãã¡ã¯ã¿ãªã³ã°ã¯ãã¹ãŠãã®åŽ©å£ã«ã€ãªãããŸãã ããã«ããã䟡å€ã倧å¹
ã«äœäžããŸãã ãã¹ãã¯ãã°ãã°åœéœæ§ãããããããã®ãããä¿¡é Œã§ããã»ãŒããã£ãããã®äžéšãšããŠèªèãããªããªããŸãã
ãã®æ¬ã®ãããžã§ã¯ãã®å®å
šãªãœãŒã¹ã³ãŒãã¯ã次ã®
ãªã³ã¯ããå
¥æã§ããŸãã
mokã䜿çšããªã代æ¿å®è£
äžèšã®ãã¹ãŠã¯éåžžã«æ·±å»ãªå£°æã§ãããæããã«ãç§ã¯ãããã代æ¿ãœãªã¥ãŒã·ã§ã³ã§ããã¯ã¢ããããå¿
èŠããããŸãã ãã®ä»£æ¿ãœãªã¥ãŒã·ã§ã³ã®å®å
šãªãœãŒã¹ã³ãŒãã¯ã
ããã«ãããŸã ã
ãã¡ã€ã³ãã¡ã€ã³ãé©åã«åé¢ãã埪ç°çãªäŸåé¢ä¿ãäžèŠãªæœè±¡åãé床ã«è¡ããã«ãããžã§ã¯ããå®è£
ããæ¹æ³ãç解ããããã«ãã¢ããªã±ãŒã·ã§ã³é¢æ°ãèŠãŠã¿ãŸãããã ãµãŒããŒããã€ãã³ããåãåããããã€ãã®ã³ãã³ãã§ã€ãã³ãã«å¿çããå
éšç¶æ
ãã·ã³ããµããŒãããŸãã
ãããŠãããã¯æ¬è³ªçã«ãã¹ãŠã§ãã å®éã«ã¯ãããã¯ã»ãŒçæ³çãªé¢æ°åããã°ã©ãã³ã°ã¢ãŒããã¯ãã£ã§ããããã®ãããªå®è£
ã劚ãããã®ã¯äœããããŸããã
代æ¿ãœãªã¥ãŒã·ã§ã³ãã£ãŒãã®å€èŠ³ã¯æ¬¡ã®ãšããã§ãã
ããã€ãã®éèŠãªéããèŠãŠã¿ãŸãããã ãŸãããã¡ã€ã³ã¢ãã«ã¯å€çããå®å
šã«åé¢ãããŠããŸãã ãã®äžã®ã¯ã©ã¹ã¯ããã¥ãŒã¢ãã«ãŸãã¯XMPPãµãŒããŒãšçŽæ¥å¯Ÿè©±ããããã¹ãŠã®ãªã³ã¯ã¯ãã¡ã€ã³ã¯ã©ã¹ã«åã
ãã ããã®éã¯ãããŸããã
ãµãŒããŒã§ããããšUIã§ããããšãå€çãšã®ãã¹ãŠã®éä¿¡ã¯ã¢ããªã±ãŒã·ã§ã³ãµãŒãã¹ã¬ã€ã€ãŒã«äžããããŸãããã®ã¬ã€ã€ãŒã¯ããã®å ŽåAuctionSniperViewModelã«ãã£ãŠåçãããŸãã ããã¯ãå€çã®äžèŠãªåœ±é¿ãããã¡ã€ã³ã¢ãã«ãä¿è·ããã·ãŒã«ããšããŠæ©èœããŸããçä¿¡ã€ãã³ãããã£ã«ã¿ãªã³ã°ããçºä¿¡ã³ãã³ãã解éããŸãã
第äºã«ããã¡ã€ã³ã¢ãã«ã«ã¯åŸªç°äŸåé¢ä¿ãå«ãŸããŠããŸããã ã¯ã©ã¹ã®æ§é ã¯ããªãŒã«äŒŒãŠããŸããã€ãŸããæœåšçãªæ°ããéçºè
ã¯ããã®ã³ãŒããèªã¿å§ããããšãã§ããæ確ãªå Žæãæã£ãŠããŸãã äžåºŠã«ããªãŒå
šäœãé ã«çœ®ãå¿
èŠãªããããªãŒãæ圢ããŠããªãŒã段éçã«äžã«ç§»åããããšããå§ããããŸãã ãã¡ããããã®ç¹å®ã®ãããžã§ã¯ãã®ã³ãŒãã¯éåžžã«åçŽãªã®ã§ã埪ç°äŸåé¢ä¿ããã£ããšããŠããåé¡ãªãèªãããšãã§ããŸãã ãã ããããè€éãªã·ããªãªã§ã¯ãåçŽããšèªã¿ãããã®èŠ³ç¹ãããæ確ãªããªãŒæ§é ã倧ããªãã©ã¹ã«ãªããŸãã
ãšããã§ãããç¥ãããŠããDDDãã¿ãŒã³-Aggregate-ã¯ããã®ç¹å®ã®åé¡ã解決ããããšãç®çãšããŠããŸãã è€æ°ã®ãšã³ãã£ãã£ã1ã€ã®éåäœã«ã°ã«ãŒãåããããšã«ããããã¡ã€ã³ã¢ãã«å
ã®ãªã³ã¯ã®æ°ãæžãããŠãã³ãŒããç°¡çŽ åããŸãã
ããã§ã®3çªç®ã®éèŠãªç¹ã¯ã代æ¿ããŒãžã§ã³ã«ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãå«ãŸããŠããªãããšã§ãã ããã¯ãå®å
šã«åé¢ããããã¡ã€ã³ã¢ãã«ãæã€ããšã®å©ç¹ã®1ã€ã§ããå®éã®æœè±¡åãè¡šããŠããªãå Žåãã€ã³ã¿ãŒãã§ã€ã¹ãã³ãŒãã«æ¿å
¥ããå¿
èŠã¯ãããŸããã ãã®äŸã§ã¯ããã®ãããªæœè±¡åã¯ãããŸããã
æ°ããå®è£
ã®ã¯ã©ã¹ã¯ãç®çã«å¿ããŠæ確ã«åããããŠããŸãã ãããã¯ããã¡ã€ã³ã¢ãã«å
ã®ã¯ã©ã¹ã§ããããžãã¹ç¥èãå«ããããã¡ã€ã³ã¢ãã«å€ã®ã¯ã©ã¹ã§ããå€çãšéä¿¡ããŸãããäž¡æ¹ã¯ãããŸããã ãã®è·åã®åé¢ã«ãããäžåºŠã«1ã€ã®åé¡ã«éäžããããšãã§ããŸãããã¡ã€ã³ããžãã¯ã«ã€ããŠèããããUIãšãªãŒã¯ã·ã§ã³ãµãŒããŒããã®ã€ã³ã»ã³ãã£ããžã®å¯Ÿå¿æ¹æ³ã決å®ããŸãã
ç¹°ãè¿ãã«ãªããŸãããããã«ããã³ãŒããç°¡çŽ åãããŸããã€ãŸãããµããŒãã匷åãããŸãã
Application Servicesã¬ã€ã€ãŒã®æãéèŠãªéšåã¯æ¬¡ã®ãšããã§ãã
_chat.MessageReceived += ChatMessageRecieved; private void ChatMessageRecieved(string message) { AuctionEvent ev = AuctionEvent.From(message); AuctionCommand command = _auctionSniper.Process(ev); if (command != AuctionCommand.None()) { _chat.SendMessage(command.ToString()); } }
ããã§ã¯ããªãŒã¯ã·ã§ã³ãµãŒããŒããæååãååŸããã€ãã³ãã«å€æãïŒæ€èšŒã¯ãã®æé ã«å«ãŸããŸãïŒãã¹ãã€ããŒã«æž¡ããçµæã®ã³ãã³ããNoneã§ãªãå ŽåããµãŒããŒã«éãè¿ããŸãã ã芧ã®ãšãããããžãã¹ããžãã¯ããªããããã¢ããªã±ãŒã·ã§ã³ãµãŒãã¹ã¬ã€ã€ãŒã¯ç°¡åã«ãªããŸãã
ã¢ããªãã®ãã¹ã
åé¢ãã¡ã€ã³ã¢ãã«ã®ãã1ã€ã®å©ç¹ã¯ãæ©èœçãªã¢ãããŒãã䜿çšããŠãã¹ãã§ããããšã§ãã åäœã®åéšåãäºãã«åé¢ããŠæ€èšãããã®çµæãã©ã®çšåºŠæ£ç¢ºã«éæããããã«æ³šæãæãããšãªããçæãããæçµçµæã確èªã§ããŸãã
ããšãã°ã次ã®ãã¹ãã§ã¯ããªãŒã¯ã·ã§ã³ã«åå ããã°ããã®SniperãCloseã€ãã³ãã®åä¿¡ã«ã©ã®ããã«åå¿ãããã確èªããŸãã
[Fact] public void Joining_sniper_loses_when_auction_closes() { var sniper = new AuctionSniper(ââ, 200); AuctionCommand command = sniper.Process(AuctionEvent.Close()); command.ShouldEqual(AuctionCommand.None()); sniper.StateShouldBe(SniperState.Lost, 0, 0); }
çµæã®ã³ãã³ãã空ã§ããããšãã€ãŸãã¹ãã€ããŒãã¢ã¯ã·ã§ã³ãå®è¡ããŠããªãããšãããã³ç¶æ
ããã®åŸLostã«ãªã£ãããšã確èªããŸãã
å¥ã®äŸã瀺ããŸãã
[Fact] public void Sniper_bids_when_price_event_with_a_different_bidder_arrives() { var sniper = new AuctionSniper(ââ, 200); AuctionCommand command = sniper.Process(AuctionEvent.Price(1, 2, âsome bidderâ)); command.ShouldEqual(AuctionCommand.Bid(3)); sniper.StateShouldBe(SniperState.Bidding, 1, 3); }
ãã®ãã¹ãã§ã¯ãçŸåšã®äŸ¡æ Œãšæå°å¢åãèšå®ãããäŸ¡æ Œå¶éãããå°ããå Žåã«ãçæå
µããªã¯ãšã¹ããéä¿¡ããããšã確èªããŸãã
mokaãæ£åœåãããå¯èœæ§ãããå¯äžã®å Žæã¯ãå€éšã·ã¹ãã ãšéä¿¡ããApplication Servicesã¬ã€ã€ãŒããã¹ããããšãã§ãã ãããããã®éšåã¯ãšã³ãããŒãšã³ãã®ãã¹ãã§ã«ããŒãããŠããããããã®ç¹å®ã®ã±ãŒã¹ã§ã¯ããã¯å¿
èŠãããŸããã ã¡ãªã¿ã«ããã®æ¬ã®ãšã³ãããŒãšã³ãã®ãã¹ãã¯çŽ æŽããããå€æŽãæ¹åãå¯èœãªãã®ã¯èŠã€ãããŸããã§ããã
代æ¿å®è£
ã®ãœãŒã¹ã³ãŒãã¯ã
ããã«ãããŸã ã
ãããã«
åã
ã®ã¯ã©ã¹éã®éä¿¡ã«çŠç¹ãåããããšããã¹ããè匱ã«ãªãããããžã§ã¯ãã¢ãŒããã¯ãã£èªäœãç ŽæããŸãã
ãããã®æ¬ ç¹ãåé¿ããã«ã¯ïŒ
- ãã¡ã€ã³ã¯ã©ã¹ã®ããããŒã€ã³ã¿ãŒãã§ã€ã¹ãäœæããªãã§ãã ããã
- ã³ãŒãå
ã®åŸªç°äŸåé¢ä¿ã®æ°ãæå°éã«ããŸãã
- ãã¡ã€ã³ã¢ãã«ãåé¢ããŸãããã¡ã€ã³ã¯ã©ã¹ãå€éšãšéä¿¡ããªãããã«ããŸãã
- äžèŠãªæœè±¡åãæžãããŸãã
- ãã¡ã€ã³ã¢ãã«ããã¹ããããšãã¯ãã¯ã©ã¹éã®éä¿¡ã§ã¯ãªããç¶æ
ãšæçµçµæã®ç¢ºèªã«çŠç¹ãåãããŸãã
Pluralsightã³ãŒã¹
å®çšçãªåäœãã¹ãã«é¢ããæ°ããPluralsightã³ãŒã¹ãåè¬ããŸããã ãã®äžã§ããŠããããã¹ãã®æ§ç¯ã®å®è·µã«ã€ããŠè©±ãããšããŸãããããã«ãããæå°éã®åŽåã§æé«ã®çµæãåŸãããŸããã äžèšã®èšäºã®ã¬ã€ãã©ã€ã³ããã®ã³ãŒã¹ã®äžéšã«ãªããå€ãã®äŸãšãšãã«è©³çŽ°ã«æ€èšãããŠããŸãã
ãŸãã30æ¥éïŒç§ã®ã³ãŒã¹ã ãã§ãªããã©ã€ãã©ãªå
šäœã«ïŒPluralsightã«ç¡å¶éã«ã¢ã¯ã»ã¹ã§ããå€æ°ã®ãã©ã€ã¢ã«ã³ãŒãããããŸãã 誰ããå¿
èŠãªå Žå-å人çã«æžããŠãç§ã¯åãã§ãããå
±æããŸãã
ã³ãŒã¹ãªãã¡ã¬ã³ã¹ïŒ
å®çšçãªåäœãã¹ãã¹ã€ãŒãã®æ§ç¯ ã