çãããããã«ã¡ã¯ïŒãããã¯ããã°ãã¯ïŒ 楜楜粟ç®ãããã¯ããããŒãžã£ãŒã®wekkyyyyã§ãã ååã¯ããæ¥œæ¥œç²Ÿç®PdMã®æ¥åå
容ã玹ä»ããŸãããšããã¿ã€ãã«ã§èšäºãæžãããŠããã ããŸããã tech-blog.rakus.co.jp ä»åã¯ã第äºåŒŸãšã㊠PBIã®åªå
床èšå®æ¹æ³ã®ãã€ã³ããšèšå®ããããšã®çã ãšããããŒãã§ããã°ãèšèŒããŸãã ä»åãã®ããŒãã§æžãããšæã£ããã£ããã¯ã åŒç€Ÿå
ãPdMã³ãã¥ããã£ã®äžã§ ããªãã§ãã®æ¡ä»¶ãåªå
ããããã ããïŒä»ã«ãããã®ã«ãããã ãæ¬¡ã«äœéçºãããã ããïŒã§ããã°å°ããã€èŠéã«ãããŠãããããªããã ãšãã£ãçåãæãããŠããæ¹ãäžå®æ°ããããšã確èªã§ãããããã£ãæ¹éã®äžå©ã«ãªã察å¿äºäŸãæäŸã§ããã°ã»ã»ã»ãšæã£ãããšã§ãã ããèšãç§ããPdMé§ãåºãã®é ã¯äžèšã®ããšãæã£ãŠãŸããã ãããäžæºãšãã圢ã§äžåžã«ã¶ã€ããŠããŸãããããªãã³ãã¥ãã±ãŒã·ã§ã³ãåã£ãŠããŸã£ãŠããŸãããïŒä»æããšéåžžã«æ¥ãããããç³ãèš³ãªãéãã§ãïŒ åæ PBIã®åªå
床èšå®ã®çã PBIã®åªå
床èšå®æ¹æ³ã®ãã€ã³ã 泚æç¹ ä»åŸã®å·çå
容(倿Žå¯èœæ§ãã) ã©ã¯ã¹ã®PdMãšããŠæŽ»èºããŠã¿ãŸããã? åæ åŒç€Ÿãããã¯ãã®äžã§ã楜楜粟ç®ãã§ã®äºäŸãèšèŒããŠãããŸãã åªå
床èšå®æ¹æ³ã® äžäŸ ãšããŠæããŠãã ããã ãããâ»äŒæ¥ã«ãã£ãŠããããã®ç¶æ³ãèãæ¹ãããã®ã§é©ããåœ¢ãæ¢ããŠãã ããã PBIã®åªå
床èšå®ã®çã 1. é¢ä¿è
ããå
ãèŠæ®ããŠè¡åã§ããåå°ãã€ãã ãããã¯ããããŒãžã£ãŒç®ç·ïŒ é¡åšåããŠãã課é¡ã«å¯Ÿãããœãªã¥ãŒã·ã§ã³æ¡ãæ€èšãèç©ããŠããããšãçã£ãŠããŸãã ããã«ããéçºãªãœãŒã¹ã®ç©ºããåºãéã«ããã«éçºã«èŠæ±ä»æ§ãæž¡ãããããªãããã§ãã æ¬¡ã«èª¿æ»ãã¹ã課é¡ã®èšç»ãäºåã«ç«ãŠãŠãããåãåºããæ©ãããããšãçã£ãŠããŸãã 調æ»èšç»ãç«ãŠãããã«ã¯æå€ãšæéãããããšèããŠããããã§ãã(ã©ãããèšç»ïŒã¯å¥èšäºã§æžãäºå®ã§ã) ãšã³ãžãã¢ç®ç·ïŒ æè¡æ¹åææ¡ãããéã«ã广ãå¢å ã§ããæ¡ä»¶ããããäºåã«ææ¡ãææ¡ã¿ã€ãã³ã°ãå
容ãå³ãããããªãããšãçã£ãŠããŸãã æè¡ã«å¯ã£ãŠããŸã£ãŠããŠãŒã¶ãŒããŒãºãããžãã¹ãŽãŒã«ãšçŽã¥ããªãããšãé¿ããããã§ãã 2. åªå
床ã«ã€ããŠäŒè©±ã®ã¬ãã«ãäžãã ãä»ã®åªå
床èšå®æ¹æ³ã ãšãã®èª²é¡ãããããªã®ã§ãã®ããã«å€ããããããšããã³ãã¥ãã±ãŒã·ã§ã³ã«ããŠããããšãçã£ãŠããŸãã åªå
床èšå®æ¹æ³ã®åå°ããªããšãåæèªèå
容ãåããã«é¢ä¿è
ã³ãã¥ãã±ãŒã·ã§ã³ãé£ãããªãããšãå€ããšèããŠããããã§ãã PBIã®åªå
床èšå®æ¹æ³ã®ãã€ã³ã 1. éçºã«ããŽãªåé¡ã決ãã æ¥œæ¥œç²Ÿç®ã§ã¯ã以äžã®éçºã«ããŽãªã«åããŠããŸãã 2. ã«ããŽãªã®åªå
åºŠãæ±ºãã æ¥œæ¥œç²Ÿç®ã§ã¯ãç¶æç®¡çæ¡ä»¶ãåºæ¬åªå
ãããããã«ããŠããŸãã ãâ»å¯Ÿå¿æéã«ããåŸåãã«ããããšã¯ãããŸãã 3. ã«ããŽãªå
ã®åªå
åºŠææšãæ±ºãã ç¶æç®¡çïŒå¯Ÿå¿æéïŒææ¥ãæ©ããã®ããïŒ è²¡å广ïŒå€±æ³šãè§£çŽMRRã®åèšMRRïŒéé¡ãé«ããã®ããïŒ ãæ¥œæ¥œç²Ÿç®ã§ã¯ææšãšããŠå®ããŠããŸãã 財å广ã«ãããŠããããã§äºæ¥ç®æšãéæã§ããã®ïŒããšãã声ãããããã§ãããããã¯ãŸãå¥èšäºã§èª¬æããŸãã 4. éçºãªã¹ãå
¥ãã®æ¡ä»¶ã決ãã ãããŸã§ãèŠããšãç¶æç®¡çã«å
¥ããŠããŸãã°äœã§ãåªå
ãããããã«ã¿ããŠããŸããŸãã ã§ããããã®ç¶æ
ã¯å¥å
šã§ã¯ãªãã®ã§ãã§ãã«ãŒ(äºæ¥æ¬éšé·ãéçºéšé·ã®æ¿èªïŒã眮ããŠããŸãã æ³šæç¹ äžèšãåºæ¬ã«ãŒã«ãšãªããŸãããäºæ¥æŠç¥çãªäºæ
ã§äžéšåªå
床å€ããå ŽåãããããŸãã ãŠãŒã¶ããªã㣠芳ç¹ã§èŠãªãããã§ã¯ãããŸããã倱泚ãè§£çŽã«çµã³ã€ããªãäºè±¡ã¯åªå
床ãäžãããšãã圢ã§ãã ãã°ãã€ã³ã·ãã³ã察å¿ã¯ãå¥é ãããå€ ãæ±ºããŠå¯Ÿå¿ãé²ããŠããå¿
èŠããããŸãã ã³ã¹ãåæžæ¡ä»¶ãããå Žå 財åå¹æèŠ³ç¹ã§åªå
åºŠãæ±ºããŸãã ä»åŸã®å·çå
容(倿Žå¯èœæ§ãã) éçºæ¡ä»¶ã«ã€ãªãå¶æ¥/CSããã®VoCåéæ¹æ³ ã©ã¯ ã¹ã®ãããã¯ããããŒãžã£ãŒã«å¿
èŠãªã¹ãã« ãšã³ãžãã¢ãšã®ã³ãã¥ãã±ãŒã·ã§ã³è¡ ã©ã¯ ã¹ã®PdMãšããŠæŽ»èºããŠã¿ãŸããã? 楜楜粟ç®PdMã¯ãåŒãç¶ã人æãåéããŠãããŸãã æ¯éã«ãžã¥ã¢ã«é¢è«ãããç³ã蟌ã¿ããã ãããšå¹žãã§ãã プロダクトマネージャー | エンジニア職種紹介 | 株式会社ラクス キャリア採用
å§ãã« åŒç€Ÿã§ã¯ã æ°è¡ãšç»åïŒæã®éçããŒãžã衚瀺ãããããã ã ã«ã1å°ãµãŒããŒãæ§ç¯ãä¿å®éçšããŠãŸããã ããã ãã®ããã«ã1å°ã®ãµãŒããŒãä¿å®éçšããã®éŠ¬é¹¿ããããïŒïŒïŒïŒïŒïŒ ããïŒéŠ¬é¹¿ãããïŒïŒïŒ ãšããããšã§ã AWS äžã«ç§»è¡ããããš ãšãªããŸãã ã«ããŸããã ä»åã¯ãS3ãšCloudFrontãå©çšããŠéçããŒãžã衚瀺ãããèšå®ãã玹ä»ãããŠããã ããŸãã åæ©çãªå
容ãšãªããŸãã®ã§ãããããéçããŒãžãäœããããã ãã©ïŒãšãã£ãæ¹åãã®å
容ãšãªããŸãã å§ãã« èŠä»¶ æ§æã«ã€ã㊠AWSã®å©çšãµãŒãã¹ æ§æå³ å®éã®èšå®æé S3èšå® 1. ãã±ããäœæ 2. indexãã¡ã€ã«ã®ã¢ããããŒã CloudFrontèšå® 1. ãã£ã¹ããªãã¥ãŒã·ã§ã³ãäœæ 2.ããªã·ãŒèšå® 3.æ¥ç¶ç¢ºèª Route53 èšå® 1. ã«ã¹ã¿ã SSL èšŒææžçºè¡ 2. CNAMEç»é² 3. ã«ãŒãã£ã³ã°èšå® 4.ã«ã¹ã¿ã SSL èšŒææžèšå® 5.確èªäœæ¥ HTTPã¬ã¹ãã³ã¹ã®å€æŽ 1. Cloud Front颿° 2. Cloud FrontçŽã¥ã 3.確èªäœæ¥ ãããã« èŠä»¶ ä»åã®èŠä»¶ã¯äžèšã§ãã åŒç€Ÿã® ãã¡ã€ã³ ãå©çšå¯èœ HTTPã¬ã¹ãã³ã¹ã³ãŒã(501 ã 503 çªå°ç) ãä»»æã®ãã®ã«å€æŽãå¯èœ https éä¿¡ã§éçããŒãžã衚瀺å¯èœ åŒç€Ÿã®ã·ã¹ãã åŽããã®FWã®èš±å¯èšå®ã远å ã®å¿
èŠããªã æ§æã«ã€ã㊠AWS ã®å©çšãµãŒãã¹ Route53 : ç¬èªãã¡ã€ã³ ãç»é²ããããã«å©çš CloudFront : ç¬èªãã¡ã€ã³ ã®å©çšåã³ã¬ã¹ãã³ã¹ã³ãŒããä»»æã®ãã®ã«å€æŽããããã«å©çš S3 : éçãã¡ã€ã«(HTML) ãé
眮 æ§æå³ æ§æã¯äžèšãæ³å®ããŠããŸãã å®éã®èšå®æé ããã§ã¯æ©éèšå®æé ã«å
¥ãããŠããã ããŸãã S3èšå® éçããŒãžãä¿åããããã ãã«å©çšããŠãããŸãã æ¬çªãµãŒãã¹ã§çšŒåããéã«ã¯ããã°ä¿åã®èšå® ã æš©éã®èšå®ãªã©ãè²ã
ãããã£ãŠããŸããã ä»åã¯æäœéã®èšå®ã ããšãªããŸãã 1. ãã±ãã äœæ äžèšã®èšå®æé ã§ ãã±ãã ãèšå®ãã ãã±ãã å: rakus-tset ä»ã®èšå®: ããã©ã«ã 2. indexãã¡ã€ã«ã®ã¢ããããŒã äžèšã®ãã¡ã€ã«ãäœæãã ãã±ãã ã«ä¿åããŸãã index.html <!DOCTYPE html> <html lang="ja"> <head> <title>hello rakus!</title> </head> <body> <h1>hello rakus!</h1> </body> </html> CloudFrontèšå® ç¬èªãã¡ã€ã³ ã®å©çš åã³ ã¬ã¹ãã³ã¹ã³ãŒããä»»æã®ãã®ã«å€æŽããããã«å©çšããŸãã ãŸãã¯ã ç¬èªãã¡ã€ã³ ãå©çšããã«httpéä¿¡ãå¯èœãªãšãããŸã§èšå®ããŸãã 1. ãã£ã¹ããªãã¥ãŒã·ã§ã³ ãäœæ ãã£ã¹ããªãã¥ãŒã·ã§ã³ ã¯äžèšã®ããã«èšå®ããŸãã ãªãªãžã³ ãã¡ã€ã³ : äœæããS3 ãéžæ ãªãªãžã³ã¢ã¯ã»ã¹ : Origin access control settings (recommended) Origin access control : ã³ã³ ãããŒã« èšå®ãäœæ â»ããã©ã«ãã§äœæ ãŠã§ãã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã¢ãŠã©ãŒã« (WAF):ä¿è·ããªã æéã¯ã©ã¹ : åç±³ãšæ¬§å·ã®ã¿ãäœ¿çš IPv6 : ãªã ä»ã®èšå®: ããã©ã«ã 2.ããªã·ãŒèšå® 該åœãªãªãžã³ã®ããŒãžã«æ»ã£ãéã«äžèšã®ããã«ã§ãŠãããããäœæããS3ã® ãã±ãã ããªã·ãŒã«ã³ããã§èšå®ãããŸãã 3.æ¥ç¶ç¢ºèª ãããŸã§ã§äžèšã«ã¢ã¯ã»ã¹ã§ããããã«ãªã£ãããã確èªããŸãã https://ãã£ã¹ããªãã¥ãŒã·ã§ã³ãã¡ã€ã³å/index.html Route53 èšå® DNS ã«CNAME ã ã«ãŒãã£ã³ã°ã®èšå®ãè¡ããŸãã ãã®èšå®ãè¡ãããšã§ãCloudFront ãš ç¬èªãã¡ã€ã³ ãçŽã¥ãã ç¬èªãã¡ã€ã³ ã§ã® https éä¿¡ãè¡ããããã«ãªããŸãã 1. ã«ã¹ã¿ã SSL èšŒææžçºè¡ ãã¡ããCloudFrontã®ç»é¢ããèšå®ããŸãã 該åœã® ãã£ã¹ããªãã¥ãŒã·ã§ã³ ã®èšå®ãã ã«ã¹ã¿ã SSL èšŒææž ã®é
äžã«ãã [èšŒææžããªã¯ ãšã¹ ã] ãæŒäžããŸãã èšå®ç»é¢ã®éãã«é²ãã§ãããŸãã äžèšã®éãã§èšå®ããŠãããŸãã å®å
šä¿®é£Ÿ ãã¡ã€ã³ å: ä»»æ ä»ã®èšå®: ããã©ã«ã 2. CNAMEç»é² ç»é²åŸäžèšã®ããã«ã§ãããã èšŒææžã®è¡šç€ºãæŒäžããŸãã ãã®åŸãRoute 53 ã§ã¬ã³ãŒããäœæãæŒäžããŠRoute53ã«ç»é²ããŸãã æ€èšŒãçµãããŸã§åŸ
æ©ããŸãã 3. ã«ãŒãã£ã³ã°èšå® Route53 ã®ãµãŒããŒãžã¢ã¯ã»ã¹ãã該åœãã¹ããŸãŒã³ã«é·ç§»ããäžèšã®èšå®ãç»é²ããŸãã ã¬ã³ãŒãå: èšå®ãã ãã¡ã€ã³ å ã¬ã³ãŒãã¿ã€ã : A ãšã€ãªã¢ã¹ : ã¯ã ãã©ãã£ã㯠ã®ã«ãŒãã£ã³ã°å
: äœæãã ãã£ã¹ããªãã¥ãŒã·ã§ã³ ãéžæ 4.ã«ã¹ã¿ã SSL èšŒææžèšå® 該åœã® ãã£ã¹ããªãã¥ãŒã·ã§ã³ ã®èšå®ãäžèšã®ããã«å€æŽããŸãã ä»£æ¿ ãã¡ã€ã³ å (CNAME) : å
ã»ã©ç»é²ããCNAME ã«ã¹ã¿ã SSL èšŒææž : ã«ã¹ã¿ã SSL èšŒææžçºè¡ã§äœæãããã® 5.確èªäœæ¥ äžèšã®ã³ãã³ã宿œããŸãã curl -I https://ãã¡ã€ã³å/index.html çŸç¶ã§ã¯ãã¬ã¹ãã³ã¹ã³ãŒãã200çªã§è¿ã£ãŠããŸãã HTTPã¬ã¹ãã³ã¹ã®å€æŽ httpã¬ã¹ãã³ã¹ã400çªå°ã500çªå°ã§è¿ãããããããã¡ãã®å
容ãèšå®ããŠãããŸã Viewer Response Eventã§ãHTTPã¬ã¹ãã³ã¹ã³ãŒããæžãæããŸã 1. Cloud Front颿° Cloud Frontã®é¢æ°é
ç®ããäžèšãäœæããŸãã åå: ä»»æ 説æ: ä»»æ 説æ: éçºã³ãŒãã¯äžèš â»ã¬ã¹ãã³ã¹ã³ãŒãã200ã ã£ãå Žå 503 çªå°ã«å€æŽãããããªãã®ãšãªã£ãŠãããŸãã function handler(event) { var response = event.response; var contentType = response.headers['content-type'].value; if (response && response.statusCode === 200) { response.statusCode = 503; response.statusDescription = 'test mode'; } return response; } çºè¡ã¿ãããçºè¡ãè¡ããŸãã 2. Cloud FrontçŽã¥ã äœæãã ãã£ã¹ããªãã¥ãŒã·ã§ã³ ã®ç»é¢ããããã€ãã¢ãç·šéããŸãã 颿°ã®é¢é£ä»ã ãäžèšã®ããã«èšå®ããŠãã ããã ãã¥ãŒã¯ãŒã¬ã¹ãã³ã¹: CloudFront function å
ã»ã©äœæãã颿° ãæå® 3.確èªäœæ¥ äžèšã®ã³ãã³ã宿œããŸãã curl -I https://ãã¡ã€ã³å/index.html çµæ(äžéšæç²) HTTP/1.1 503 test mode Content-Type: text/html Content-Length: 143 Connection: keep-alive ãããã« S3ãéçããŒãžã§æ¡çšãããããšã¯çµæ§ããããšæããŸãã ãã¡ã€ã³ ã ã¬ã¹ãã³ã¹å
容ã®å¶çŽã«ãããå©çšãããããšãæå¿µããã±ãŒã¹ããããããããŸããã CloudFront functionã¯éåžžã«äŸ¿å©ã§è²ã
ãªããšãã§ããŸãã®ã§ããããããã°æã£ãŠã¿ãŠãããããããããããŸããã æ¬¡ã¯ã眲åä»ã URL ãšçœ²åä»ã Cookie ããããè§ŠããããšæããŸãã æåŸãŸã§èªãã§ããã ãããããšãããããŸããã çããŸã®åèã«ãªãã°å¹žãã§ãã
ããã«ã¡ã¯ïŒããã³ããšã³ããéçºèª²æå±ã® koki _matsuraã§ãïŒ ä»åã¯ãã®ããã仿޿ãåŠããªãã®ã§ãããReactã®v18ã§çºè¡šããããSuspenseããšVercel瀟ãæäŸããŠããReact Hooksã©ã€ãã©ãªã®ãSWRãã«ãã£ãŠäœã解決ããŠãããã®ãã ã³ã³ããŒãã³ã ã®è¡šç€ºãšå®è£
ãäŸã«ç޹ä»ããŸãã ç®æ¬¡ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã Suspenseãšã¯ SWRãšã¯ Suspenseã»SWRã解決ããããš Suspenseã»SWRå°å
¥ã«ãããã³ã³ããŒãã³ã衚瀺ã®å€å Suspense ãªããSWR ãªã Suspense ãããSWR ãªã Suspense ãããSWR ãã Suspenseã»SWRå°å
¥ã«ãããã³ã³ããŒãã³ãå®è£
ã®éã Suspense ãªããSWR ãªã Suspense ãªããSWR ãã Suspense ãããSWR ãã ãŸãšã çµããã« Suspenseãšã¯ React16.6ã§å®éšçãªæ©èœãšããŠè¿œå ãããReact18ã§æ£åŒã«è¿œå ãããæ©èœã§ãã ã³ã³ããŒãã³ã ã®ããŒãã£ã³ã°ç¶æ
ããã³ããªã³ã°ãããããšã圹å²ãšãªã£ãŠããŸãã åºæ¬çã«ããã ããªã®ã§ãããããã«ãã ã³ã³ããŒãã³ã åäœã§ã®ããŒããå¯èœã«ããŸãã SWRãšã¯ ããŒã¿ååŸã®ããã®ã©ã€ãã©ãªã§ãã ååã®ç±æ¥ã¯HTTPãã£ãã·ã¥ç¡å¹åæŠç¥ã®"stable-while-revalidate"ã§ãã ãã¡ãããã£ãŠããããšã¯ã·ã³ãã«ã§ç¹å®ã®ããŒã¿ããã£ãã·ã¥ããããäžåºŠãå¿
èŠã«ãªã£ãéã«ãã£ãã·ã¥ããããŒã¿ãè¿ããŸãããŸãã宿çã«è£åŽã§ãã§ãããããææ°ã®ããŒã¿ã«æŽæ°ããŠãããŸãã Suspenseã»SWRã解決ããããš çµè«ãããããŸãã Suspenseã¯ä»¥äžã®ããšã解決ããŸãã ããŒã¿ååŸã®ããŒãã£ã³ã°ç¶æ
ã宣èšçã«ãã ã³ã³ããŒãã³ã åäœã§ã®ããŒããå¯èœã«ãã ã³ã³ããŒãã³ã ã®è²¬åãæç¢ºã«ãã SWRã¯ä»¥äžã®ããšã解決ããŸãã ãã£ãã·ã¥ã«ãããæŽæ°æã®é·æã®ããŒãã£ã³ã°ããªããªã API éä¿¡ãç°¡ç¥åããã ãã§ããããããŒã¿ã®ç®¡çãããªããŠãããªã ããSuspenseã¯ãããŒãã£ã³ã°ç¶æ
ããã³ããªã³ã°ãããã®ãã®ããã«æã£ãŠããŸã£ãŠããæ¹ãããŸãããã¡ããééã£ãŠã¯ããŸããããããã ãã§ã¯ãªããšããããšã§ãã ããããSuspenseã®ãããšããã¯ã ã³ã³ããŒãã³ã ã®è²¬åãæç¢ºã«ãããéšåã§ãããããæ¬è³ªã ãšæã£ãŠããŸãã SWRã¯ãã£ãã·ã¥ã®ç®¡çãéåæåŠçç¶æ
ã®ç®¡çãããŠããããããããŒã¿ã®ããŒããåŸ
ã€å¿
èŠããªãã£ãããããŒã¿ã®ååŸãéåžžã«ã·ã³ãã«ã«ããŠãããŸãã ãããã㯠ã³ã³ããŒãã³ã ã®è¡šç€ºãšå®è£
ãäŸã«ãå®éã«SuspenseãšSWRã解決ããŠããããšã玹ä»ããŠãããŸãã Suspenseã»SWRå°å
¥ã«ããã ã³ã³ããŒãã³ã 衚瀺ã®å€å 衚瀺ã«ãããŠSuspenseãšSWRãåãå
¥ããããšã§ã©ã®ãããªå€åãããã®ãã玹ä»ããŸãããŸããæŽæ°æã«ãããŠã®éããèŠãŠãããŸãã äžèšã®ãã¿ãŒã³ã§å€åãèŠãŠãããŸãã Suspense ãªããSWR ãªã Suspense ãããSWR ãªã Suspense ãããSWR ãã äžå³ã®ããã«ããŒãžã«3ã€ã® ã³ã³ããŒãã³ã ã衚瀺ããäŸã§æ¯èŒããŸããããããã® ã³ã³ããŒãã³ã ã¯äžãã1ç§éã2ç§éã3ç§éããããã§ããåŠçãè¡ã£ãŠããããã衚瀺ããã«ã1ç§éã2ç§éã3ç§é以äžããããŸãã Suspense ãªããSWR ãªã ãŸãã¯SuspenseãSWRã䜿ã£ãŠããªãäŸã§ããåæè¡šç€ºæãšæŽæ°æã®åç»ãèŒããŠããŸãã ã»åæè¡šç€ºæ ã»æŽæ°æ åæè¡šç€ºæã¯ãSuspenseãå©çšããªãããšãããã¿ã³ãæŒãããšãã«è©²åœã®ããŒãžããªã¯ ãšã¹ ãããŸãããããã3ç§éçµéããã®ã¡ã3ã€ã® ã³ã³ããŒãã³ã ãæã£ãç¶æ
ã§ç»é¢ã衚瀺ãããŠããŸãã æŽæ°æã3ç§åŸã«ãâ¯ç§åŸã«è¡šç€ºããã ã³ã³ããŒãã³ã _ãã®åŸãã«ã€ããŠããæååãäžæ°ã«å€æŽãããŠããããšãããããŸãã ããã¯ãµãŒããå®å
šã«HTMLãæ§ç¯ããŠããã¯ã©ã€ã¢ã³ãã«è¿ããŠããããšã衚ããŠããŸãã å³ã§è¡šããšä»¥äžã®ããã«ãªããŸãã ããŒãžããªã¯ ãšã¹ ã API ãµãŒããžãªã¯ ãšã¹ ãïŒ3ã€ïŒ 1,2,3ç§åŸã«ã¬ã¹ãã³ã¹ãWEBãµãŒããžè¿åŽ WEBãµãŒãã¯å
šãŠæã£ãŠããHTMLãæ§ç¯ ã¯ã©ã€ã¢ã³ããžHTMLãè¿åŽ HTMLãæç»ããJSãããŒããHTMLã«ãã€ãã¬ãŒã·ã§ã³ãå®è¡ å°ãéã«ç޹ä»ããŠããŸããã倧ãŸããªæµãã衚ããŠãããšæããŸããåæè¡šç€ºãæŽæ°æã«æ¯å3ç§åŸ
ããããã®ã¯åé¡ã§ãããŸããJSã®ããŒãããã€ãã¬ãŒã·ã§ã³ã®ããšãèãããšæäœã§ããããã«ãªãã«ã¯3ç§ãããããããšèããããŸãã ããã«Suspenseãå°å
¥ããããŒãžã®ããŒãåäœã ã³ã³ããŒãã³ã åäœã«ããããšã§å€§ããªåŸ
ã¡æéã解決ããŠãããŸãã Suspense ãããSWR ãªã Suspenseãå°å
¥ãããšä»¥äžã®ããã«å€åããŸãã ã»åæè¡šç€ºæ ã»æŽæ°æ åæè¡šç€ºæã¯ãSWRãªãããšãããã¿ã³ãæŒããšããŒãžããªã¯ ãšã¹ ããããããã«ããŒãžãé·ç§»ããŠããŸãããããŠã1,2,3ç§åŸã«ããããã® ã³ã³ããŒãã³ã ãé ã«è¡šç€ºãããŠããããšã確èªã§ããŸããååŸäžã¯ä»£ããã® ã³ã³ããŒãã³ã ïŒä»åã¯ããŒãã£ã³ã° ã³ã³ããŒãã³ã ïŒã衚瀺ãããŸãã æŽæ°æãåæ§ã«ãå
šäœãååŸäžã«ãªãã1,2,3ç§ã§ ã³ã³ããŒãã³ã ã衚瀺ãããŠãããŸãã WEBãµãŒãã¯HTMLãæªå®æã®ç¶æ
ã§ãè¿ããŠãããããšãããããšæããŸãã å³ã§è¡šããšä»¥äžã®ããã«ãªããŸããå°ãèŠã«ãããªã£ãŠããŸãããã¿ãŸããã ããŒãžããªã¯ ãšã¹ ã API ãµãŒããžãªã¯ ãšã¹ ãïŒ3ã€ïŒ ã¬ã¹ãã³ã¹ããããªãéšåã ãã®HTMLãæ§ç¯ ã¯ã©ã€ã¢ã³ããžïŒã§äœæããHTM Lãè¿åŽ HTMLãæç»ãJSãããŒãããã€ãã¬ãŒã·ã§ã³ãååŸäžã®éšåã¯ä»£ããã® ã³ã³ããŒãã³ã ã衚瀺 ã1ç§åŸã® ã³ã³ããŒãã³ã ãã®ã¬ã¹ãã³ã¹ãWEBãµãŒããž ã1ç§åŸã® ã³ã³ããŒãã³ã ãã®HTMLãæ§ç¯ ã1ç§åŸã® ã³ã³ããŒãã³ã ããè¿åŽ ã1ç§åŸã® ã³ã³ããŒãã³ã ãã衚瀺ãããã®éšåã®JSãããŒãããã€ãã¬ãŒã·ã§ã³ 以äžç¥... 10ã16ã¯6ã9ãšåãæµãã«ãªãã®ã§çç¥ããŸããã Suspenseã䜿ãããšã§ ã³ã³ããŒãã³ã åäœã§ã®ããŒã(JSã®ããŒãã»ãã€ãã¬ãŒã·ã§ã³)ãå¯èœã«ããããšã«ãããåæè¡šç€ºã®å€§ããªåŸ
ã¡æéã解決 ããŠãããŠããŸãã ããããªãããæŽæ°ãããã³ã«å®å
šã«è¡šç€ºãçŽãã®ã«çµå±3ç§ä»¥äžãããã®ã¯åé¡ã§ãã ãããSWRã®ãã£ãã·ã¥ç®¡çã«ãã解決ããŸãã Suspense ãããSWR ãã SWRãå°å
¥ãããšã以äžã®ããã«ãªããŸãã â» SWRãå°å
¥ãããšã SSR ã¯ã§ããŸããã CSR ã«ãªããŸãã ã»åæè¡šç€ºæ ã»æŽæ°æ åæè¡šç€ºã¯Suspenseã®ã¿ãå°å
¥ããæãšèŠãç®ã¯å€ãããŸããã èŠãç®ã¯å€ãããªãã®ã§ããè£åŽã§ã¯ãã§ãããšå
±ã«ããŒã¿ããã£ãã·ã¥ããŠãããæŽæ°æã«ã¯ãã®ãã£ãã·ã¥ãè¿ãããšã§ããã«è¡šç€ºããããšãã§ããŠããŸããã€ãŸããSWRã«ãã æŽæ°æã®é·æã®ããŒãã£ã³ã°ã解決 ãããŠããããšãããããŸãã ãŸããè£ã§åãã§ããããŠãããŠããã®ã§ææ°æ
å ±ãååŸã§ããã°ããã« ã³ã³ããŒãã³ã ãæŽæ°ãããŠããããšãæååã倿ŽãããŠããããšã§ç¢ºèªã§ããŸãã ã³ã³ããŒãã³ã ã®è¡šç€ºã§æ¯èŒããããšã§Suspenseã® ã³ã³ããŒãã³ã åäœã®ããŒãã«ãã衚瀺é床ã®è§£æ±º ãšSWRã® ãã£ãã·ã¥ç®¡çã«ããæŽæ°æã®è¡šç€ºé床ã®è§£æ±º ãå®éã«èŠãŠãçè§£ã§ãããšæããŸãã æ¬¡ã¯ãã³ãŒãåŽããèŠãŠSuspenseãšSWRã解決ããŠãããããšã玹ä»ããŸãã Suspenseã»SWRå°å
¥ã«ããã ã³ã³ããŒãã³ã å®è£
ã®éã ãã¡ããäžèšã®3ãã¿ãŒã³ã§å€åãèŠãŠãããŸããå
ã»ã©ãšã¯éã£ãŠãSWRã ããå°å
¥ããå Žåãšããã«Suspenseãå°å
¥ããå Žåã§ç޹ä»ãããŠããã ããŸãã Suspense ãªããSWR ãªã Suspense ãªããSWR ãã Suspense ãããSWR ãã ãŠãŒã¶æ
å ±ã衚瀺ãã ã³ã³ããŒãã³ã ãäŸã«ããŸãã Suspense ãªããSWR ãªã äžèšã¯Suspenseã»SWRãå
±ã«äœ¿ã£ãŠããªãUser ã³ã³ããŒãã³ã ã§ããŠãŒã¶æ
å ±ã衚瀺ããããã ãã®ã·ã³ãã«ãª ã³ã³ããŒãã³ã ã§ãã const User = () => { const [ user , setUser ] = useState < User >( null ); useEffect (() => { fetchUser () .then (( res ) => setUser ( res )); } , [] ); if ( user === null ) return < Loading / >; return < Contents user = { user } / >; } ; ããŒã¿ãnullã®éãã€ãŸãååŸäžã®éã¯ããŒãã£ã³ã°ã衚瀺ãnullãããªããã°ããŠãŒã¶æ
å ±ã衚瀺ããããã«ãªã£ãŠããŸãããã®ãŠãŒã¶æ
å ±ã¯useEffectå
ã®fetchUser()ã§ååŸãããstateã«ãã管çãããŠããŸãã ãŸããåé¡ãšããŠæããããã®ã¯ãuseEffectå
ã§ãã§ãããããŠããç¹ã§ããæ¬æ¥ãuseEffectã¯å¯äœçšåŠçãæžãããã®ãã®ã§ãã£ãŠãåªçæ§ã®ãªãåŠçãæžããªãæ¹ãæãŸããã§ãã ãŸããUser ã³ã³ããŒãã³ã ã®äžã§LoadingãšContent ã³ã³ããŒãã³ã ãåºãåããè¡ãããŠããç¹ãåé¡ã§ããä»åã¯äŸã«æããªãã£ãã®ã§ããããã§ããã®ãšã©ãŒåŠçãããããšããããŸãããããªããšãError ã³ã³ããŒãã³ã ãåºãåãã«å ããããšã«ãªããŸãã æ¬æ¥ã¯ãŠãŒã¶æ
å ±ã衚瀺ããããšã®ã¿ãä»äºã®User ã³ã³ããŒãã³ã ãããŒãã£ã³ã°ããšã©ãŒããŠãŒã¶æ
å ±ã衚瀺ãã ã³ã³ããŒãã³ã ã«ãªã£ãŠããŸããŸãã ãããã®åé¡ãSWRãå°å
¥ããæãã©ã®ããã«å€ãããèŠãŠãããŸãããã Suspense ãªããSWR ãã å
ã»ã©ã® ã³ã³ããŒãã³ã 衚瀺ã§ã¯SWRã«ãã£ãŠãã£ãã·ã¥ãåãããšã確èªã§ãããšæããŸãã ã³ãŒãã¯ä»¥äžã®ããã«ãªããŸãã const User = ()=> { const { data: user , isLoading } = useSWR ( "user" , fetchUser ); if ( isLoading ) return < Loading / >; return user && < Contents user = { user } / >; state管çã»useEffectããªããªãããã®ä»£ããã«useSWRããã¯ã䜿ã£ãŠããŸãã useSWR㯠API éä¿¡ãç°¡çŽ åããŠãããããã æ¬æ¥æžãã¹ãã§ã¯ãªãuseEffectå
ã§ã®ãã§ããåŠçããã§ããåŸã®ããŒã¿ç®¡çããã£ãã·ã¥ã®ç®¡çã®åé¡ã解決 ããããšãã§ããŸãã ä»åã¯æžããŠããŸããããuseSWRã¯ãšã©ãŒã«ã察å¿ããŠããŸãã SWRã ãã§ãéåžžã«ã·ã³ãã«ã«ãªããŸãããããŸã User ã³ã³ããŒãã³ã ã¯ããŒãã£ã³ã°ãšãŠãŒã¶ã®åºãåããšããè€æ°ã®è²¬åãæã£ãŠããŸã£ãŠããŸããããã«Suspenseãåãå
¥ããŠã¿ãŸãã Suspense ãããSWR ãã Suspenseãåãå
¥ããUser ã³ã³ããŒãã³ã ã¯ä»¥äžã®ããã«ãªããŸãã const User = ()=> { const { data: user } = useSWR ( "user" , fetchUser , { suspense: true , } ); return < Contents user = { user } / >; SWRã§Suspenseã䜿ãããæã¯useSWRã®ç¬¬äžåŒæ°ã§suspenseãªãã·ã§ã³ãã€ããã ãã§ãã 倿Žç¹ã¯ããŒãã£ã³ã°ã®åºãåãããªããªã£ãéšåã§ãã SuspenseãLoading ã³ã³ããŒãã³ã ãåºã責åãæ
ã£ãŠãããŸããããã£ãäžè¡æžã£ãã ãã§ãããããã§ ã³ã³ããŒãã³ã ã®è²¬åã®äžæç¢ºå ã解決ã§ããŸããã ã¡ãªã¿ã«ãSuspenseã䜿ããšãã¯è©²åœã® ã³ã³ããŒãã³ã ãSuspense ã³ã³ããŒãã³ã ã§å²ãã ãã§å®è£
ã§ããŸãã ä»åã®å Žåã¯ä»¥äžã®ããã«ãªããŸãã < Suspense fallback = { < Loading / > } > < User / > < /Suspense > fallbackã®äžã«ããŒãã£ã³ã°äžã«è¡šç€ºããã ã³ã³ããŒãã³ã ãå
¥ããã ãã§ãã ããŒãã£ã³ã°ç¶æ
ãåœä»€çãªãã®ãã宣èšçãªãã® ã«ãªã£ãŠããŸãã Suspenseã»SWRãåãå
¥ããããšã«ããåŸæ¥ã® ã³ã³ããŒãã³ã ã®åé¡ç¹ã解決ã§ããããšãçè§£ã§ãããšæããŸãã ãŸãšã ã³ã³ããŒãã³ã ã®è¡šç€ºã«ããéããšå®è£
ã®éããäŸã«Suspenseã»SWRãäœãããŠãããã®ãã説æããŠããŸããã ãŸãšãããšãSWRã¯ä»ãŸã§ ã³ã³ããŒãã³ã å
ã§è¡ã£ãŠããããŒã¿ã®ç®¡çããã§ããã®åŠçãuseSWRããã¯ã®ã¿ã§å®çµããããã£ãã·ã¥ãŸã§ãæè»ã«ç®¡çããŠãããã©ã€ãã©ãªã§ãã ãããŠãSuspenseã¯ããŒãã£ã³ã°ç¶æ
ã宣èšçã«ããŠãããããšã«ããã ã³ã³ããŒãã³ã èªäœãéåæåŠçãšããŠæ±ãã責åãæç¢ºã«ãããšãšãã«ã ã³ã³ããŒãã³ã åäœã®ããŒããå¯èœã«ããŠãããŸããã çµããã« ãããŸã§èªãã§ããã ããæ¬åœã«ããããšãããããŸãã ééã£ãŠããç¹ãªã©ãããã°ããã²ã³ã¡ã³ãã§ããããŠãã ããïŒ ãã®èšäºãSuspenseãSWRã«èå³ãæã€ãã£ããã«ãªã£ãŠãããã°å¹žãã§ãã
ã¯ããã« ããã«ã¡ã¯ã MasaKu ã§ãã åŒç€Ÿã§ã¯ã PHP ã«é¢ããææ°ãã¥ãŒã¹ã®çºä¿¡ãæ°ã«ãªããé¡ã«ã€ããŠè°è«ããã€ãã³ãã PHP TechCafeããæ¯æéå¬ããŠãããŸãã æ¬æ¥ã¯ã PHP TechCafe ãšã¯ã©ããªã€ãã³ããªã®ãã®ã説æãšãéå»éå¬ããã€ãã³ãã®äžã§ç¹ã«çãäžãã£ãã€ãã³ããã玹ä»ãããŠããã ããŸãã Web à PHP TechCafe ã¯ããã« PHP TechCafeã®ç®ç ç«ã¡äžãããã®çµç·¯ åå 察象è
ãšãã®çç± éå¶ã¡ã³ã㌠ããŒãéžå®æ¹é ã³ã³ãã³ãäœã ç¹ã«è©å€ã®è¯ãã£ãããŒã10éž PHPerã®ããã®ãPHPãšåå®çŸ©ãèªãåãã PHP TechCafe PHPerã®ããã®ãPHPã®ãªãŒããã«ãªã³ãŒãããèªãåãPHP TechCafe PHPerã®ããã®ãLaravel10ã®æ°æ©èœããèªãåã PHP TechCafe PHPerã®ããã®ãPHPDocçžè«äŒãPHP TechCafe PHPerã®ããã®ãPHP8.2ã®æ°æ©èœããèªãåãPHP TechCafe PHPerã®ããã®ãComposerããèªãåãPHP TechCafe PHPerã®ããã®ãPHPãã¬ãŒã ã¯ãŒã¯ããèªãåãPHP TechCafe PHPerã®ããã®ãéçè§£æããèªãåãPHP TechCafe PHPerã®ããã®ãXdebugã®æŽ»çšæ¹æ³ããèªãTechCafe PHPerã®ããã®ãPHPUnit ã®å§ãæ¹ãã«ã€ããŠèªããã PHP TechCafe ãããã« PHP TechCafeã®ç®ç PHP TechCafe ã¯æã«äžåºŠ ZOOM ã§éå¬ãããŠãããªã³ã©ã€ã³ã€ãã³ãã§ãã ãšã³ãžãã¢å士ã®äº€æµã®æ©äŒãæäŸããããšã³ãžãã¢ãšæè¡ã亀差ããæ©ãã®å ŽïŒã«ãã§ïŒã«ãªãããããªã€ãã³ããç®æããŠããŸãã PHP TechCafe ãšããã€ãã³ããã®ãã®ãåŠã³ã®å Žãšãªããéå¶ã¡ã³ããŒãå«ããåå è
å
šå¡ããšã³ãžãã¢ãšããŠã¬ãã«ã¢ããããŠãããããã«æ¯æŽããããšãç®çãšããŠéå¬ããŠãããŸãã ç«ã¡äžãããã®çµç·¯ ç«ã¡äžãåœæã¯ PHP ãããŒãã«ããå匷äŒã§ã¯ãªããåŒç€Ÿã®ã«ãã§ã¹ããŒã¹ãå©çšãã瀟å€åãã® ããããäŒ ã§ããã ããããäŒ ã§ç€Ÿå€ã®ãšã³ãžãã¢ãšäº€æµãæ·±ããŠããäžã§ãæè¡çãªããŒãã§äº€æµã§ããããšã®æ¥œããã«æ°ã¥ããŸããã ãã£ãšæè¡çãªããŒãã§èªãåãæ¹æ³ã¯ãªãããšæ€èšãããšãããèªåãã¡ã®åŒ·ã¿ã§ãã PHP ã軞ã«ããã€ãã³ãã«ããŠã¿ãŠã¯ã©ãããšããæ¹åæ§ã«è³ããä»¥æ¥æš¡çŽ¢ãéããŠããŸãã æå㯠PHP ã®ãã¥ãŒã¹ã玹ä»ããã ãã®ã€ãã³ãã§ããããã€ãã³ãã«åå ããŠãã ãã£ãåå è
ã«ãã£ãšäŸ¡å€ãæäŸã§ããªãããšèããç¹éã³ãŒããŒãèšãããªã©ããŠçŸåšã®åœ¢ã«é²åããŠããŸããã åå 察象è
ãšãã®çç± PHP TechCafe ã®åå 察象è
PHP TechCafe ã®åå 察象è
㯠PHP å
¥éåŸã®åçŽãšã³ãžãã¢ ïœ ã·ãã¢ãšã³ãžã㢠ãšããŠããŸãã çç±ãšããŸããŠã¯ã PHP TechCafe ãéå¶ããŠããã¡ã³ããŒã®ã¬ãã«æãåŒç€Ÿã® PHP ãšã³ãžãã¢ã®æè¡é åããã®èŸºãã«äœçœ®ããŠãããããã€ãã³ããéããŠåå è
ãšäžç·ã«æé·ããŠãããããšèããŠããããã§ãã PHP TechCafe ã®ã€ãã³ãã«ã¯ãšãã¹ããŒã以äžã®ãšã³ãžãã¢ãåå ããŠãã ããããšããããŸãã ãããã£ãéã«ã¯ç©æ¥µçã«è³ªåãããªã©ããŠéå¶ã¡ã³ããŒã®ã¬ãã«ã¢ããã«ãã€ãªããŠãããããšèããŠããŸãã éå¶ã¡ã³ã㌠éå¶ã¡ã³ããŒã¯å®éã«ã€ãã³ãã«åå ããã¡ã€ã³ã¡ã³ããŒãšã€ãã³ãã®ã³ã³ãã³ãäœæã«ååããŠããã ããµããŒãã¡ã³ããŒã§æ§æãããŠããŸãã çŸåšä»¥äžã®ã¡ã³ããŒæ§æã§å®æœããŠããŸãã ã¡ã€ã³ã¡ã³ã㌠Y-Kanoh , MasaKu ãµããŒãã¡ã³ã㌠8å åŒç€Ÿã® PHP ç³»ãããã¯ãããå2åãã€åå ããŠããŸã äžèšã®ãã¡ã€ãã³ããµããŒã¿ãŒã¯2çã«åããŠéæã§åå ããŠããã£ãŠããŸãã ãã®ãããæ®æ®µã®ã€ãã³ãã¯ã¡ã€ã³ã¡ã³ããŒ2åãšã€ãã³ããµããŒã¿ãŒ4åã®åèš6åã§äœæ¥ãããŠããŸãã ããŒãéžå®æ¹é åºæ¬çã«ã¯éå¶ã¡ã³ããŒãåŠãã§ã¿ãã PHP é¢é£ã®æè¡ãããŒãã«ããŠããŸãã çŽè¿ã®æ¥åã§æ±ã£ãŠããéšåããæ¥åã«åãå
¥ããŠã¿ããæè¡ãªã©ãããŒãã«äžããããšããããŸãã ä»ã®ãã¿ãŒã³ãšããŠã¯ã以äžã®ãããªãã®ããããŸãã æ°ããããŒãžã§ã³ã® PHP ã ãã¬ãŒã ã¯ãŒã¯ ãå
¬éãããã¿ã€ãã³ã° æ°æ©èœã®çŽ¹ä» åçš® PHP é¢é£ã€ãã³ãïŒ PHPã«ã³ãã¡ã¬ã³ã¹ çïŒãéå¬ãããã¿ã€ãã³ã° ãµããããäŒãªã©ãéå¬ â»ã€ãã³ãã®ãµããããäŒã宿œããéã¯äºåã«ã€ãã³ãã®éå¶å
ã«èš±å¯ãããã ããŠå®æœããŠãããŸã åå è
ãå€ãéãŸã£ããã SNS ãZOOMã®ãã£ããã§çãäžãã£ãäŒã«ã€ããŠã¯ãã€ãã³ãã®ãã©ãã·ã¥ã¢ãããè¡ããªã©ããŠç¹°ãè¿ã宿œããããšããããŸãã ããŒããæ±ºãŸã£ãããã€ãã³ãåœæ¥ã¯ã©ã®ãããªæµãã§è©±ãããã°çãäžãããããããšããããšãèããªãã ã¢ãžã§ã³ã ãäœæããããã«ããŠããŸãã ã³ã³ãã³ãäœã éžå®ããããŒããå
ã«ãµããŒãã¡ã³ããŒãšå
±ã«ã€ãã³ãåœæ¥ã«å
¬éãã ShowNote ãäœæããŸãã æ
åœç¯å²ã¯ããŒãéžå®ã®æã«äœæãã ã¢ãžã§ã³ã ãå
ã«åæ
ããŠããŸãã åã
ã調ã¹ãŠããå
容ãã€ãã³ãåœæ¥ãŸã§ã«æã¡å¯ã£ãŠæ
å ±å
±æãè¡ããã¡ã€ã³ã¡ã³ããŒããã£ãããšã€ã³ãããããŠåœæ¥ã®ã€ãã³ãã«åããããšããæµãã§æºåãããŠããŸãã ç¹ã«è©å€ã®è¯ãã£ãããŒã10éž ä»¥äžã§ã¯ãç¹ã«è©å€ã®è¯ãã£ãåãããã¯ã¢ãããããŠããã ããŸããã®ã§ãã玹ä»ããããŸãã PHPerã®ããã®ãPHPãšåå®çŸ©ãèªãåãã PHP TechCafe rakus.connpass.com æŠèŠ åçåä»ãèšèªã§ãã PHP ã¯ãæè»œã«ã³ãŒããèšè¿°ã§ããåé¢ã ä¿å®æ§ã®æ
ä¿ããŸãã¯æå³ããªãæåãé²ããããåžžã«åãæèããŠã³ãŒãã£ã³ã°ãè¡ãå¿
èŠããããŸãã ããããæè»œã«æžããåé¢ã PHP ãå§ããã°ããã®äººã®äžã«ã¯ãããŸãåãæèããèšèŒããŠãã人ãããã®ã§ã¯ãªãã§ããããïŒ ãããªæ¹ã®ããã«åãšã®ä»ãåãæ¹ãèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io PHPerã®ããã®ãPHPã®ãªãŒããã«ãªã³ãŒãããèªãåãPHP TechCafe rakus.connpass.com æŠèŠ PHP ã§èªã¿ãããã³ãŒããšã¯ã©ã®ãããªã³ãŒãã§ãããïŒ åãåŠçã§ãæžãæ¹ã«ãã£ãŠå¯èªæ§ãã²ããŠã¯ä¿å®æ§ã¯å€§ããå€ãããŸãã ãã®ããŒPHPerã«äŒããããå¯èªæ§ã®é«ãã³ãŒããã«ã€ããŠèªããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãLaravel10ã®æ°æ©èœããèªãåã PHP TechCafe rakus.connpass.com æŠèŠ Laravel ã®åçãªãªãŒã¹ãã 11幎ç®ã« Laravel10 ããªãªãŒã¹äºå®ãããŸããã Laravel ã®åºç€çãªå
容ããããããã€ã€ãLaravel10 ã®æ°æ©èœã«ã€ããŠåãäžããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãPHPDocçžè«äŒãPHP TechCafe rakus.connpass.com æŠèŠ PHPDocã¯æ°ãå€ããããŒã«ã«ãã£ãŠå¯Ÿå¿æç¡ãç°ãªããŸãã ãããªPHPDocã«ã€ããŠãã€ãã³ãéå¶ã¡ã³ããçåã«æã£ãããšãäžå¿ã«è°è«ããŸããïŒ PHP ã§åå®çŸ©ãããŠããå ŽåãPHPDocã§ãåãæžããæ¹ããããïŒ PhpStormææ°çã¯é
åã®åã 飿³é
å ã®key, value ã®åãæ€ç¥ããŠãããïŒ ã¬ã¬ã·ãŒã·ã¹ãã ãšPHPDocã®åãåãæ¹ ãªã© ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãPHP8.2ã®æ°æ©èœããèªãåãPHP TechCafe rakus.connpass.com æŠèŠ PHP8.2 ã¯å®çšçãªæ©èœããç Žå£çãªæ©èœãŸã§ãæ§ã
ãªæ©èœã远å ãããŸããã PHP8.2 ã§å®è£
ãããæ©èœãã©ã®ãããªãã®ãªã®ããã©ããã£ãçšéãããã®ãã«ã€ããŠèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãComposerããèªãåãPHP TechCafe rakus.connpass.com æŠèŠ PHP ã®äŸåæ§ç®¡çããŒã«ã§ãã "Composer" ã«ã€ããŠæ·±æãããŸããã äœã«äœ¿ããã®ãªã®ããã©ã®ããã«äœ¿ãã®ããPackagist ãšã¯äœãªã®ã çã«ã€ããŠèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãPHPãã¬ãŒã ã¯ãŒã¯ããèªãåãPHP TechCafe rakus.connpass.com æŠèŠ Laravelã Symfony ãCakeãSlim ãªã©ã PHP ã® ãã¬ãŒã ã¯ãŒã¯ ã«ã€ããŠæåã©ããããªã¹ãã¢ããããŸããã äž»å¬è
äžåãè§Šã£ãããšããªã ãã¬ãŒã ã¯ãŒã¯ ã倿°ååšããäžãéå¬ãŸã§ã«ãã£ãããšèª¿æ»ããŠèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãéçè§£æããèªãåãPHP TechCafe rakus.connpass.com æŠèŠ éçè§£æãšã¯ãã³ãŒããå®è¡ããããšãªãè¡ãã³ãŒãæ€èšŒã®ããšã§ãã PHP ã«ã PHP _CodeSniffer ã PHPStan ãªã©ã®éçè§£æããŒã«ãååšããŸãã PHP ã§ãªãéçè§£æãå¿
èŠãªã®ãããåéçè§£æããŒã«ã®ç¹åŸŽã«ã€ããŠãæ·±å ããŠèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãXdebugã®æŽ»çšæ¹æ³ããèªãTechCafe rakus.connpass.com æŠèŠ Xdebug 㯠PHPer ã«ãã ãããã° ã®ãäŸã§ããããã䜿ããã "ã¹ãããå®è¡" ã ãã§ãªããããŸããŸãªæ©èœãæäŸããæ¡åŒµããŒã«ã§ãã å®ã¯ã Xdebug 㯠"ã¹ãããå®è¡" ã ãã§ãªããæ§ã
ãªæ©èœãæããŠããŸãã®ã§ã䟿å©ãªäœ¿ãæ¹ã«ã€ããŠèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp PHPerã®ããã®ãPHPUnit ã®å§ãæ¹ãã«ã€ããŠèªããã PHP TechCafe rakus.connpass.com æŠèŠ PHPUnit ã«èå³ã¯ãããã©äœããå§ããã°ããã®ïŒ åŠã¶åã«å
šäœåãææ¡ãããïŒãšãã£ãæ¹ã察象ã«ã PHPUnit ã®åºæ¬çãªç¥èãªã©ã顿ã«ããŸããã PHP åå¿è
ã®æ¹ã ãã§ãªããããã©ã³ãšã³ãžãã¢ã®æ¹ãåŠã³çŽãã»æ°ã¥ãã®çºæãªã©ã®æ©äŒã«ãªãã°ãšæãèªãåããŸããïŒ ShowNoteã¯ãã¡ãïŒ hackmd.io ãŸãšãèšäºã¯ãã¡ãïŒ tech-blog.rakus.co.jp ãããã« PHP TechCafe ã¯çŸåšã®ãªã³ã©ã€ã³åœ¢åŒã«ãªã£ãŠãã çŽ3幎 ã€ãã³ããç¶ç¶ããŠããŸãã ã€ãã³ãéå¶ã®èŠåŽããããŸããã PHP é¢é£ã®ããŒãã§ç€Ÿå€ã®ãšã³ãžãã¢ãšäº€æµã§ããããšã¯è²Žéãªçµéšã«ãªã£ãŠããŸãã ããããã PHP TechCafe ãã©ãããããããé¡ãããããŸãã æ¬¡åã® PHP TechCafe 㯠9æ26æ¥ ã«éå¬ããŸãã ãåå ãåŸ
ã¡ããŠãããŸãã rakus.connpass.com
ã¯ããã« ããã«ã¡ã¯ akihiyo76 ã§ããçŸåšãç§ã®ããŒã ã§ã¯ã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ãææåããŠãã¬ãã¥ã¢ãŒã¯ ã¬ã€ãã©ã€ã³ ã«åŸã£ãŠã³ãŒãã¬ãã¥ãŒãè¡ãªã£ãŠããŸãããã® ã¬ã€ãã©ã€ã³ ã¯ãããŒã ã§éçšãéå§ããŠïŒå¹Žã«ãªããŸãããããŒã ã§ã浞éãã¬ãã¥ãŒæã«å¿
ãå©çšããããã«ãªããŸããã ã¯ããã« ã³ãŒãã¬ãã¥ãŒã®èª²é¡æ èª²é¡æ¹åã«åã㊠æ¡çšããã³ãŒãã¬ãã¥ãŒèŠ³ç¹ 1. DesignïŒèšèšïŒ å®çŸ© å
·äœäŸ 2. SimplicityïŒçè§£å®¹ææ§ïŒ å®çŸ© å
·äœäŸ 3. NamingïŒåœåïŒ å®çŸ© å
·äœäŸ 4. StyleïŒã³ãŒãã¹ã¿ã€ã«ïŒ å®çŸ© å
·äœäŸ 5. FunctionalityïŒæ©èœèŠæ±ïŒ å®çŸ© å
·äœäŸ 6. TestïŒãã¹ãïŒ å®çŸ© å
·äœäŸ 7. DocumentïŒæç« ïŒ å®çŸ© å
·äœäŸ ææå¯Ÿå¿ã®èŠåŠ å
·äœçãªå©ç𿹿³ ææäŸ æåŸã« ã³ãŒãã¬ãã¥ãŒã®èª²é¡æ ç§ã¯çŸåšã¢ãã€ã«éçºããŒã ã«æå±ããŠãããŸãããã¡ã³ããŒã¯è¥æãšã³ãžãã¢ãäžå¿ã§ããäžæ¹ãåŒç€Ÿã®ãµãŒãã¹ã¯ SaaS ãäžå¿ã§ããããããããŸã§ã¢ãã€ã«éçºã®çµéšè
ãå°ãªãç¶æ³ã§ããããã®ãããã¢ãã€ã«æè¡ã®ã»ãªãªãŒãåãããªãããšãã課é¡ãããŒã ã«ãããã³ãŒãã¬ãã¥ãŒã«èŠåŽããç¶æ³ã§ããã ãã®çµæãšããŠã ã¡ã³ããŒã®æè¡åã®äŒžã³æ©ã¿ ãªãªãŒã¹åŸã«äžå®æ°ã®ãã°ãçºçãã ãšãã£ãç¶æ³ã§ããã èª²é¡æ¹åã«åã㊠ããã§ããã®èª²é¡æ¹åã«åãçµãããšã«ããŸãããã ã¬ãã¥ãŒææãé¡ååããŠãã¡ã³ããŒã®æè¡åãå®éåã§ããªãã ãšèããŸããããã®ææ®µãšããŠãã³ãŒãã¬ãã¥ãŒã«å¯Ÿãã ã¬ã€ãã©ã€ã³ ãäœæããŠãã¬ãã¥ãŒã³ã¡ã³ããé¡ååã» å®é åããããšã«ããŸããã äžå®ã®èгç¹ãæã£ãŠã¬ãã¥ãŒã³ã¡ã³ããé¡ååããããšã§ãKPIãšããŠèšæž¬ãå¯èœïŒ èŠããå ïŒã«ãªãã匱ç¹åæãããããšãã§ããããã§ãã ã¬ã€ãã©ã€ã³ ãäœæããäžã§ã Google ãå
¬éããã¬ãã¥ãŒã¬ã€ãã©ã€ã³ ãåèã«ããŠä»¥äžã®ïŒã€ã®ã¬ãã¥ãŒèгç¹ãèšããããšã«ããŸããã æ¡çšããã³ãŒãã¬ãã¥ãŒèŠ³ç¹ ã§ã¯ãå®éã«ã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ã§æ¡çšãã芳ç¹ã玹ä»ããŸãã No èŠ³ç¹ æŠèŠ 1 Design èšèšãé©åã 2 Simplicity çè§£å®¹ææ§ 3 Naming ã¯ã©ã¹ãã¡ãœããã倿°åãªã©ã® åœå 4 Style ã³ãŒãã¹ã¿ã€ã« 5 Functionality æ©èœïŒèŠä»¶ïŒãå
è¶³ããŠããã 6 Test ãã¹ãã®èšè¿°ããã¿ãŒã³ãé©å 7 Document ã³ã¡ã³ããããã¥ã¡ã³ãã«é¢é£ ç¹ã«No.1 ~ No.4ã¯ã ãªããžã§ã¯ãæå ã®èгç¹ã§éåžžã«éèŠãªèгç¹ãšãããŸãããããããããã®èгç¹ãšæŠèŠã ãã§ã¯å€æãé£ãå Žé¢ãããããšæãã®ã§ãããå°ãå
·äœçã«ã³ãŒãããŒã¹ã§èª¬æããŸãã 1. DesignïŒèšèšïŒ å®çŸ© ã·ã¹ãã ã«ãšã£ãŠé©åãªè²¬åã»æ¯ãèãã«ãªã£ãŠããããã·ã¹ãã ãšã㊠ã¢ãŒããã¯ã㣠ãéµå®ã§ããŠãããããŸããã·ã¹ãã å
šäœãšã㊠äžè²«æ§ããèšèšã«ãªã£ãŠãããã å
·äœäŸ åºæ¬çã«ã¯ã以äžã®ãã㪠ãªããžã§ã¯ãæå ã®åºæ¬ã§ãã SOLID ååã«åãããããªå Žåãææã®å¯Ÿè±¡ã«ãªããŸãã é¢å¿ã®åé¢ååéåïŒâ åäžè²¬ä»»ååéåïŒ å¯çµå äœåé DRY ååéå etc. äŸãã°ã以äžã®ã³ãŒãã®å Žå add() ã§æ§ã
åŠçãè¡ãªã£ãŠããã責åè¶
éãšããããã Design ææã®å¯Ÿè±¡ã«ãªããŸãã class HogeDiscountManager { lateinit var manager: DiscountManager /** * ååã远å ãã */ fun add(product: Product): Boolean { if (product.id < 0 ) { // ããªããŒã·ã§ã³ 1 throw IllegalArgumentException () } if (product.name.isEmpty()) { // ããªããŒã·ã§ã³ 2 throw IllegalArgumentException () } val temp: Int = if (product.canDiscount) { // æ¡ä»¶åå² 1 manager.totalPrice + manager.getDiscountPrice(product.price) } else { manager.totalPrice + product.price } return if (temp < 3000 ) { // æ¡ä»¶åå² 2 manager.totalPrice = temp manager.discountProducts.add(product) true } else { false } } } 2. SimplicityïŒçè§£å®¹ææ§ïŒ å®çŸ© ã·ã¹ãã ãšããŠå¯èªæ§ããã³ãŒãã£ã³ã°ã«ãªã£ãŠãããã åŠçãã§ããã ãã·ã³ãã«ãªæ¯ãèãã«ãªã£ãŠãããã å
·äœäŸ 以äžã®ããã«å®è£
ãè€éã«ãªãå Žåãææã®å¯Ÿè±¡ã«ãªããŸãã ãã¹ããæ·±ã if å è€é㪠äžé
æŒç®å æ åé·ãª SQL stream, filter, map ãå€çšããObjectæŽåœ¢æ etc. ãã®ããã«åå²ãå€ã if åã¯ãSimplicity ã®ææã®å¯Ÿè±¡ã«ãªããŸãã // Before.kt val powerRate: float = member.powerRate / menber.maxPowerRate var currentCondition: Condition = Condition.DEFAULT if (powerRate == 0 ) { currentCondition = Condition.DEAD } else if (powerRate < 0.3 ) { currentCondition = Condition.DANGER } else if (powerRate < 0.5 ) { currentCondition = Condition.WARNING } else { currentCondition = Condition.GOOD } return currentCondition å®éã®ã¬ãã¥ãŒã³ã¡ã³ãã§ã¯ã以äžã®ããã«ãã¹ããè§£æ¶ããããã«ææãããå Žåãªã©ã«äœ¿çšããŸãã // After.kt val powerRate: float = member.powerRate / menber.maxPowerRate if (powerRate == 0 ) { return Condition.DEAD } if (powerRate < 0.3 ) { return Condition.DANGER } if (powerRate < 0.5 ) { return Condition.WARNING } return Condition.GOOD 3. NamingïŒ åœå ïŒ å®çŸ© 倿°ãã¯ã©ã¹ãã¡ãœããã«è²¬åãæå³ããæç¢ºãªååãä»ããããŠããããè±èªææ³ã«èª€ãããªããã typo ãããã«å«ãŸããã å
·äœäŸ ãã®ãã㪠åœå ã«é¢ããææãããå Žåã«äœ¿çšããŸãã æ¯ãèããšäžèŽããªã倿°åã颿°å 責åãšäžèŽããªã颿°å è±ææ³ã®èª€ã etc. äŸãã° iOS ã¢ããªéçº æã«ãããŠã¯ãSwift Foundation ã Cocoa ã® åœåèŠå ã«æºæ ããªãå ŽåãNaming ã®ææå¯Ÿè±¡ã«ãªããŸããåºæ¬ç㪠åœåèŠå ã¯ãå©çšããŠãã ãã¬ãŒã ã¯ãŒã¯ ãèšèªã®ç¹æ§ã«ãããã®ãå€æåºæºã«ãªããŸãã 4. StyleïŒã³ãŒãã¹ã¿ã€ã«ïŒ å®çŸ© ã³ãŒãã¹ã¿ã€ã«èšèªä»æ§ã«æºæ ããŠãããã å
·äœäŸ ã³ãŒãã¹ã¿ã€ã«ãåæ§ã«èšèªä»æ§ã ãã¬ãŒã ã¯ãŒã¯ ã«æºæ ãããããšãåºæ¬ã«ãªããããããã«åããå Žåã«äœ¿çšããŸãã éçè§£æéå äžé©åãªã¢ã¯ã»ã¹ä¿®é£Ÿå 衚èšéå(ã¹ããŒã¯ããã£ã¡ã«ãªã©) etc. ä»ã«ãã¢ãã€ã«éçºã§ã¯ãå
¬åŒ( Apple ã Google ç)ã§å
¬éããŠãã ã¬ã€ãã©ã€ã³ éåããŠããå Žåãããã«å«ãŸããŸããã³ãŒãã¹ã¿ã€ã«ã®å€æã¯ãã®äººã®çµæŽãªã©ã®äž»èгçãªéšåã圱é¿ããã®ã§ãã³ãŒããã©ãŒããã¿ãŒãå°å
¥ãã æ©æ¢°ç ãªå€æåºæºãèšããããšããã®ææç¹ãæžããæå¹ãªææ®µã§ãã 5. FunctionalityïŒæ©èœèŠæ±ïŒ å®çŸ© ã·ã¹ãã ãšããŠå€éšä»æ§ãå
è¶³ããŠããããäœè
ãæå³ããéãã®æ¯ãèãã§ãããã ãŸããã·ã¹ãã ã®éä¿¡éãããã©ãŒãã³ã¹ã«æžå¿µããªããã å
·äœäŸ äž»ãªèгç¹ãšããŠã¯ãå€éšæ©èœãå
è¶³ããŠããããšããç¹ã察象ã«ãªããŸãã å€éšä»æ§ã®æªå
è¶³ïŒäžå
·åïŒ æŠèŠèšèšæžã® ãããŒãã£ãŒã ãšç°ãªããããŒã«ãªã£ãŠãã äžèŠããŒã¿ãéä¿¡ããŠãã etc. 6. TestïŒãã¹ãïŒ å®çŸ© ã·ã¹ãã ãšããŠé©åãªèªåãã¹ããå
ŒãåããŠããããèªåãã¹ãã®å
容ã§å質ãæ
ä¿ã§ããŠãããã ãŸããã·ã¹ãã ãæ
ä¿ãããã©ã¡ãŒã¿çŸ€ãåããŠãããã å
·äœäŸ ãã¹ãã³ãŒããæåŸ
ã«ãªã£ãŠããªãå Žåãããã¹ãã§ã®ãã©ã¡ãŒã¿ã«èæ
®æŒããããå Žåãææã®å¯Ÿè±¡ã«ãªããŸãã 察象ã®ã¡ãœããããã¹ããããŠããªã ãã¹ããã¿ãŒã³ãç¶²çŸ
ã§ããŠããªãïŒãã¿ã¡ãŒã¿ãã¹ãã éŸå€ ãã¹ãã®äžè¶³ïŒ åå²ããã¿ãŒã³ãç¶²çŸ
ãããŠããªã å®è£
äžå®£èšããŠããéç宿°å€ãçŽæ¥ããŒãã³ãŒããããŠãã ã¢ãŒããã¯ãã«æºãããã¹ãã«ãªã£ãŠããªã 7. DocumentïŒæç« ïŒ å®çŸ© ãœãŒã¹ã³ãŒã äžã«èšèŒãããŠãã docãã³ã¡ã³ããé©åãªå
容ã§ãããã ãŸããé¢é£ããããã¥ã¡ã³ãã¯æŽæ°ãããŠãããããã®å
容ã¯é©åãã å
·äœäŸ ãœãŒã¹ã³ãŒã ã«é¢é£ããã³ã¡ã³ãã ãã§ãªãããããžã§ã¯ãã§ç®¡çããŠããé¢é£ããã¥ã¡ã³ãïŒREADMEïŒã察象ã«ãªããŸãã é¢é£ããã¥ã¡ã³ãã®æŽæ°æŒãïŒREADME ãªã©ïŒ doc ãã³ã¡ã³ãã®å
容ãäžé©åãå
容ãäžé©å ææå¯Ÿå¿ã®èŠåŠ æŽã«ã³ãŒãã¬ãã¥ãŒã®çŸå Žã§ã¯äžèšã®7ã€ã®èгç¹ã«å ããŠãææä¿®æ£ã®èŠåŠãïŒã€ã®çޝèšã«åããŠã³ã¡ã³ãããŠããŸãã èŠ³ç¹ æŠèŠ MUST PRãMR ãããŒãžããããã«ã¯å¿
ãä¿®æ£ãå¿
èŠ SHOULD ä¿®æ£ãªãã«ããŒãžããããšã¯ã§ãããããªãªãŒã¹ãŸã§ã«ã¯ä¿®æ£ãå¿
èŠ IMO ã¬ãã¥ãŒã¢ãŒèгç¹ã®æèŠãä¿®æ£äžèŠ NITS IMO ãã现ããæèŠãªã©ãä¿®æ£äžèŠ ãã®ããã«ãã³ãŒãã¬ãã¥ãŒã§ããŒãžããããã«å¿
èŠãªä¿®æ£ã¯ MUST ææãšãªããŸããMUST ãš SHOULD ã®äœ¿ãåãã¯é£ããéšåããããŸããããããŸã§ã®ã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ã®éçšã§ã¯ã SQL ã®ããã©ãŒãã³ã¹ãããè¯ãããããã®ææããã¹ãã³ãŒãã®æé©åã®ææãªã©ã§ SHOULD ã¯å©çšãããå Žé¢ããããŸãããã®å Žåãä¿®æ£ã¿ã¹ã¯ã Issue ã«ç©ãã äžã§ïŒä¿®æ£ã¹ã³ãŒãã®åæïŒãããŒãžããããã«ããŠããŸããäžæ¹ãIMO ã NITS ã¯ä¿®æ£ã¯äžèŠã§ãããä¿®æ£ããªãå Žåã¯ãã®æšãã³ã¡ã³ãã«è¿ä¿¡ããŠããããã³ã¡ã³ããéããŠããããŒãžããéçšãããŠããŸãïŒã¬ãã¥ã¢ãŒãšã®åæïŒã å
·äœçãªå©ç𿹿³ å®éã«ã³ãŒãã¬ãã¥ãŒããããšããäžèšã®7ã€ã®èгç¹ãšä¿®æ£ã®æž©åºŠæããã®ããã«äº€ãã Prefix ãä»ããŠãã³ã¡ã³ããããŸãã ææäŸ MUST(Design): ãã¡ã€ã³ ããžãã¯ã Controller ã¯ã©ã¹ã«å®è£
ãããŠãŸãã domain å±€ã®å¯Ÿè±¡ package ã«æ°ããã¯ã©ã¹ãäœæããŠå®è£
ãç§»ããŠãã ããã ãã®ãšã Prefix ã®å
¥åãæå
¥åã«ããŠããŸããšãå
¥åã®æéãå
¥åããã¹ãçããããšãããã®ã§ãã«ã¹ã¿ã script ã§å
¥åããµããŒãããããã«ããŠããŸãã æåŸã« 以äžã®ããã«ãç§ã®ããŒã ã§ã¯ã³ãŒãã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ãäœæããŠã«ãŒã«ãææåããããšã§ãæè¡åã èŠããå ãããŠèª²é¡æ¹åãé²ããŠããŸããã¬ãã¥ãŒã³ã¡ã³ãããã®ããã«åæããããšã§ãå人ã®åŒ±ç¹ã«åãããã¢ãããŒãæ¹æ³ãèŠããŠããŸãããã®ããã«æè¡åã«å¯Ÿããã¢ãããŒããšã㊠PDCA ãµã€ã¯ã«ãåãããšã§ãããŒã ã¡ã³ããŒã®æè¡è²æãé²ããŠãããŸãã æåŸã«ç°¡åã«ãŸãšãããšãã³ãŒãã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ãææåããå Žåã æææ°ã«å¿ããŠæè¡åã èŠããå ã§ãã ã³ãŒãã¬ãã¥ãŒã§ ãªããžã§ã¯ãæå ãåŠã¹ã ã¹ãã«ã¢ãã ã®ããã®ã¢ã¯ã·ã§ã³ãã©ã³ãæ€èšãããã ãšãã£ãæ©æµãåããããšã§ããã®ã§ããã²ããŒã ã«åã£ãã³ãŒãã¬ãã¥ãŒ ã¬ã€ãã©ã€ã³ ãäœæããŠã¿ãŠã¯ãããã§ããããã
ã¯ããã« ã¯ãããŸããŠãã€ã³ãã©ãšã³ãžãã¢ã® rkyohei ã§ãã Linux ãµãŒãã®éçšãã¢ãã¿ãªã³ã°ã«ãããŠãæ§èœãã¥ãŒãã³ã°ã ãã©ãã«ã·ã¥ãŒãã£ã³ã° ã«ã¯ããŸããŸã³ãã³ãã䜿çšãããšæããŸãããã®äžã§ããç¹ã«ãªãœãŒã¹äœ¿çšç¶æ³ã詳现ã«åæããããã«äŸ¿å©ãªããŒã«ã®1ã€ããvmstatããšãªããŸãã vmstatã³ãã³ãã®ååšèªäœã¯ç¥ã£ãŠãããã©ããªãã·ã§ã³ãå®è¡çµæã®èŠæ¹ã«ã€ããŠããŸãç¥ããªãã£ãã®ã§ãããå
æ¥æ¥åã§äœ¿çšããæ©äŒããããvmstatã³ãã³ãã«ã€ããŠèª¿ã¹ãŸããã®ã§ãã®ãšã³ãžãã¢ããã°ã§ã¿ãªããã«ã玹ä»ããããšæããŸãã ã¯ããã« vmstatãšã¯äœãïŒ vmstatã³ãã³ãã®åºæ¬çãªäœ¿ãæ¹ vmstatã³ãã³ãå®è¡çµæã®èŠæ¹ vmstatã³ãã³ãã®å®è¡äŸ 1. vmstatã³ãã³ãã®ã¿ã§ã®å®è¡äŸ 2. æŽæ°ééãè¡šç€ºåæ°ãå«ããå®è¡äŸ 3. -sãªãã·ã§ã³ïŒã¡ã¢ãªçµ±èšæ
å ±ã®è¡šç€ºïŒã䜿çšããå®è¡äŸ 4. -dãªãã·ã§ã³ïŒãã£ã¹ã¯I/Oçµ±èšæ
å ±ã®è¡šç€ºïŒã䜿çšããå®è¡äŸ æåŸã« åèæç® vmstatãšã¯äœãïŒ vmstatãšã¯ Virtual Memory Statistics ã®ç¥ã§ããã Linux ã·ã¹ãã äžã§ ä»®æ³ã¡ã¢ãª ã®çµ±èšæ
å ±ã衚瀺ããã³ãã³ãã§ãã vmstatã³ãã³ãã®åºæ¬çãªäœ¿ãæ¹ vmstatã³ãã³ãã®åºæ¬çãªäœ¿ãæ¹ã«ã€ããŠã玹ä»ããŸãã vmstatã[ãªãã·ã§ã³] [éé(sec) [åæ°] ] â»[ ] ã¯çç¥å¯èœã§ã ãªãã·ã§ã³: ããã§ã¯vmstatã³ãã³ãã®ãªãã·ã§ã³ã«ã€ããŠäžéšã玹ä»ããŸãã ãªãã·ã§ã³ 説æ -a ä»®æ³ã¡ã¢ãª ã®è©³çްæ
å ±ã衚瀺ããŸããããã»ã¹ã®ã¹ããŒãïŒå®è¡äžãã¹ãªãŒãäžãªã©ïŒãããŒãžã³ã°ãã¡ã¢ãªæ
å ±ãªã©ãå«ãŸããŸãã -s ä»®æ³ã¡ã¢ãª ã®çµ±èšæ
å ±ã®ã¿ã衚瀺ããŸããåçš®ã¡ã¢ãªã¹ã¿ãããããŒãžã³ã°ã ã¹ã¯ãã æ
å ±ãªã©ã衚瀺ãããŸãã -d ãããã¯ã ãã€ã¹ ã®IOçµ±èšæ
å ±ã衚瀺ããŸããIOã®ãã€ãæ°ããªã¯ ãšã¹ ãæ°ã転éæéãªã©ã衚瀺ãããŸãã -D ãã£ã¹ã¯ã®çµ±èšæ
å ±ã1é
ç®1è¡ã§è¡šç€ºããŸãã -p < ããŒãã£ã·ã§ã³ > æå®ãã ããŒãã£ã·ã§ã³ ã«é¢ããæ
å ±ã衚瀺ããŸãã ããŒãã£ã·ã§ã³ ãæå®ããŠè©³çްæ
å ±ãååŸããããšãã§ããŸãã -S åäœ åäœãk,K,m,Mã§æå®ããŸãã -t ã¿ã€ã ã¹ã¿ã³ãã衚瀺ããŸãã ãããã®ãªãã·ã§ã³ã䜿çšããããšã§ãããŸããŸãªæ
å ±ãååŸããããšãã§ããŸããäŸãã°ã ä»®æ³ã¡ã¢ãª ã®è©³çްæ
å ±ãçµ±èšæ
å ±ããããã¯ã ãã€ã¹ ã®IOçµ±èšæ
å ±ãªã©ãå©çšããŠãã·ã¹ãã ã®æ§èœããªãœãŒã¹äœ¿çšç¶æ³ããã詳现ã«åæã§ããŸãã äžèšä»¥å€ã«ããªãã·ã§ã³ã¯ãããŸãã®ã§ããªãã·ã§ã³ã®è©³çްã«ã€ããŠèå³ãããæ¹ã¯ã man ã³ãã³ãã䜿çšããŠããã¥ã¢ã«ããŒãžãåç
§ããŠããã ããã°ãšæããŸãã æŽæ°éé: ããã©ã«ãã§ã¯1ç§ããšã«æ
å ±ã衚瀺ãããŸãããå¿
èŠã«å¿ããŠå€æŽã§ããŸãã è¡šç€ºåæ°: æå®åæ°ã ãæ
å ±ã衚瀺ããåŸã«ã³ãã³ããçµäºããŸãã vmstatã³ãã³ãå®è¡çµæã®èŠæ¹ vmstatã³ãã³ãã®å®è¡çµæã®èŠæ¹ã«ã€ããŠã以äžã«ã玹ä»ããããŸããããã§ã¯vmstatã³ãã³ãããªãã·ã§ã³ç¡ãã§å®è¡ããçµæãäŸãšããŠããŸãã # vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----  r  b  swpd  free  buff  cache  si  so   bi   bo  in  cs us sy id wa st  0  0 123088 154496    0 1168484   0   0   0   1   1   1  0 0 100  0  0 åºå å€ æå³ procs r çŸåšå®è¡åŸ
ã¡ã®ããã»ã¹æ°ãCPUãéè² è·ã§ãããã©ãããç€ºãææšã§ãã b ã¹ãªãŒãäžã®ããã»ã¹æ°ãã¹ãªãŒãäžã®ããã»ã¹ã¯I/Oã®å®äºãåŸ
ã£ãŠããŸãã memory swpd ã¹ã¯ãã ãããããŒãžã®æ°ã ã¹ã¯ãã ã®éãç€ºãææšã§ãã free 䜿çšãããŠããªãã¡ã¢ãªã®éã倧ããªå€ãæãŸããã§ãã buff ãã¡ã€ã«ã®èªã¿åãçµæãšããŠãã£ãã·ã¥ãããŠããã¡ã¢ãªéã cache ãã¡ã€ã«ã·ã¹ãã ããã£ãã·ã¥ããŠããããŒãžã®éãã¡ã¢ãªäœ¿çšå¹çã®ææšã swap si ã¹ã¯ãã é åããã¡ã¢ãªã«ããŒãžã転éãããåæ°ã so ã¡ã¢ãªãã ã¹ã¯ãã é åã«ããŒãžã転éãããåæ°ã io bi ãããã¯ã ãã€ã¹ ããåãåã£ããããã¯ãïŒblocks/sïŒ bo ãããã¯ã ãã€ã¹ ã«éããããããã¯ãïŒblocks/sïŒ system in 1ç§ãããã®å²ã蟌ã¿ã®æ°ãããŒããŠã§ã¢ã®è² è·ã瀺ãã cs 1ç§ãããã® ã³ã³ããã¹ãã¹ã€ãã ïŒããã»ã¹ã®åãæ¿ãïŒã®æ°ã cpu us ãŠãŒã¶ãŒããã»ã¹ãæ¶è²»ããCPUæéã sy ã«ãŒãã« ããã»ã¹ãæ¶è²»ããCPUæéã id ã¢ã€ãã«ç¶æ
ã®CPUæéãé«ãã»ã©CPUãã¢ã€ãã«ã§ããããšã瀺ããŸãã wa ãã£ã¹ã¯I/Oã®åŸ
æ©æéããã£ã¹ã¯ãžã®ã¢ã¯ã»ã¹ãé
ãå Žåã«å¢å ããŸãã st ä»®æ³ãã·ã³ ããçãŸããæéã瀺ããŸãã vmstatã³ãã³ãã®å®è¡äŸ vmstatã³ãã³ãã®å®è¡äŸãšçµæã«ã€ããŠããã€ãã玹ä»ããŸãã 1. vmstatã³ãã³ãã®ã¿ã§ã®å®è¡äŸ vmstatã³ãã³ãããªãã·ã§ã³ç¡ãã§å®è¡ãããšã1åã®ã¿çµæã衚瀺ãããŸãã # vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----  r  b  swpd  free  buff  cache  si  so   bi   bo  in  cs us sy id wa st  0  0 123088 154496    0 1168484   0   0   0   1   1   1  0 0 100  0  0 2. æŽæ°ééãè¡šç€ºåæ°ãå«ããå®è¡äŸ 以äžã®ããã«å®è¡ããããšã§æŽæ°ééãè¡šç€ºåæ°ãæå®ããããšãã§ããŸããããã§ã¯1ç§ééã§5åå®è¡ãããããã«æå®ããŠããŸãã ãŸã -t ãªãã·ã§ã³ã䜵ããŠäœ¿çšããããšã§ã¿ã€ã ã¹ã¿ã³ããçµæã«è¡šç€ºãããããšãã§ããŸãããããã ãã©ãã«ã·ã¥ãŒãã£ã³ã° ã®éã«ã¯åé¡ãšãªãäºè±¡ãåçºãããŸã§ã³ãã³ããç¶ç¶ããŠå®è¡ããå¿
èŠããããcronã§å®æçã«å®è¡ããããåŒæ°ã䜿çšããŠå®è¡ç¶æ
ã®ãŸãŸçµéç£èŠãããšæããŸãã TeraTerm çã®ãã°ä¿åèšå®ã«ã¿ã€ãã¹ã¿ã³ããä»äžããããšãå¯èœã§ããã -t ãªãã·ã§ã³ã䜿çšãã¿ã€ã ã¹ã¿ã³ãã衚瀺ããããšã§åé¡ãçºçããæéã®ãã°ãæ¢ãããããªããŸãã # vmstat 1 5 -t procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp-----  r  b  swpd  free  buff  cache  si  so   bi   bo  in  cs us sy id wa st         JST  0  0 123088 154320    0 1168484   0   0   0   1   1   1  0  0 100  0  0 2023-08-28 12:17:49  1  0 123088 154224    0 1168484   0   0   0   0  141  202  1  0 100  0  0 2023-08-28 12:17:50  0  0 123088 154224    0 1168484   0   0   0   0  150  218  0  0 100  0  0 2023-08-28 12:17:51  0  0 123088 154256    0 1168484   0   0   0   0  128  189  0  0 100  0  0 2023-08-28 12:17:52  0  0 123088 154256    0 1168484   0   0   0   0  139  192  0  1 100  0  0 2023-08-28 12:17:53 3. -s ãªãã·ã§ã³ïŒã¡ã¢ãªçµ±èšæ
å ±ã®è¡šç€ºïŒã䜿çšããå®è¡äŸ -s ãªãã·ã§ã³ã䜿çšããããšã§ã¡ã¢ãªã®çµ±èšæ
å ±ã1é
ç®1è¡ã§è¡šç€ºããããšãã§ããŸãã # vmstat -s 1728000 K total memory 405420 K used memory 621268 K active memory 539020 K inactive memory 153972 K free memory 0 K buffer memory 1168608 K swap cache 2097148 K total swap 123088 K used swap 1974060 K free swap 3091882 non-nice user cpu ticks 135539 nice user cpu ticks 1694588 system cpu ticks 2524043051 idle cpu ticks 59367 IO-wait cpu ticks 1517573 IRQ cpu ticks 1268497 softirq cpu ticks 487644 stolen cpu ticks 9009973 pages paged in 20842448 pages paged out 74510 pages swapped in 207951 pages swapped out 1668051957 interrupts 2180661177 CPU context switches 1680577615 boot time 393160 forks 4. -d ãªãã·ã§ã³ïŒãã£ã¹ã¯I/Oçµ±èšæ
å ±ã®è¡šç€ºïŒã䜿çšããå®è¡äŸ -d ãªãã·ã§ã³ã䜿çšããããšã§ãã£ã¹ã¯I/Oã®çµ±èšæ
å ±ã衚瀺ããããšãã§ããŸãããã£ã¹ã¯ã®æ§èœè©äŸ¡ã ãã©ãã«ã·ã¥ãŒãã£ã³ã° ã«åœ¹ç«ã€æ
å ±ã確èªããããšãã§ããŸãã # vmstat -d disk- ------------reads------------ ------------writes----------- -----IO------ total merged sectors ms total merged sectors ms cur sec sda 238129 21641 18019946 506118 893700 503648 41682672 4461928 0 2138 sr0 9 0 3 2 0 0 0 0 0 0 dm-0 181053 0 17319481 448718 1182573 0 40014120 8384242 0 2099 dm-1 74608 0 600776 58836 207951 0 1663608 8075290 0 42 ãã£ã¹ã¯I/Oã®çµ±èšæ
å ±ã§ã¯3ã€ã®é
ç®ã衚瀺ãããŸããããããèªã¿åãïŒreadsïŒãšæžã蟌ã¿ïŒwritesïŒãå®è¡äžã®I/Oã§ããåé
ç®äžã®msãšsecã¯åèšæéã瀺ããŠããŸãã æåŸã« vmstatã³ãã³ãã¯ã Linux ãµãŒããšã³ãžãã¢ã«ãšã£ãŠéèŠãªã¢ãã¿ãªã³ã°ããŒã«ã§ãããªãœãŒã¹äœ¿çšç¶æ³ã® ãã©ãã«ã·ã¥ãŒãã£ã³ã° ãæé©åã«ãšãŠãæå¹ã ãšèããŸãã ãã ãããªãã·ã§ã³ãå®è¡çµæãçè§£ããèŠããããšã¯ãªããªãé£ãããšæããŸãã ã³ãã³ããå®è¡ããç°å¢ãããã®ã§ããã°ãå®éã«ã³ãã³ããå®è¡ããããšã§ããªãã·ã§ã³ãçµæã«ãµããŠã¿ãã®ãè¯ããšæããŸãã åèæç® How to read Vmstat output
ã¯ããã« æšä» æžç±ãå瀟Blogèšäºãªã©ã§ãããã¯ããããŒãžã£ãŒ(以äžPdM)ã®æ¥åå
容ã«ã€ããŠèšèŒãããåªäœã倿°ã§ãŠããç¶æ³ã§ãã ã§ãããè€æ°ã®åªäœãåç
§ãããæ¹ã¯ãããæãããããšãå€ããšèããŠãããŸãã ãèŠããã®ã«ãã£ãŠåœ¹å²ãæ¥åå
容éããªããïŒã å®éãäŒæ¥ã»ãããã¯ãã»ããŒã ãšãã£ãåäœã§ãPdMã®æ¥åå
容ã¯å€ãã£ãŠãããšç§ãèããŠãããŸãã åŒç€Ÿ ã©ã¯ ã¹ã«ãã以äžã®ããã«ããŸããŸãªãããã¯ããããããŸãããåãããã¯ãã«ãã£ãŠPdMã®æ¥åå
容ã¯ç°ãªã£ãŠããŸãã ãã®äžã§ãä»åã¯ã ãæ¥œæ¥œç²Ÿç®ãã®PdMæ¥åå
容ãã玹ä»ããŸãã ã¹ã³ãŒã ã¯ããã« ãããã¯ãäœå¶ 楜楜粟ç®ã®PdMæ¥åå
容 äºæ¥KPIè²¢ç®ã«æ²¿ã£ãåªå
é äœ PRD(èŠæ±ä»æ§æž)äœæ ä»åŸã®å±æ ã©ã¯ã¹ã®PdMãšããŠæŽ»èºããŠã¿ãŸããã? ãããã¯ãäœå¶ ãã£ããPdMã®æ¥åå
容ã説æããããšããã§ããã ãŸãã¯æ¥œæ¥œç²Ÿç®ãæäŸã»éçºããäžã§ã®äœå¶(æŠç¥å³)ã説æãããŠãã ããã ïŒãã®æ¹ãåŸç¶ã®çè§£ããããããªãããã§ãïŒ æ¥œæ¥œç²Ÿç®ãARR100åãéæããŠããããšãããçµç¹ãšããŠã倧ãããªã£ãŠãããŸãã ãã®äžã§ãç¹çããéšåã¯ãéçºãšäºæ¥ãã€ãªã圹å²ãšããŠPdM/PMMãé
眮ããŠããéšåã§ãã æ¥œæ¥œç²Ÿç®ãããã¯ãäœå¶æŠç¥å³ 楜楜粟ç®ã®PdMæ¥åå
容 倧ãã以äžã®æ¥åãããããŸãã äºæ¥KPIè²¢ç®ã«æ²¿ã£ãåªå
é äœã§æ¡ä»¶ãæšé²ããã㚠顧客解å床ãé«ããäžã§ãPRD(èŠæ±ä»æ§æž)ãäœæãéçºãžæž¡ãããš äºæ¥KPIè²¢ç®ã«æ²¿ã£ãåªå
é äœ åºæ¬çã«ã以äžå³ã®ããã«CSããèŠãããè§£çŽåå ãå¶æ¥ããèŠããã倱泚åå ããã財å广ãå²ãåºãæ¡ä»¶ã®åªå
é äœã決ããŠãããŸãã äŒç€ŸæŠç¥äž åªå
ããããšã決å®ããŠããæ¡ä»¶ãEOLãªã©ã®ç¶æç®¡çæ¡ä»¶ãªã©ã¯ããã®éãã§ã¯ããããŸããã åºæ¬åªå
é äœããžã㯠PRD(èŠæ±ä»æ§æž)äœæ 楜楜粟ç®ã§ã¯ãPRDã«çã蟌ãèŠçŽ ã¯ã以äžç»åã®ãªã¬ã³ãžéšåãšå®çŸ©ããŠããã調æ»å¯Ÿè±¡ã«å®ããŠããŸãã ïŒãã¡ãã¯åPdMã«ãã£ãŠæ§ã
ãªãæèŠãããããšæããŸãããäžæŠæ¥œæ¥œç²Ÿç®ã§ã¯ããããŠããŸãïŒ ç»å㯠ãããã¯ããããžã¡ã³ãã®ãã¹ãŠ ããæç²ãããŠããã ããŠãããŸãã ïŒå
šPdMãèªãã¹ãè¯æžãšç§ã¯æã£ãŠããŸãïŒ ãããã¯ã4éå±€ ãåºå
žïŒã ãããã¯ããããžã¡ã³ã ã®ãã¹ãŠãp.52ã®èšèŒãåŒçšãããªã¬ã³ãžæ ã¯çè
è¿œèš ãŸãã調æ»ããããã®èšç»Agendaã¯ãçŸç¶ä»¥äžã®ããã«å®ããŠããŸãã ïŒãã©ãã·ã¥ã¢ããã¯ç¶ããŠããŸã) 調æ»èšç»Agenda æçµçã«ã¯ã以äžã®Agendaã®å
å®¹ã¯æäœã§ãPRDã«çã蟌ãããã«ããŠããŸãã PRD Agenda(äžéš) ä»åŸã®å±æ çŸåšä»¥äžã®ããã«DACIãšãã ãã¬ãŒã ã¯ãŒã¯ ãå©çšããŠãPdM/PMMã®åœ¹å²åæ
ãæ±ºããŠããŸãã ä»åŸã¯ãã€ã³ã¿ãã¥ãŒçã®å鿥åããããã¯ãææšã®æ±ºå®(å
±ã«çŸç¶0ã§ã¯ãªãã®ã§ãã)ã«ãèžã¿èŸŒãã§ãããããšèããŠãããŸãã DACI衚(äžéš) ã©ã¯ ã¹ã®PdMãšããŠæŽ»èºããŠã¿ãŸããã? ä»åŸã®å±æã«ãèšèŒã®éããPdMãšããŠåœ¹å²ãåºããŠãããããšèããŠãããŸãã ãã®ããã«ã楜楜粟ç®PdMã¯ã人æãåéããŠãããŸãã æ¯éã«ãžã¥ã¢ã«é¢è«ãããç³ã蟌ã¿ããã ãããšå¹žãã§ãã プロダクトマネージャー | エンジニア職種紹介 | 株式会社ラクス キャリア採用
ã¯ããã« ããã«ã¡ã¯ akihiyo76 ã§ããSwift Concurrency ã WWDC ã§çºè¡šãããŠãã 2 幎ã«ãªããŸãããåãããã¯ãã§ã¯ãµããŒãããŒãžã§ã³ãã¢ããããŒããããå®éã«å°å
¥ãé²ã¿å§ããŠãããããã¯ããå€ãã®ã§ã¯ãªãã§ãããããäžæ¹ã§æ°èŠã§éçºããå Žåã¯ãåæãšãªãæè¡ã ãšèããŠããŸããåŒç€Ÿã§ã Swift Concurrency ãžã®ç§»è¡å¯Ÿå¿ãè¡ããŸããããä»åã¯å®éã«è¡ã£ãå°å
¥æŠç¥ã玹ä»ããããšæããŸãã ã¯ããã« å°å
¥ããã¡ãªãã 1. 䞊è¡åŠçãç°¡æœã»å®å
šã«èšè¿°ã§ãã 2. ããŒã¿ã®ç«¶åããããããã¯ãåé¿ïŒå質åäžïŒ async / await Sendable Actor Task æ¢åãããžã§ã¯ããžã®å°å
¥ 1. PoCã³ãŒãã®å®è£
Strict Concurrency Checking ã®èšå® å®è£
æ¹éã®æ±ºå® 2. ã¹ã³ãŒãåå² 3. 暪å±éã»ãã¹ã ãŸãšã åè å°å
¥ããã¡ãªãã ã§ã¯ãåããŠããæ¢åã³ãŒããä¿®æ£ã㊠Concurrency ãå°å
¥ããã¡ãªããã¯äœã§ããããã å®éã«å¯Ÿå¿ãé²ããå Žåãå®è£
ã³ã¹ãã ãã§ã¯ãªããå質ãæ
ä¿ããããã®ãã¹ãã³ã¹ããå¿
èŠã«ãªããŸããæŽã«ãããã¯ãã«ãã£ãŠã¯ãªãªãŒã¹ã³ã¹ããå¿
èŠã«ãªãããããã®ã³ã¹ãã«åãã¡ãªãããèŠæ±ãããŸãã ããã§ãå®éã« Concurrency ãå°å
¥ããã¡ãªããã«ã€ããŠèããŠã¿ãããšæããŸãã 1. 䞊è¡åŠçãç°¡æœã»å®å
šã«èšè¿°ã§ãã ãŸããConcurrency ã®ã¡ãªãããšããŠã䞊è¡åŠçãç°¡æœã»å®å
šã«èšè¿°ã§ããããšããç¹ãæããããŸãã å®éã®ã³ãŒããæ¯èŒããŠã¿ãŸãããã以äžã¯åŸæ¥ã® Block æ§æã§å®è£
ããéä¿¡åšãã®ã³ãŒãäŸã§ãã func fetchImageData (request : URLRequest , completionHandler : @escaping ( UIImage? ) -> () ) { self .session.dataTask(with : request ) { data, response, error in // Image ãããŒããã self .loadImage(data : data ) { image in // Image ãµã€ãºãé©åããã§ãã¯ãã self .checkImage(image : image ) { completionHandler(image) } } }.resume() } ãã®å®è£
äŸã§ã¯ completionHandler() ã§ã³ãŒã«ããã¯ãç¹ããå®è£
ã«ãªã£ãŠãããããããã®åŠçããã¹ãæ§é ã圢æããŠããŸããããã«ããã³ãŒãã®è€éæ§ãå¢ããåå²åŠçããšã©ãŒåŠçã远å ããããšæŽã«å®è£
ãè€éã«ãªããå¯èªæ§ãäœäžããå質ã«ã圱é¿ãåãŒãå¯èœæ§ããããŸããè€éæ§ã®ããã« completionHandler() ã®èšè¿°ãå¿ããå Žåãç¹å®ã®åŠçã§ã³ãŒã«ããã¯ãåŸãããã¢ããªã®åŠçãæ¢ãŸããªã¹ã¯ãèããããŸãã ããã§ã¯ããã® Block æ§æã§èšè¿°ãããã³ãŒãã Concurrency ã䜿çšããŠæžãæããŠã¿ãŸãããã func request (url : URL ) async throws -> UIImage? { let (data, response) = try await URLSession.shared.data(from : url , delegate : nil ) let image = try await loadImage(data : data ) let result = try await checkImageSize(image : image ) return result } async / await ã䜿ã£ãŠæžãæããããšã§ãBlock æ§æã®å€æ®µãã¹ããè§£æ¶ãããéåæã®å®è£
ãç°¡æœã«èšè¿°ã§ããããã«ãªããŸãã ãã ããã³ãŒãã¹ã¿ã€ã«ãå¯èªæ§ã®åäžã ãã§ Concurrency ç§»è¡ã®ã³ã¹ããæ€èšããã®ã¯ãå²ã«åããªããããããŸããã 2. ããŒã¿ã®ç«¶åã ããããã㯠ãåé¿ïŒå質åäžïŒ Concurrency å°å
¥ã®ã¡ãªããã¯ãããŒã¿ç«¶åã ããããã㯠ãåé¿ã§ããããšã§ããå
·äœçã«ã¯ Sendable ã Actor ãšãã£ãæ©èœã®æ©æµã«ãããã®ã§ãããããã«ã€ããŠã¯åŸã»ã©å
·äœçã«èª¬æããŸããConcurrency ãå°å
¥ãããããã®æ©èœã«æºæ ããããšã§ãå質ã®ç¢ºä¿ã»æ¹åã«æåŸ
ã§ããç¹ã倧ããªã¡ãªããã ãšèããŠããŸãã async / await 颿°ã®å
é ã« asyncïŒasync throwsïŒ ãå®çŸ©ããããšã§ããã®é¢æ°ãéåæé¢æ°ãšããŠå®çŸ©ã§ããŸããå®çŸ©ããéåæé¢æ°ãå®è¡ããããã«ã¯ã await ã䜿çšããå¿
èŠããããŸãã func execute () { Task.detached { do { let url = URL(string : "https://api.example.com" ) ! // å®è¡å®äºãŸã§åŸ
æ©ãã let response = try await self .request(url : url ) // åŸç¶åŠç } catch { print(error.localizedDescription) } } } // éåæé¢æ°ãšããŠå®çŸ©ãã func request (url : URL ) async throws -> HTTPURLResponse { // éä¿¡åŠç return result } ãã®ããã«ã async / await ã䜿ã£ãŠå®çŸ©ããããšã§ãéåæé¢æ°ã®å®çŸ©ãšå®è¡ãå¯èœã«ãªããŸãã Sendable Sendable ã¯ããŒã¿ç«¶åãèµ·ãããªãããšã ã³ã³ãã€ã« æã«ä¿èšŒããŠãããåã§ãããŒã¿ç«¶åãé¿ããŠå®å
šã«æž¡ããããŒã¿ãè¡šãæŠå¿µãšããŠå°å
¥ãããŸãããSendable ãããã³ã« ã«æºæ ããããšã«ãã£ãŠããã®åã Sendable ã§ããããšã ã³ã³ãã€ã© ã«äŒããããŸãã final class Valid : Sendable { // 宿°å®çŸ© let name : String init (name : String ) { self .name = name } } final class Invalid : Sendable { // 倿°å®çŸ© var name : String init (name : String ) { self .name = name } } Valid ãš Invalid ã¯å
±ã« Sendable ãããã³ã« ã«æºæ ããŠããŸãããname ã«ã€ããŠã¯å®æ°ãšå€æ°ã§å®çŸ©ããŠãããInvalid ã® name ã¯å
¬éãããŠãããã倿Žãå¯èœã§ãããããŒã¿ç«¶åãçããå¯èœæ§ããããŸãããã®ç¶æ
ã§ ã³ã³ãã€ã« ãããšã Stored property 'name' of 'Sendable'-conforming class 'Invalid' is mutable ãšãã ã³ã³ãã€ã© ã®ããŒã¿ç«¶åèŠåãçºçããŸãã Actor Swift 5.5 ããå°å
¥ããã Actor 㯠Concurrency ã®äžéšãšããŠãããŒã¿ç«¶åãé²ãåã§ããActor ã«ããäœæããã ã€ã³ã¹ã¿ã³ã¹ ã¯ãäžã€ã®ããŒã¿ãžã®ã¢ã¯ã»ã¹ãåæã«è¡ãããªãããã«å¶åŸ¡ãããŸããããã Actor isolated ãšåŒã³ãè€æ°ã®ã¿ã¹ã¯ãããŒã¿ã«ã¢ã¯ã»ã¹ããéã«ãããŒã¿ç«¶åãé²ãããšãã§ããŸãã actor MainActor { // 倿°å®çŸ© var number : Int = 1 } func increment () { let act = MainActor() Task.detached { // number ãæŽæ° await act.number = 100 } } ãã®ããã« Actor ã§çæããã ã€ã³ã¹ã¿ã³ã¹ ã® number ã倿Žããããšãããšã Actor-isolated property 'number' cannot be mutated from a Sendable closure ãšãã ã³ã³ãã€ã« ãšã©ãŒãçºçããŸãã Task Task ã¯äžŠè¡åŠçãå®è¡ããåäœã§ãè€æ°ã®ã¿ã¹ã¯ã®æ§é åïŒTask TreeïŒãå¯èœã«ãªããŸãã以äžã®ã³ãŒãã®ããã«ã withTaskGroup ã䜿çšããŠã¿ã¹ã¯ã°ã«ãŒãïŒèŠªã¿ã¹ã¯ïŒãäœæããèŠçŽ ãšãªãåã¿ã¹ã¯ã远å ã»å®è¡ããããšãã§ããŸãã func getUser () async -> UserInfo { // 芪ã¿ã¹ã¯ await withTaskGroup(of : DataType.self ) { group in // åã¿ã¹ã¯ A group.addTask { let friends = await self .getFriends() return DataType.friends(friends) } // åã¿ã¹ã¯ B group.addTask { let notes = await self .getNotes() return DataType.notes(notes) } } return UserInfo(friends : friends , notes : notes ) } ãããã async / await ã Sendable ã Actor ã Task ãšãã£ãæ©èœã䜿çšããããšã§ãSwift Concurrency ãæŽ»çšãã广çãªéåæåŠçãå®çŸã§ããããã«ãªããŸãã æ¢åãããžã§ã¯ããžã®å°å
¥ ããããã¯æ¢åãããžã§ã¯ããžã®å°å
¥æ¹æ³ã«ã€ããŠç޹ä»ããŸããå°å
¥ã®äž»ãªæµããšããŠã¯ã以äžã®ããã«ãªããŸãã PoCã³ãŒãã®å®è£
ïŒConcurrency èšå®ãšå®è£
æ¹éã®æ±ºå®ïŒ ã¹ã³ãŒãåå² åã¹ã³ãŒãããšã®å¯Ÿå¿ ãªã°ã¬ãã·ã§ã³ ãã¹ã 倧ãŸããªå¯Ÿå¿æ¹æ³ãšããŠã¯ãå®è£
æ¹éãFIXããŠããŒã å
šäœã§äžæ°ã«å¯Ÿå¿ããŠãããšããæµãã§ãã 1. PoCã³ãŒãã®å®è£
Strict Concurrency Checking ã®èšå® å°å
¥ã«éããŠã¯ãå®è£
æ¹éïŒConcurrency ã®èšè¿°æ¹æ³ïŒã決å®ããå¿
èŠããããŸãããŸãæåã«ãããžã§ã¯ãã®èšå®ãšããŠã Strict Concurrency Checking ã®èšå®ãè¡ããŸãã èšå®ã«ã¯ MinimalãTargetedãComplete ã® 3 çš®é¡ããããŸããã Targeted ã«èšå®ããŸãã Minimal Sendable ã®å¶çŽããæç€ºçã«æ¡çšãããå Žæã«ã®ã¿åŒ·å¶ããã³ãŒããäžŠè¡æ§ãæ¡çšããå Žæã§ã¯ actor-isolated ãã§ãã¯ãå®è¡ããŸã Targeted Sendable ã®å¶çŽã匷å¶ããã³ãŒããäžŠè¡æ§ãæ¡çšããå ŽæïŒ Sendable ãæç€ºçã«æ¡çšããå Žæãå«ãïŒ actor-isolated ãã§ãã¯ãå®è¡ããŸã Complete ã¢ãžã¥ãŒã«å
šäœã§ Sendable ã®å¶çŽãš actor-isolated ã®åé¢ãã§ãã¯ã匷å¶ããŸã Complete ã¯ã¢ãžã¥ãŒã«å
šäœã«å€§ããªåœ±é¿ãåãŒããããå°å
¥æã®å¶çŽãšããŠã¯å³ãããããšå€æããŸããã åèïŒ https://developer.apple.com/documentation/xcode/build-settings-reference#Strict-Concurrency-Checking å®è£
æ¹éã®æ±ºå® Strict Concurrency Checking ã®èšå®åŸã¯ãåºæ¬ç㪠Concurrency ã®å®è£
ãã¿ãŒã³ãäœæããŸãã éä¿¡å®è£
ãªã©ã®ã³ã¢ãªéšåãå€ã察象ã«ãªããšèãããããããåã責åã® Concurrency 颿°ãæºåããŸããæçµçã«ã¯æ¢åã®å®è£
ãåé€ããããã @available ã§ deprecated ãæå®ããŠãããŸãã以äžã¯ withCheckedThrowingContinuation ã䜿çšã㊠Concurrency ã«å€æããŠããŸãããasync / await ã䜿çšããŠãåæ§ã«å€æå¯èœã§ãã @available ( * , deprecated , message: "This function is deprecated. Use the requestAsync () instead." ) func request (request : URLRequest , completionHandler : @escaping ( Data? ) -> () ) { self .session.dataTask(with : request ) { data, response, error in completionHandler(data) }.resume() } func requestAsync (request : URLRequest ) async throws -> Data? { return try await withCheckedThrowingContinuation { continuation in self .session.dataTask(with : request ) { data, response, error in if let error = error { continuation.resume(throwing : self.handleNSURLError (error : error as NSError )) return } continuation.resume(returning : data ) }.resume() } } ãŸããrequestAsync() ã®åŒã³åºãå
ã¯ã©ã¹ã倿ŽããŸãã以äžã® fetchUserData() 㯠View åŽããå®è¡ãããæ³å®ãªã®ã§ã @MainActor ãä»ã㊠Main Thread ããå®è¡ã§ããããã«ãããŸã nonisolated ãæå®ããŠéåé¢ã¡ãœãããšããŠæå®ããŸãã @MainActor class ViewModel { private let apiService = ApiService() nonisolated func fetchUserData () async throws -> Data? { do { let urlRequest = await self .createUrlRequest() return try await apiService.requestAsync(request : urlRequest ) } catch { throw await self .handleError(error) } } } æåŸã« fetchUserData() ã®åŒã³åºãã Task å
ã§è¡ããŸããTask ã®å®çŸ©ã¯ããããžã§ã¯ãã® ã¢ãŒããã¯ã㣠ã«åãããŠè¡ãã®ãè¯ãã§ãããã override func viewDidLoad () { super .viewDidLoad() Task { do { let userData = try await viewModel.fetchUserData() self .updateUser(userData) } catch { // ãšã©ãŒåŠç } } } } 2. ã¹ã³ãŒãåå² å°å
¥ã®åºæ¬æ¹éã確å®ããããå
·äœçãªé²è¡æ¹æ³ãæ€èšããŸããå€§èŠæš¡ãªãããžã§ã¯ãã§ã¯ä¿®æ£ãå€å²ã«ãããããšãäºæ³ãããŸãããäžåºŠã«è¡ã倿Žã倧ãããšãã¬ãã¥ãŒãå質管çãé£ãããªãå¯èœæ§ããããŸãããã®ãããäžå®ã®ç²åºŠã§åå²ãã察å¿ãé²ããããšã§è¿
éãªå¯ŸåŠãå¯èœã§ããããŒã å
šäœã§é²è¡ããå Žåãåã¡ã³ããŒãå®è£
ãšã¬ãã¥ãŒãåæã«è¡ãããšãæãŸããã§ããããããä¿®æ£ãã¹ãç®æãå€ãå Žåã¯ã ã¹ãã¬ããã·ãŒã ã§äžèЧåããŠããããã¡ã€ã«ããšãã¯ã©ã¹ããšãªã©æç¢ºãªåºåãæ¹æ³ã«ããããšã§ãäœæ¥ã®åæ
ã容æã«ãªããŸãã 3. 暪å±éã»ãã¹ã ä¿®æ£ãã¹ãã¹ã³ãŒãã確å®ããããããšã¯äžæ°ã«ä¿®æ£ãé²ããŸããããŒã ã®ç¶æ³ã«ãã£ãŠã¯ãåŸã
ã«ç§»è¡ããæ¹æ³ãããŸãããä»ã®æ©èœã®å®è£
ãé²è¡äžã®å Žåãã³ã³ããªã¯ããçºçããå¯èœæ§ããããããäžæ°ã«å¯Ÿå¿ããæ¹æ³ããªã¹ã¹ã¡ããŸããæåŸã«ã@available deprecated ãæå®ãã颿°ãåé€ããããšãå¿ããã«è¡ããŸããããå°å
¥å®è£
ãå®äºãããã ãªã°ã¬ãã·ã§ã³ ãã¹ãã宿œããŠæ©èœ ãã°ã¬ ããªãããšã確èªããŸãã ãŸãšã Swift Concurrency ã®äž»èŠãªæ©èœã«çŠç¹ãåœãŠãªãããæ¢åã®ãããžã§ã¯ãã«ãããå°å
¥æŠç¥ã玹ä»ããŸãããä»å玹ä»ããå°å
¥æŠç¥ã¯ãç§èªèº«ãå®è·µããæ¹æ³ã§ãããæ¢åã®å®è£
ãä¿ã¡ãªããé²è¡ãããããå€å°åé·ãªç®æããããããããŸãããããã¯ãããŸã§äžã€ã®æŠç¥ãšããŠãSwift Concurrency ã®å°å
¥ãæ¯æŽããããã®æå©ããšãªãããšãé¡ã£ãŠãããŸãã åè developer.apple.com
ããã«ã¡ã¯ããããã¯ããã°ãã¯ããã±..ãã±ããããµãŒããµã€ãã®ãšã³ãžãã¢ã®( @taclose )ã§ãâ åŒç€Ÿã§ã¯å
æ¥ ãã¹ãé§åéçº ïŒä»¥éãTDDãšåŒã¶)ãã³ãºãªã³å匷äŒãéå¬ããŸããïŒ ä»åã®èšäºã®å
容ã¯ãºããªïŒã€ 誀解ããŠã!? ãã¹ãé§åéçº ã®è¯ãïŒåŠã¶äºã®æå³ïŒ TDDãã³ãºãªã³å匷äŒãéå¬ããæå³ã宿œå
å®¹ãææ³ïŒ èªè
ã®ã¿ãŒã²ãã㯠TDDã誀解ããŠãã人 TDDãã³ãºãªã³å匷äŒãåŒç€Ÿã§ããããïŒãšãæã£ãŠã人 ãæ³å®ããŠããŸãã£ã 誀解ãããã¡ãªTDDãèšäºã«ããã«ã¯æžããããªãTDD...ãªãã¹ãå°é£ããå
容ã¯çããŠèå³ãæã£ãŠãããããã®èšäºãæžããŠã¿ãããšæããŸãïŒ ãã¹ãé§åéçºïŒTDDïŒã¯è¯ãç©ã ïŒ ãã¹ãé§åéçºïŒTDDïŒãšã¯äœãïŒ TDDã«å¯Ÿãã誀解 TDDãã³ãºãªã³ã«ã€ã㊠TDDãã³ãºãªã³ã®è¶£æš TDDãã³ãºãªã³ã®èšç» äºåæºå ã¹ã±ãžã¥ãŒã«ãšæŠèŠ TDDãã³ãºãªã³ã®ææ³ïŒåçç¹ãæ¯ãè¿ãïŒ åç»ã¯äºåã«èŠãŠãããã¹ãã ã£ã TODOãªã¹ãã®äœæã«ããå°ãããšããæã€ãšè¯ã ãŸãšã æåŸã« åèæç®ç ãã¹ãé§åéçº ïŒTDDïŒã¯è¯ãç©ã ïŒ ãã¹ãé§åéçº ïŒTDDïŒãšã¯äœãïŒ ããã°ã©ã éçºææ³ã®äžçš®ã§ãããã°ã©ã ã«å¿
èŠãªåæ©èœã«ã€ããŠãæåã«ãã¹ããæžãããã®ãã¹ãã åäœããå¿
èŠæäœéãªå®è£
ããšããããè¡ãªã£ãåŸãã³ãŒããæŽç·Žãããããšããçãå·¥çšãç¹°ãè¿ãã¹ ã¿ã€ã«ã§ãã (Wikipediaããæç²ïŒ ããTDDã«ã€ããŠèª¿ã¹ãŠã¿ããšãã ãããäžã®ãããªèª¬æã«å§ãŸããRed/Green/Refactorã®ãµã€ã¯ã«ãTDDã§ãããšåŠãã§çµãã£ãŠããŸããã§ãããã®èšäºã«èŸ¿ãçãèªè
ã¯ããããªäºã¯ããã£ãŠããããšãã人ã倧åã ãšæãã®ã§ããããŠããã§ã¯ãã説æããŠãããŸãã ãåäœããããããªã³ãŒãããRon Jeffriesã®ãã®ç°¡æœãªèšèãããã¹ãé§åéçºïŒTDDïŒã®ãŽãŒã«ã ã åäœããããããªã³ãŒãã¯ããããæå³ã§äŸ¡å€ãããã ïŒããã¹ãé§åéçºãè Kent Beck èš³ åç°å人ã®ãŸãããããæç²ïŒ TDD Boot Camp 2020 Online #1 åºèª¿è¬æŒ/ã©ã€ãã³ãŒãã£ã³ã° 2020幎ã«ãã£ãåç°ããã«ããåºèª¿è¬æŒããTDDãšã¯äœãïŒããšãã話ã¯ããããå§ãŸããŸããæ¯éãã®åç»ã¯èŠãŠé ãããã®ã§ãããæç²ããŠèšããšã ãåäœããããããªã³ãŒããæžãäºã¯ãå質ã»ã³ã¹ãã»éçºé床ã©ã®åŽé¢ããèŠãŠãéèŠãªèŠçŽ ã§ããããããå®çŸããã®ã«TDDã¯ïŒã€ã®è§£ã§ããã ãšãã£ãå
å®¹ã«æããŸããã ãã®ãŽãŒã«ããå§ãŸãããŸããããã®æžãæ¹ããããããèãããšTDDã£ãœããŠææ
šæ·±ãã§ããïŒã°ã¬ã€ãã£ïŒç¬ïŒ ã§ã¯ãããããªã«TDDãè¯ãã®ãªããªããã£ãšæ®åããªãã®ãïŒãå°ãã ãTDDã«å¯Ÿãã誀解ã«ã€ããŠè©±ããŠããããšæããŸãã TDDã«å¯Ÿãã誀解 ãã¹ãã³ãŒããæžãäºãäžè¬çã«ãªã£ãæšä»ã§ããããããªäžã§ ãTDDã¯å
ã«ãã¹ãã³ãŒããæžãäºããšããåã£ãèªç¥ ãåºãã£ãŠãã£ãããã§ããããã¯èª€ã£ãèªèã ãšããäºã¯å£°ã倧ã«ããŠãäŒããããã§ãã TDDã ãã¹ããã¡ãŒã¹ã ã§ããäºã«ã¯è€æ°ã®æå³ããããŸãããç§ãäžçªãã£ããããè§£éãšããŠã¯ã 詳现èšèšãšå®è£
ã®çéã«ãã©ããªé¢šã«ã¯ã©ã¹ãåããŠãã©ããªã¡ãœãããå®çŸ©ããŠããããšè¯ãã ãããïŒããšããã®ããã¹ãã³ãŒããšãã圢ã§ç®æ¡æžãããŠããéçºãã㌠ã ãšæããŸããã æãã€ãã§æžããåäœããã³ãŒãã¯ãåŸãŠããŠãã¹ãã³ãŒããæžãã¥ãããæ¢åå®è£
ã«å¯ŸããŠæžããããã§å®è£
ãé²ãã§ããŸããŸãããªã®ã§ãå
ã«ã©ã®ã¯ã©ã¹ã«ã©ããªã¡ãœãããååšããŠããŠã»ãããããã¹ãã³ãŒããšããŠèšèŒããŠããäºã§ãæ¬æ¥ããã¹ãå®è£
ã»æ¯ãèããå®è£
ã§ããã ãŸãã ãTDDã¯ãã¹ãã³ãŒãã®éçºã«æéããããã ãšããã®ãããèã話ã§ãããå
ã»ã©ç޹ä»ããåç»ã®äžã§ãæåŸã«è§£èª¬ãããŠããŸããããã¹ãã®çµæžæ§ãšããã®ã¯å®éãããªã«æªãã¯ãªããå°ãªãããæ
åœè
ãé¢è·ããééãããçãã¿ã€ãã³ã°ã§å
ã¯åããããã§ãã ãŸããããã§ãããŠãé¢è·ããééãããçãããšããèšãåãããããŠããã£ãã®ã¯ãå®äœéšçã«åœäºè
æèãæãŠããïŒãšããã®ãæ¡å€å€§äºãªã®ã§ã¯ãªãããšæã£ãããè£è¶³ãããŠããããŸãããå
éšå質ã®é«ãã³ãŒããæžãäºã®èŠè¿ãã¯èªåã«ãããäºãç¥ã£ãŠããŠã»ããã§ãã xUnit Test Patternsããæç² â»äžã®ç»åã¯ãå
ã»ã©è§£èª¬ããåç»ã®æåŸã®æ¹ã§åºãŠããã°ã©ãã§ãã ç¡é§ã«ã¡ã³ããã³ã¹ãå°é£ãªãã¹ãã³ãŒããéç£ããŠãããšã¡ã³ããã³ã¹ã³ã¹ããé«ããªãäºãããã®ã§æ³šæã§ãã â»æ¬æ¥ã® ãã¹ãé§åéçº ãããã°ããã¯ãªããŸãããïŒæ·±ãèãããã¹ããåŸããæžããããªéçºããŠããšãããªã£ã¡ããçŸå®ãåŸ
ã£ãŠããšããæ³šæåèµ·ã§ãã TDDãã³ãºãªã³ã«ã€ã㊠ããæå³ããããããæ¬é¡ã§ããã£ïŒ TDDãã³ãºãªã³ã®è¶£æš ãTDDã®è¯ããç¥ã£ãŠããã£ãŠãæ®æ®µã®éçºã«æŽ»ãããŠã»ãããããšããäºã§éå¬ãããŸããã å
ã«ãèšèŒããéããTDDãšããã®ã¯åå ããã ãŠã誀解ãããã¡ãªåŸåã«ãããæ¬åœã®è¯ãã£ãŠäŒããã«ãããã®ã§ãã å®éã«æãåãããŠã¯ãããŠããã確ãã«éçºã®æµãããã£ããããïŒå®å¿æãããïŒããããªTDDã ãããããã³ãºãªã³ãããæå³ãããã®ã§ã¯ïŒ ãšèããŸããã TDDãã³ãºãªã³ã®èšç» äºåæºå TDDã宿œããéçºç°å¢ãšã㊠Java ãåãéçºç°å¢ãå¿
èŠã«ãªããŸãããæéã§ããã° Codinggame.com ã®ãããªãµã€ãã§ãã£ãŠããã£ãŠãè¯ãããšæããŸãã www.codingame.com â»åŒç€Ÿãäžéšã®ç€Ÿå¡ã¯ãã¡ãã䜿ããŸãããæ®æ®µ PHP ã§éçºããŠã㊠Java ç°å¢ããªã瀟å¡çã ã¹ã±ãžã¥ãŒã«ãšæŠèŠ èšç» ïŒæ¥ç®ïŒ åŒç€Ÿã§ã¯ïŒæ¥ç®ã TDD Boot Camp 2020 Online #1 åºèª¿è¬æŒ/ã©ã€ãã³ãŒãã£ã³ã° ãäžç·ã«èŠèŽããæéã«è²»ãããŸããããã³ãºãªã³æ¬ç·šä»¥å€ã®éšåãã¹ããããããã1.25åéã§åçããŠ1æéåã«ç¡çç¢çççž®ããŸããïŒŸïŒŸïŒ ãŸãã¯åºç€ç¥èãšããŠTDDã®æµãã«ã€ããŠã¡ãããšçè§£ããŠãããããã£ãããã§ãã ïŒæ¥ç®ïŒ ããã幎åé¡ã¯ä»¥äžãšããŸããã å
¥åããæŽæ°ãããã幎ãã©ãããå€å®ããããã°ã©ã ãæžãã ããã幎ã®ãšãã¯ãtrueãããã以å€ã¯ãfalseããšããªã³ãããããšã ããã幎ã®å®çŸ© ã»è¥¿æŠå¹Žå·ã4ã§å²ãåãã幎ãããã幎ãšãã ã»ãã ãã西æŠå¹Žå·ã100ã§å²ãåãããã€400ã§å²ãåããªã幎ã¯å¹³å¹Žãšããã ç§ã®ææãšããŠã¯ãïŒæéåã§ãããã³ãºãªã³ã§ããã°ãäžåºŠããé£æåºŠããªãšæããŸããã ã¿ã€ã ã¹ã±ãžã¥ãŒã«ãšããŠã¯ä»¥äžãšããŸããã ããã幎ã«ã€ããŠã®TODOãªã¹ãã®æŽçïŒïŒïŒåïŒ ïŒããŒã ããTODOãªã¹ããçºè¡šïŒïŒåïŒ â»ãããåèã«åŸåã¿ã¹ã¯ãé²ããŠããã ãã¹ãã³ãŒãã®ãµã€ã¯ã«éå§ïŒRed/Green/Refactor)ïŒïŒïŒåïŒ ïŒããŒã ããTDDã®çµæãçºè¡šïŒïŒåïŒ ãããã¡ïŒïŒïŒåïŒ TDDãã³ãºãªã³ã®ææ³ïŒåçç¹ãæ¯ãè¿ãïŒ åç»ã¯äºåã«èŠãŠãããã¹ãã ã£ã åå è
ããé ããã³ã¡ã³ãã«ã ãéå¬åæ°ãå¢ããŠãããã®ã§ãããªã¯æ©åãåçã§ã¯ãªãéåžžåçãè¯ãã£ãã§ããã ãšãã£ããæèŠããããŸããã 確ãã«1.25åéã§æç²ããŠèŠãŠããã£ãã®ã¯èŠèã®çã§ãèšç»æ®µéã§ãæ©ãã ãã€ã³ãã§ããã ãåå è
ã¯äºåã«ãããèŠãŠæ¥ãŠãã ããïŒåéã§èŠããšãã¯ãä»»ãïŒããšããäžã§ãéèŠãã€ã³ãã ãããã¯ã¢ããããŠè§£èª¬ããŠããå§ãããããã«ããæ¹ããåæ»ã«é²ãã ããïŒ TODOãªã¹ãã®äœæã«ããå°ãããšããæã€ãšè¯ã åç»ãèŠãŠããããšãããããšã¯æããŸãããTODOãªã¹ããšã¯ãã©ããªæ¯ãèããããŠã»ããã®ããç®æ¡æžãã«ãã仿§æžã®ãããªãã®ãã§ãã TODOäœææéã«æéãå²ããŠãè¯ãã£ãããã«æããŸããã TODOããã£ããã§ããŠããã°åŸã¯ããéãã«å®è£
ããã ããªã®ã§ã å²åçã«ã¯TODOäœææéãå€ããªãã€ã¡ãŒãžã ãšå人çã«ã¯ããå°ãããŸãã§ããã®ããªãšæããŸããã äžèšã®ãããªæèŠãåŸæ¥ã¢ã³ã±ãŒãã§é ããŸããã 確ãã«ïŒïŒåãªããããå
šç¶è¶³ããªãã£ãïŒååã®TODOãªã¹ãäœæã¯ïŒïŒåãããã¯ãããŠããã¹ããïŒïŒåã§ãè¯ããšæããŸããã ïŒåã¯ããã³ã°ã¿ããã«ãåºæ¥äžãã£ãTODOãªã¹ãã¯ãã¡ãã§ããã£ãŠæç€ºããã®ã¯äžæ¡ãããããªããã§ããããã³ãºãªã³ã®æå³ãè²è€ªãã¡ãããŸãããOrz ãã£ããã®ãã³ãºãªã³ãªã®ã§ããå°ãæéã«ããšããããã°è¯ãã£ãã§ãïŒåçïŒ ãŸãšã åçãã¹ãç¹ã¯ãããŸãããïŒïŒåçšåå é ããç·ããŠTDDãã³ãºãªã³ã®å®æœã§æ°ããåŠã³ããã£ããšããæèŠã¯å€ããææçŸ©ãªæéã ã£ããªãšæããŸãïŒ TDDãã³ãºãªã³é¢šæ¯ïŒå€§éªïŒ TDDãã³ãºãªã³é¢šæ¯ïŒæ±äº¬ïŒ ãšã³ãžãã¢ã¯äžèœã§ã¯ãªãã®ã§ïŒå°ãªãããç§ã¯ïŒãã¹ããäºã¯å€ã
ãããŸããTDDã¯ãããã£ãæ®éã®äººã§ããæ£ããå®è£
ãå®å¿ããŠéçºããŠãããææ³ã§ãã æ¯éãããã°èšäºïŒã€ã§çè§£ããã€ããã«ãªãããæ¬ãèªãã ããTDDãã³ãºãªã³ãå®éã«äœæããŠãäžèããŠããããã°ãªãšæããŸãã æåŸã« åç°ããã«æè¬ïŒTDDããŒããã£ã³ãã®åºèª¿è¬æŒã®åç»ãšãŠãåèã«ãªããŸããã åç°ããã®åã§ãã¡ãããšãã¹ãæžããŠãŸãïŒãã£ãŠèšããããã«ããã°ããŸãïŒ åèæç®ç ããã¹ãé§åéçºãè Kent Beck èš³ åç°å人 TDD Boot Camp 2020 Online #1 åºèª¿è¬æŒ/ã©ã€ãã³ãŒãã£ã³ã° xUnit Test PatternsããåŠã¶ãŠããããã¹ãã®ïŒã€ã®ç®æãã¹ããŽãŒã« Codinggame.com
ããã«ã¡ã¯ãµãã«ãŒå€§å¥œã@neroblubrosã§ãã ã©ã¯ ã¹ã§ã¯æã«äžåºŠã§ããã宿åŸã«ãã¢ããã·ã¥ãè¡ã£ãŠããŸãã éçºéšéã¯æ±äº¬ãªãã£ã¹ãšå€§éªãªãã£ã¹ã«ããŸãããããããã§ãã¢ããã·ã¥ãéå¬ããŠããŸãã ä»åã¯å€§éªãªãã£ã¹ã§éå¬ããŠãããã¢ããã·ã¥ã«ã€ããŠç޹ä»ããããŸãã ãã¢ããã·ã¥ãšã¯ 6æã¬ããŒã 1人ç®ã瀟äŒäºº1幎ç®ãæ¯ãè¿ããã 2人ç®ã瀟äŒäººïŒå¹Žç®ã®æ¯ãè¿ãã 3人ç®ãããããäºäŸéã 4人ç®ãPHPMDã§ã³ãŒãå質ãèšæž¬ããã 5人ç®ãRSSã§æè»œã«æŽæ°éç¥ã 6人ç®ãChatGPTã§ããã°ãæžããŠã¿ãã 7人ç®ããããããDBèšèšæ¬ããã±!ã 7æã¬ããŒã ããŒãæ ã¯ãæ°åã«äŒãããããšã 4人ç®ãæ°åã®æ¹ã
ã«ãäŒããããããšã 5人ç®ãåãã¡ã¯ã©ãçãããã 6人ç®ãæ°åã«äŒãããããšLTã 7人ç®ãæå¹Žé·ã®ãããã¯ãã«å±
座ãç¶ããæ°åå
¥ç€Ÿã®ãã€ã»ã³ããäŒããã âããã ãã¯ãã£ãŠããâãã 8人ç®ãæ°åã®çããã«ç¥ã£ãŠã»ããïŒãã£ãããã£ãŒã©ãŒéçºèª²ã 9人ç®ãPHPãæ¯ããã³ãã¥ããã£ãã¡ã 次åã®8æãã¢ããã·ã¥ã®äºå ãã¢ããã·ã¥ãšã¯ ãŸãã¯ããã§è»œããã¢ããã·ã¥ã®èª¬æãããŸãããã¢ããã·ã¥ãšã¯ã ã·ãªã³ã³ãã¬ãŒ ãçºç¥¥ã§ ãã¢(beer)ïŒããŒã« ããã·ã¥( bash )ïŒ ã©ãã¡ãã éšã ãçµã¿åãããé èªã§ãããŒã«ãšè»œé£ãé£ã¹ã€ã€ã¢ãŠããããããå Žã§ãã ã©ã¯ ã¹ã®å€§éªãªãã£ã¹ã§ã¯2015幎ããå§ããéäžã³ããçŠã§ã¯éå¬ã§ããªãã£ããšãããªã³ã©ã€ã³ã§éå¬ããŠããŸããããæ¯æç¶ç¶ããŠéå¬ããŠããŸãã ã³ããã5çš®ã«ãªã£ãããšããä»å¹ŽåºŠããã¢ã«ã³ãŒã«ïŒãªãã©ã€ã³ã§ã®éå¬ãåéããŸããã 軜é£ãšã¢ã«ã³ãŒã«ãšãœããããªã³ã¯ãæ¯ãèãããŸããããããã®è²»çšã¯äŒç€Ÿæã¡ã§ãïŒ åºåžã¯èªç±ã§çºè¡šãåºåžããããšäººäºè©äŸ¡ã«ã€ãªãããŸãã 倧éªãªãã£ã¹ã§ã¯å課ã®ä»£è¡šè
ããã¢ããã·ã¥æšé²å§å¡ãæ§æããŠãã¢ããã·ã¥ã®éå¶ããŠããŸãã 以äžã ã©ã¯ ã¹å€§éªãªãã£ã¹ã®ãã¢ããã·ã¥ã®å
容ã§ãã ã¿ããªã§èªãåãã®ã§ã¯ãªããåžæè
ãçºè¡šãããŠèãã質åããã çºè¡šå
容ã¯ããŒãæ ãšèªç±æ ãããã ããŒãæ ã¯æ°å
¥ç€Ÿå¡ã®èªå·±ç޹ä»ããã©ãã«äºäŸãªã© èªç±æ ã¯ITãä»äºã«é¢ããããšãªããªãã§ãOKãä»äºã«é¢ä¿ã®ãªãè¶£å³ã®çºè¡šãšãã¯NG çºè¡šæéã¯ããŒãæ ãšèªç±æ ãšãã«5åïœ10å ãããã倧éªãªãã£ã¹ã§6æãš7æã«éå¬ãããã¢ããã·ã¥ã®å
容ããã£ãšç޹ä»ããŸãã 6æã¬ããŒã 軜é£ã¯ãã¶ïŒãã²ããïŒããããã©ã€ã æåã®3åã¯ããŒãæ ã®ã瀟äŒäºº1幎ç®ã®æ¯ãè¿ããã§ã 1人ç®ã瀟äŒäºº1幎ç®ãæ¯ãè¿ããã 1人ç®ã¯ã瀟äŒäºº1幎ç®ãæ¯ãè¿ãããã§ãã ã³ããçŠã«å
¥ç€Ÿããæ°å3幎ç®ã®çºè¡šã§ãæ°åç ä¿®ãçµããŠãé
å±éšçœ²ã§ã®ç ä¿®ã®è©±ã§ããã ç·æ¥äºæ
宣èšäžã«ç ä¿®ãããããšã®èŠåŽè©±ããããããããšãéã«è¯ãã£ãããšã®çºè¡šã§ããã 2人ç®ã瀟äŒäººïŒå¹Žç®ã®æ¯ãè¿ãã 2人ç®ã¯ã瀟äŒäººïŒå¹Žç®ã®æ¯ãè¿ããã§ãåè·ã§ç€ŸäŒäºº1幎ç®ã«çµéšããããšã®çºè¡šã§ãã ã¹ãã ã¢ããªã®æ©èœè¿œå ã§ææ°çãã€ã³ã¹ããŒã«ãããšèµ·åã§ããªããªãããªãªãŒã¹çŽåŸã«ãŠãŒã¶ããã®ã¯ã¬ãŒã ãæ®ºå°ãããªã©ãããã€ãã®èŠãçµéšãæããªããããªãããã«ãé¢çœããããçºè¡šããŠãããŸããã å人çã«ã¯ æ±æ¥æ¬å€§éçœ ã® èšç»åé» ã§ãããã¢ã®ç
§æãå®æã§æ¶ç¯ãããããããã¹ã¯ã©ã€ããã€ããŠæ®æ¥ããããšãå°è±¡ã«æ®ããŸããã 3人ç®ãããããäºäŸéã 3人ç®ã¯ãããããäºäŸéãã§ã2人ç®ãšåããããªå
容ã§ãããã¿ã€ãã«éããèªåããããããããšãã®çºè¡šã§ãã æ€èšŒç°å¢ã®ã€ãããæ¥ç¶å
ãééããŠæ¬çªç°å¢ã倿Žãã æ¬çªç°å¢ã«ãã¹ãããŒã¿ãç»é²ããŠããŸã£ã ãªã©ãããããäºäŸéãã¯ã€ãºåœ¢åŒã§ã®çºè¡šã§ããã äžè¬¹æ
ã§ãããä»äººã®äžå¹žã¯èã®å³ãšããããšã§ãäžçªçãäžãã£ãçºè¡šãšãªããŸããã æ¬¡ããã¯èªç±æ ã§ãã 4人ç®ãPHPMDã§ã³ãŒãå質ãèšæž¬ããã 4人ç®ã¯ãPHPMDã§ã³ãŒãå質ãèšæž¬ãããã§ãã ãœãŒã¹ã³ãŒã ã®åå²ãç¹°ãè¿ãåŠçãã©ãããããããã衚ããæ°å€ã埪ç°çè€é床ãšããã ãªãŒãã³ãœãŒã¹ ã®éçè§£æããŒã«ã§é
é
ã¡ãŒã«ã®åŸªç°çè€é床ãèšæž¬ããçµæã®çºè¡šã§ããã 5人ç®ã RSS ã§æè»œã«æŽæ°éç¥ã 5人ç®ã¯ã RSS ã§æè»œã«æŽæ°éç¥ãã RSS ã顿ã«ã·ã¹ãã é飿ºã§æ±ãæããã©ãŒããããèããçºè¡šã§ããã 6人ç®ãChatGPTã§ããã°ãæžããŠã¿ãã 6人ç®ã¯ãChatGPTã§ããã°ãæžããŠã¿ããã§ç§ã®çºè¡šã§ãã ChatGPTã䜿ã£ã ã©ã€ããã㯠ã«èå³ãæã£ãŠããŠãChatGPTã䜿ã£ãŠããã°ãæžãæ¹æ³ãçºè¡šããŸããã ããã°ã®èšäºãChatGPTã«çæãããã«ã¯ã©ã®ãããªããã³ãããäœæããã°ãããããå®éã«äœ¿ã£ãããã³ãããšå®æããããã°ãçšããŠèª¬æããŸããã 7人ç®ããããããDBèšèšæ¬ããã±!ã 7人ç®ã¯ããããããDBèšèšæ¬ããã±!ãã§ERDã®æ¬ã®ç޹ä»ã§ã倧éªãªãã£ã¹ã®ãã ã¯ãªãŒã ã«ããçºè¡šã§ãã åãªãæ¬ã®ç޹ä»ã§ã¯ãªããæ¬ã«æžãããŠããæ¹æ³ã§å®éã«é åæžãã€ãã£ãŠããŒãã«èšèšãè¡ããšãããããããã ã¯ãªãŒã ãšããçºè¡šã§ãåå è
ã¯ããªãããªããèããŠããŸããã 6æã¯ããŒãæ ãã瀟äŒäººã1幎ç®ã®æ¯ãè¿ããã§ããããèªç±æ ãå®äœéšã«åºã¥ãããªã¢ãªãã£ã«æº¢ããçºè¡šå
容ã§ããã 7æã¬ããŒã 軜é£ã¯ãµã³ããŠã£ãã(3çš®é¡ããéžæ)ïŒãããã ããŒãæ ã¯ãæ°åã«äŒãããããšã 7æããæ°åã§å
¥ç€Ÿããæ°äººãé
å±ããããããæ°åã®èªå·±ç޹ä»ãšããŒãæ ããæ°åã«äŒãããããšãã§ããã æåã¯æ°åã§å
¥ç€Ÿãã3åã®èªå·±ç޹ä»ã§ããããã工倫ãããããçºè¡šã§ããã 以é4人ç®ããã®çºè¡šã玹ä»ããŸãã 4人ç®ãæ°åã®æ¹ã
ã«ãäŒããããããšã 4人ç®ã¯ãæ°åã®æ¹ã
ã«ãäŒããããããšãã§ç§ã®çºè¡šã§ãã çŸåšã¯éä»»ããŸããããåç· åœ¹ã®ã¡ãŒã«ã玹ä»ããŸããã å
容ã¯ç޹ä»ã§ããŸãããã ã©ã¯ ã¹ã®æåã象城ããã¡ãŒã«ã®å
容ã ã£ãã®ã§æ°åã«çããã«ç޹ä»ããŸããã 5人ç®ã åãã¡ã¯ã©ãçããã ã 5人ç®ã¯ã åãã¡ã¯ã©ãçããã ããšããã¿ã€ãã«ã§ã¡ãã£ãšèº«æ§ããŠããŸãããã§ãããèªåãå®ãä»äºã®ä»æ¹ã®ç޹ä»ã§ãã ãã©ãã¯ãªç°å¢ã§åããŠããçµéšãã ã©ã¯ ã¹ãããã«æµãŸããç°å¢ãããããŠãã®ç°å¢ãçãããŠã楜ããå¥ãããªãšã³ãžãã¢ã©ã€ãããéããæ¹æ³ã®èª¬æã§ã ã©ã¯ ã¹æããµããçºè¡šã§ããã ç§ãçµéšããããŸãããä¿®çŸ
å ŽããããæããŠãã人ã®ã人çã¯é·ããå¿èº«ã®å¥åº·ãäžçªå€§äºãããšããèšèã«éã¿ããããŸãã 6人ç®ãæ°åã«äŒãããããšLTã 6人ç®ã¯ãæ°åã«äŒãããããšLTãã§ãã¿ãªããã¯ããã§ããïŒããšããåãããããä»äºã«å¯Ÿããå§¿å¢ãæ°åå
¥ç€Ÿã«èª¬æã ãããã®ä»äºãšã¯ïŒããšããåãããããããããã§ãã·ã§ãã«ããªä»äºã®ä»æ¹ã«ã€ããŠã®çºè¡šã§ããã 7人ç®ãæå¹Žé·ã®ãããã¯ãã«å±
座ãç¶ããæ°åå
¥ç€Ÿã®ãã€ã»ã³ããäŒããã âããã ãã¯ãã£ãŠããâãã èªå·±ç éœããã£ãŠãããšããåœããåã®ãããªå
容ãããªãå¿
èŠãªã®ãïŒãšãã説æã§ãã ã¡ãŒã«ãã£ãŒã©ãŒéçºã®å®è£
ããŒã ã®ãªãŒãã®çºè¡šã§ã説åŸåããã倧éªãªãã£ã¹ã®ãã ã¯ãªãŒã ããããããããçºè¡šã ã£ãããšç§°è³ã®ããšã°ãããããŸããã 8人ç®ãæ°åã®çããã«ç¥ã£ãŠã»ããïŒãã£ãããã£ãŒã©ãŒéçºèª²ã 8人ç®ã¯ãæ°åã®çããã«ç¥ã£ãŠã»ããïŒãã£ãããã£ãŒã©ãŒéçºèª²ãã§ããã£ãããã£ãŒã©ãŒéçºèª²ããç°åã«ãªãããã£ãããã£ãŒã©ãŒéçºèª²ã®ãããšããã®ç޹ä»ã§ãã ã¿ã€ãã«ããããããããã«ãã£ãããã£ãŒã©ãŒæã«ããµããçºè¡šã§ããã 9人ç®ã PHP ãæ¯ããã³ãã¥ããã£ãã¡ã 9人ç®ã¯ã PHP ãæ¯ããã³ãã¥ããã£ãã¡ããšããããšã§ãã¿ã€ãã«éã PHP ã®æŽå²ãšãã®ã³ãã¥ããã£ã®ç޹ä»ã§ã 7æã®çºè¡šããŒãã¯ãæ°åã«äŒãããããšãã ã£ãã®ã§ãä»äºã«å¯Ÿããããšã èªå·±åçº çãªçºè¡šãå€ãã£ãã§ãã æ¬¡åã®8æãã¢ããã·ã¥ã®äºå 倧éªãªãã£ã¹ã®8æã®ãã¢ããã·ã¥ã®ããŒãã¯ãçŽæ¶ŒïŒ ãã€ãªããã ç¹éãã§ãã æãå€ãå¹ãé£ã°ããããªãã€ãªãšãããšããœãŒããå
±æããããšã§ãåããããªãã¹ãããªãããã«ããå
容ã§ããã æ¬¡åã®ãã¢ããã·ã¥ã¬ããŒãããæ¥œãã¿ã«ããŠãŠãã ããïŒ
ã¯ããã« ããã«ã¡ã¯ akihiyo76 ã§ããå
æ¥ Android 14 Beta 5 ããªãªãŒã¹ãããæçµãªãªãŒã¹ãŸã§ããšå
ããšãªããŸãããããã§ãä»å㯠Android 14 ã§æäŸãããæ°æ©èœã®æŠèŠããŸãšããŠã¿ãŸããã ã¯ããã« æ©èœãš API ã®æŠèŠ åœéåïŒInternationalizationïŒ ã¢ããªåºæã®èšèªèšå® Grammatical Inflection API grammatical gender ã®èšå®æ¹æ³ ãŠãŒã¶ãŒè£æ£ïŒAccessibilityïŒ ãŠãŒã¶ãŒäœéšïŒUser experienceïŒ å
±æã·ãŒãã®ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ã®è¿œå ã¢ããªã¹ãã¢ã®æ¹å ã¹ã¯ãªãŒã³ã·ã§ããã®æ€ç¥ äºæž¬åãæ»ããã¢ããªå
ã¢ãã¡ãŒã·ã§ã³ ãŸãšã åè æ©èœãš API ã®æŠèŠ Android 14 ã®ãæ°æ©èœãš API ã®æŠèŠãã¯ã å
¬åŒããŒãž ã«èšèŒãããŠãããæ¥æ¬èªã®ç¿»èš³ãåŸã
ã«é²ãã§ãããŸããããã¥ã¢ã³ã¹ã埮åŠãªãšãããããã®ã§ãå¯èœã§ããã° è±èªç ã§èªããšããçè§£ãé²ãããšæããŸãã Android 14 ã®æ°æ©èœã倧å¥ãããšã以äžã® 3 ã€ã«åé¡ãããã®ã§ããããããé ã«ç޹ä»ããããšæããŸãã åœéåïŒInternationalizationïŒ ãŠãŒã¶ãŒè£æ£ïŒAccessibilityïŒ ãŠãŒã¶ãŒäœéšïŒUser experienceïŒ API ã®è¿œå ã倿Žãåé€ã®äžèЧã«ã€ããŠã¯ã API å·®åã¬ããŒã ã§ã確èªãã ããããŸããæ°ãã API ã«ã€ããŠã®è©³çްã¯ã Android API ãªãã¡ã¬ã³ã¹ ã§ã確èªãã ããã åœéåïŒInternationalizationïŒ åœéåã®æ°æ©èœãšããŠã¯ã ã¢ããªåºæã®èšèªèšå®ã®èªåå ãš Grammatical Inflection APIïŒææ³çãªèªåœ¢å€åïŒ ã远å ã«ãªããŸãã ã¢ããªåºæã®èšèªèšå® Android 13ïŒ API ã¬ãã« 33ïŒã§å°å
¥ãããã¢ããªå¥ã®èšèªæ©èœãæ¡åŒµããã以äžã®æ©èœã远å ãããŸãã ã¢ããªã® localeConfig ã®èªåçæ ã¢ããªã® localeConfig ã®åçã¢ããããŒã ã€ã³ããã ã¡ãœãã ãšãã£ã¿ïŒ IME ïŒã«ããã¢ããªã®èšèªã®ç¢ºèª Android 14ã§ã¯ãlocales_config. xml ã®çæã以äžã®èšå®ã远å ããããšã§ãèªåçæã«ããããšãå¯èœã«ãªããŸãããèªåçæã«ã¯ã Android Studio Giraffe Canary 7 ããã³ AGP 8.1.0-alpha07 以éãå¿
èŠãšãªã£ãŠããŸãã ïŒ. androidResources > generateLocaleConfig ãå®çŸ©ããã gradle:build.gradle.kts android { androidResources { generateLocaleConfig true } } ïŒ. resources.properties ãäœæããããã©ã«ãã®èšèªãèšå®ããã res/resources.properties unqualifiedResLocale=en-US ãã®ããã«èšå®ããã ãã§ãlocales_config. xml ã®çæãèªåçæã«ããããšãã§ããŸãã Grammatical Inflection API Android 14 ã§ã¯ãæ§å¥ã§ææ³ãå€ããèšèªã«åãããŠãŠãŒã¶ãŒäžå¿ã® UI ãæ§ç¯ãããããã¢ããªã ãªãã¡ã¯ã¿ãªã³ã° ããã«ææ³äžã®æ§å¥ãžã®å¯Ÿå¿ã远å ã§ãã Grammatical Inflection API ãå°å
¥ãããŠããŸãã æ¥æ¬èªã®å Žåãææ³çãªèªåœ¢å€åã¯ãªããªãã€ã¡ãŒãžãã«ãããšæããŸããããã©ã³ã¹èªã§ã®äžäŸã玹ä»ããŸãã ð«ð· å è©ã®æ§å¥ ( è±èª : the ) ç·æ§åœ¢åæ° : le 女æ§åœ¢åæ° : la ð«ð· åè©ã®éå»åè© ( è±èª : spoken ) ç·æ§åœ¢åæ° : parlé 女æ§åœ¢åæ° : parlée Grammatical Inflection API ã§ã¯ããã®ãããªææ³çèšèªå€åã«å¯Ÿå¿ããããšãã§ããŸãã grammatical gender ã®èšå®æ¹æ³ Grammatical Inflection API ã§èšå®ã§ããææ³äžã®æ§å¥ã®èšå®ã¯ä»¥äžã® 3 ãã¿ãŒã³ã«ãªããŸãã Configration. java public static final int GRAMMATICAL_GENDER_NEUTRAL = 1; // äžæ§ç public static final int GRAMMATICAL_GENDER_FEMININE = 2; // 女æ§ç public static final int GRAMMATICAL_GENDER_MASCULINE = 3; // ç·æ§ç ã¢ããªã§ Grammatical Inflection API ãå©çšããã«ã¯ã察象ãšãªã Activity ã« configChanges ã®æå®ããŸãã AndroidManifest. xml <activity android:name=".MainActivity" android:configChanges="grammaticalGender" android:exported="true"> </activity> å®éã« grammatical gender ã GRAMMATICAL_GENDER_FEMININE ã«èšå®ããå Žåã¯ã setRequestedApplicationGrammaticalGender() API ãå©çšããŠèšå®ããŸãã val gIM = context.getSystemService(GrammaticalInflectionManager :: class .java) gIM.setRequestedApplicationGrammaticalGender(Configuration.GRAMMATICAL_GENDER_FEMININE) ãŸããèšå®ããã grammatical gender ãååŸããã«ã¯ã getApplicationGrammaticalGender() API ãå©çšããŸãã val gIM = context.getSystemService(GrammaticalInflectionManager :: class .java) val grammaticalGender = gIM.getApplicationGrammaticalGender() ãã®ããã«èšå®ãã grammatical gender ã«ãã£ãŠã -neuter -feminine -masculine ã® suffix ãä»ãã resources ãã¡ã€ã«ã§ãªãœãŒã¹ã䜿ãåããããšãã§ããããã«ãªããŸãã res/values-fr-neuter/strings. xml <resources> <string name="example_string">Abonnement à ...activé</string> </resources> res/values-fr-feminine/strings. xml <resources> <string name="example_string">Vous êtes abonnée à ...</string> </resources> values-fr-masculine/strings. xml <resources> <string name="example_string">Vous êtes abonné à ...</string> </resources> ãã®ããã« Grammatical Inflection API ã§ã¯ææ³äžã®æ§å¥ã«ãã£ãŠè¡šçŸãå€ããããšãã§ãããããæ§å¥ãæ±ãããšãå€ã SNS ã¢ããªãªã©ã§æŽ»çšã§ããå Žé¢ãããããšæããŸãããããŒã«ã«ã§ã®ãªãœãŒã¹èšå®ã«æ¢ãŸããã䜿ããå Žé¢ã¯éå®çã«ãªãããã§ãã ãŠãŒã¶ãŒè£æ£ïŒAccessibilityïŒ Android 14 ã§ã¯ã éç·åœ¢ ãã©ã³ãã¹ã±ãŒãªã³ã°ã 200% ãŸã§ãµããŒããããŸããSP æå®ã®å Žåã远å ã®ãªãã·ã§ã³ãšã¹ã±ãŒãªã³ã°ã®æ¹åãã¢ããªã®ããã¹ãã«èªåçã«é©çšãããããã«ãªããŸãã ïŒåŒçš: The first developer preview of Android 14 ïŒ ãã®ããã«ã¹ã¿ã³ããŒãã¹ã±ãŒãªã³ã°ã ãšè¡šç€ºåŽ©ããçããããã 200%ã®ãã©ã³ããµã€ãºã§ UI ãã¹ãã§ç¢ºèªããããš ãéèŠãšãªããŸãã 200% ã®ãã©ã³ããµã€ãºãæå¹ã«ããæé ã¯ä»¥äžã®éãã§ãã èšå®ã¢ããªãéãã[ãŠãŒã¶ãŒè£å©] > [衚瀺ãµã€ãºãšããã¹ã] ã«ç§»å] [ãã©ã³ããµã€ãº] ãªãã·ã§ã³ã§ãæå€§ãã©ã³ããµã€ãºã®èšå®ãæå¹ã«ãªããŸã§ããã©ã¹ïŒ+ïŒã¢ã€ã³ã³ãã¿ãã ãŸããã¢ããªã§ sp åäœã䜿çšããŠããå Žåã Android ã¯ãŠãŒã¶ãŒãéžæããããã¹ããµã€ãºãé©çšããŠé©åã«ã¹ã±ãŒãªã³ã°ã§ãããããããã¹ããµã€ãºã¯å¿
ã sp åäœ ã§æå®ããŸãããã ãŠãŒã¶ãŒäœéšïŒUser experienceïŒ ãŠãŒã¶ãŒäœéšã§ã¯ã以äžã®æ©èœã远å ã«ãªããŸããã å
±æã·ãŒãã®ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ã®è¿œå ã¢ããªã¹ãã¢ã®æ¹å ã¹ã¯ãªãŒã³ã·ã§ãã ã®æ€ç¥ äºæž¬åãæ»ããã¢ããªå
ã¢ãã¡ãŒã·ã§ã³ å
±æã·ãŒãã®ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ã®è¿œå å
±æã·ãŒãã®ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ã远å ããã«ã¯ãã«ã¹ã¿ã ChooserAction ãã ChooserActions ã®ãªã¹ããäœæããŸãã MainActivity.kt fun buildCustomShareSheetActions(context: Context): Array<ChooserAction> { val pendingIntent = PendingIntent.getActivity( context, 0, Intent(Intent.ACTION_WEB_SEARCH).apply { putExtra(SearchManager.QUERY, "Search on browser") }, PendingIntent.FLAG_IMMUTABLE ) val actions = mutableListOf<ChooserAction>() for (i in 0 until 5) { val customAction = ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_launcher_foreground), "Action${i+1}", pendingIntent ).build() actions.add(customAction) } return actions.toTypedArray() } 次ã«ãäœæãã ChooserActions ã®ãªã¹ãã Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS ãšããŠæå®ããå
±æã·ãŒããéããŸãã MainActivity.kt fun buildChooserIntent(chooserActions: Array<ChooserAction>): Intent { val intent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, "dummy text") } val chooserIntent = Intent.createChooser(intent, "Android 14").apply { putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, chooserActions) } return chooserIntent } fun showActionSheet() { val chooserActions = buildCustomShareSheetActions(this) val chooserIntent = buildChooserIntent(chooserActions) startActivity(chooserIntent) } ãã®ããã«è€æ°ã®ã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ãèšå®ããããšãã§ããŸãã ã¢ããªã¹ãã¢ã®æ¹å Android 14ã§ã¯ããŠãŒã¶ã®æäœãäžæããã«ã¢ããªã®ã¢ããããŒããå¯èœã«ãªããŸããå
·äœçã«ã¯ãã以äžã®æäœã API ã§å®çŸã§ããããã«ãªããŸãã ããŠã³ããŒãããåã«ã€ã³ã¹ããŒã«ã®æ¿èªããªã¯ ãšã¹ ã ä»åŸã®æŽæ°ã«è²¬ä»»ãç§»è² åœ±é¿ãå°ãªãã¿ã€ãã³ã°ã§ã¢ããªãæŽæ° ã¢ããªã€ã³ã¹ããŒã«æäœã®äºåæ¿èªã§ã¯ãtargetSdk 34 ã§ PackageInstaller ã远å ããã requestUserPreapproval() ãå®è¡ããããšã§ãäºåæ¿èªãè¡ãããšãã§ããŸãã ã¢ããªã¹ãã¢ã®æ¹åæ©èœã¯ãã¹ã ãŒãºãªã¢ããªã€ã³ã¹ããŒã«ãä¿ãããšãæåŸ
ã§ããããããŠãŒã¶ãŒã«ãšã£ãŠãå¬ããæ©èœã«ãªãã§ãããã ã¹ã¯ãªãŒã³ã·ã§ãã ã®æ€ç¥ API level 17 以éã§ã¯ã FLAG_SECURE ãèšå®ããããšã§ ã¹ã¯ãªãŒã³ã·ã§ãã ãç¡å¹ã«ããããšãã§ããŸãããã Android 14 ã§ã¯ ã¹ã¯ãªãŒã³ã·ã§ãã ã®æ€ç¥ãã§ããããã«ãªããŸãã ã¹ã¯ãªãŒã·ã§ããã®æ€ç¥ãããã«ã¯ã DETECT_SCREEN_CAPTURE ã® permission ãå®çŸ©ããŸããDETECT_SCREEN_CAPTURE ã® Protection level 㯠normal ã§ãã AndroidManifest. xml <uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" /> æ€ç¥çšã® Callback 㯠ScreenCaptureCallback ãäœæããŠãã©ã€ããµã€ã¯ã«ã«åãããŠç»é²ã»ç»é²è§£é€ãè¡ããŸãã MainActivity.kt val screenCaptureCallback = ScreenCaptureCallback { // Add logic to take action in your app. } override fun onStart() { super.onStart() registerScreenCaptureCallback(mainExecutor, screenCaptureCallback) } override fun onStop() { super.onStop() unregisterScreenCaptureCallback(screenCaptureCallback) } ãã®ããã« Android 14 ã§ã¯ ã¹ã¯ãªãŒã³ã·ã§ãã ã®æ€ç¥ãéåžžã«ç°¡åã«å®çŸã§ããŸããã¢ããªå
ã§ ã¹ã¯ãªãŒã³ã·ã§ãã ã®æ€ç¥ãããã宿ã«å
±æãããªããããªæ³šæåèµ·ãè¡ãã±ãŒã¹ãªã©ã§æçšããšæããŸãã äºæž¬åãæ»ããã¢ããªå
ã¢ãã¡ãŒã·ã§ã³ ããã¯ã¢ã¯ã·ã§ã³ã«å¯ŸããŠãäºåæ€ç¥ããããšã§ã«ã¹ã¿ã ã¢ãã¡ãŒã·ã§ã³ãªã©ã®åŠçã远å ããããšãå¯èœã«ãªããŸããã @RequiresApi(34) ã§æå®ããŠãã Implement Menbers ã Android 14 ã§è¿œå ã«ãªããŸãã MainFragment.kt val callback = object: OnBackPressedCallback(enabled = false) { @RequiresApi(34) override fun handleOnBackStarted(backEvent: BackEvent) { // Create the transition } @RequiresApi(34) override fun handleOnBackProgressed(backEvent: BackEvent) { // Play the transition as the user swipes back } override fun handleOnBackPressed() { // Finish playing the transition when the user commits back } @RequiresApi(34) override fun handleOnBackCancelled() { // If the user cancels the back gesture, reset the state } } this.requireActivity().onBackPressedDispatcher.addCallback(callback) å®éã«ã¢ãã¡ãŒã·ã§ã³ã远å å®è£
ãµã³ãã«ã¯ å
¬åŒããŒãž ã«ããã®ã§ãå®éã®å®è£
äŸãèŠãŠã¿ããæ¹ã¯ãã¡ããã芧ãã ããã ãŸãšã Android 14 ã®æ°æ©èœæŠèŠã玹ä»ãããŠé ããŸãããã¢ããªã«ãã£ãŠã¯æçšãªæ©èœããããšæãã®ã§ãtargetSdk 34 å¯Ÿå¿æã«åãããŠãã¢ããªã®æ°æ©èœãšããŠæ€èšããŠã¿ãŠã¯ãããã§ããããã åè Features and APIs Overview Android Developers Blog
ã¯ããã« ã¯ãããŸããŠãæ°å1幎ç®ã®TKDSã§ãïŒ å
æ¥ãSpring Bootã®å
¥åå€ãã§ãã¯ã«ã€ããŠè§Šããæ©äŒããã£ããããå
¥åå€ãã§ãã¯ã®äœ¿ãæ¹ã«ã€ããŠèª¿ã¹ãŠãŸããã ä»åã¯ã調ã¹ãå
容ãšç°¡åãªäœ¿ãããã«ã€ããŠã玹ä»ããããšæããŸãã ã¯ããã« å
¥åå€ãã§ã㯠ã¢ãããŒã·ã§ã³ã®å®è·µ ãã¹ããããformã®å
¥åå€ãã§ã㯠ãŸãšã åèæç® å
¥åå€ãã§ã㯠Spring Bootã§ã¯ãå
¥åå€ã®æ€èšŒãè¡ãããã®äŸ¿å©ãªæ©èœãæäŸãããŠããŸãã ããã«ãããå
¥åããŒã¿ãã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ãæºãããŠãããã©ããã確èªã§ããŸãã å
¥åå€ãã§ãã¯ã¯ãã©ãŒã ã¯ã©ã¹ã«ãã§ãã¯ããå
容ã瀺ã ã¢ãããŒã·ã§ã³ ãã€ãããšè¡ããŸãã ãã©ãŒã ã¯ã©ã¹ã«ã€ãã ã¢ãããŒã·ã§ã³ ã«ã¯ããŸããŸãªãã®ããããŸãã äžéšãèšèŒããŸãã ã¢ãããŒã·ã§ã³ ãã§ãã¯å
容 @NotNull Nullã§ãªãã @Max() æå€§å€ä»¥äžã @Min æå°å€ä»¥äžã @Pattern æ£èŠè¡šçŸ ã«äžèŽããã @Size èŠ çŽ æ° ãæå°ä»¥äžãã€æå€§ä»¥äžã§ããã ã¢ãããŒã·ã§ã³ ã®å®è·µ ãµã³ãã«ã¢ããªãçšããŠãå®éã« ã¢ãããŒã·ã§ã³ ãè¡ã£ãŠã¿ãŸãã æ€èšŒçšã«POSTãªã¯ ãšã¹ ããããããš json ãè¿ãã¢ããªãå®çŸ©ããŸãã ãŸã ãã®ãµã³ãã«ã¢ããªã§ã¯å
¥åå€ãã§ãã¯ã¯è¡ãããŠããŸããã ã³ã³ãããŒã©ãŒ // äžéšæç² @PostMapping ( "todo-list/{id}" ) public ResponseEntity<Object> post( @PathVariable Integer id, @RequestBody Todo todo,) { List<Todo> todoList = new ArrayList<>(); todo.setId( 1L ); todo.setUsrName( "test001" ); todoList.add(todo); return ResponseEntity.status(HttpStatus.OK).body(todoList); } ã¬ã¹ãã³ã¹ããã£ãåãåãå
Œè¿ä¿¡çšã¯ã©ã¹ public class Todo { private Long id; private String usrName; private String taskName; @JsonSerialize (using = LocalDateTimeSerializer. class ) @JsonDeserialize (using = LocalDateTimeDeserializer. class ) @JsonFormat (pattern = "yyyy-MM-dd'T'HH:mm:ss" ) private LocalDateTime date; // Getter, Setter, ã³ã³ã¹ãã©ã¯ã¿çç¥ } ãã®ãµã³ãã«ã¢ããªã¯ã¿ã¹ã¯åãšæå»ã JSON ã«å«ããŠãªã¯ ãšã¹ ããéä¿¡ãããšTodoåã®ãªããžã§ã¯ãã«åœãŠã¯ããŠã JSON 圢åŒã§è¿åŽããŸãã ãªã¯ ãšã¹ ãã®éä¿¡ã«ã¯ã VS Code æ¡åŒµã®REST Clientã䜿çšããŠããŸãã ãªã¯ ãšã¹ ã POST http://localhost:8000/todo-app/todo-list/ 1 Content-Type: application/json { " taskName " : " èªæž " , " date " : " 2023-08-02T22:20:00 " } ã¬ã¹ãã³ã¹ HTTP/ 1 . 1 200 Content-Type: application/json Transfer-Encoding: chunked Date: Wed, 02 Aug 2023 15:20:54 GMT Connection: close [ { " id " : 1 , " usrName " : " test001 " , " taskName " : " èªæž " , " date " : " 2023-08-02T22:20:00 " } ] çŸç¶ã®ã³ãŒãã§ã¯ããªããŒã·ã§ã³ãã§ãã¯ããªã«ãè¡ãããŠããªããããNullãªã©ã®å€ãéã£ãŠããã®ãŸãŸãšã©ãŒãã§ãã¯ãããæããŸãã äŸãšããŠãtaskNameããªã¯ ãšã¹ ãããã£ã«å«ãããªã¯ ãšã¹ ããéä¿¡ããŸãã ãªã¯ ãšã¹ ã POST http://localhost:8000/todo-app/todo-list/ 1 Content-Type: application/json { " date " : " 2023-08-02T22:20:00 " } ã¬ã¹ãã³ã¹ HTTP/ 1 . 1 200 Content-Type: application/json Transfer-Encoding: chunked Date: Wed, 02 Aug 2023 15:11:12 GMT Connection: close [ { " id " : 1 , " usrName " : " test001 " , " taskName " : null, " date " : " 2023-08-02T22:20:00 " } ] ãªã¯ ãšã¹ ãã«å«ãŸããŠããªã "taskName" ã null ã«ãªã£ãŠããã®ã確èªã§ããŸãã ã§ã¯ãå
¥åå€ã®ããªããŒã·ã§ã³ãã§ãã¯ãè¡ããtaskNameãæå®ãããŠããªãå Žåã«ãšã©ãŒãè¿ãããã«ããŸãã Todoã¯ã©ã¹ã®taskNameã« @NotNull ã¢ãããŒã·ã§ã³ ãä»ããŸãã @NotNull private String taskName; ããã§ãNullå€ã蚱容ããªãèšå®ã«ããããšãã§ããŸããã æ¬¡ã«ãšã©ãŒãã³ããªã³ã°ãã§ããããã«ããŸãã ã³ã³ãããŒã©ãŒã次ã®ããã«å€æŽããŸãã @PostMapping ( "todo-list/{id}" ) public ResponseEntity<Object> post( @PathVariable Integer id, @RequestBody @Validated Todo todo, BindingResult result) { if (result.hasErrors()) { return new ResponseEntity<Object>( "bad request" , HttpStatus.BAD_REQUEST); } List<Todo> todoList = new ArrayList<>(); todo.setId( 1L ); todo.setUsrName( "test001" ); todoList.add(todo); return ResponseEntity.status(HttpStatus.OK).body(todoList); } åŒæ°ã®éšåã« ã¢ãããŒã·ã§ã³ ã远å ãããšã©ãŒãã³ããªã³ã°ã®åŠçã远å ããŸãã å
ã»ã©ãšåããtaskNameããªããªã¯ ãšã¹ ããéä¿¡ããŸãã çµæã¯æ¬¡ã®éãã§ãã HTTP/ 1 . 1 400 Content-Type: text/plain; charset =UTF-8 Content-Length: 11 Date: Wed, 02 Aug 2023 15:33:01 GMT Connection: close bad request ãšã©ãŒãã³ããªã³ã°ã®éšåã§èšå®ãã bad request ãè¿ã£ãŠããã®ã確èªã§ããŸããã ãã¹ããããformã®å
¥åå€ãã§ã㯠åé
ã§ã¯ãå
¥åå€ãåãåãã¯ã©ã¹ã®ãã£ãŒã«ã倿°ã«å¯ŸããŠç°¡åã«ããªããŒã·ã§ã³ãè¡ãããšãã§ããããšã確èªã§ããŸããã ãããããã©ãŒã ã¯ã©ã¹å
ã«èªäœã¯ã©ã¹ã䜿çšããŠãã£ãŒã«ã倿°ãæã€å ŽåãåŸæ¥ã®æ¹æ³ã ãšããªããŒã·ã§ã³ãã§ãã¯ãæ£åžžã«æ©èœããªãã±ãŒã¹ããããŸãã å
·äœçã«ã¯ããã©ãŒã ã¯ã©ã¹ã®å€æ°èªäœã¯ ã¢ãããŒã·ã§ã³ ã§ãã§ãã¯ã§ãããã®ã®ããã®ãã£ãŒã«ã倿°ãèªäœã¯ã©ã¹ã§ããããã€ç©ºã®é
åãå
¥åãããå Žåãå
¥åå€ã®ãã§ãã¯ãããŸãè¡ãããªãããšããããŸãã å®éã«èŠçŽ ã远å ããŠç¢ºèªããŠã¿ãŸãããã public class Todo { private Long id; private String usrName; @NotNull private String taskName; @JsonSerialize (using = LocalDateTimeSerializer. class ) @JsonDeserialize (using = LocalDateTimeDeserializer. class ) @JsonFormat (pattern = "yyyy-MM-dd'T'HH:mm:ss" ) private LocalDateTime date; // 远å éšå private List<SubTask> subTasks; public static class SubTask { @NotNull private String taskName; // Getter Setter ã³ã³ã¹ãã©ã¯ã¿çç¥ } // Getter Setter ã³ã³ã¹ãã©ã¯ã¿çç¥ ãªã¯ ãšã¹ ã POST http://localhost:8000/todo-app/todo-list/ 1 Content-Type: application/json { " taskName " : "" , " date " : " 2023-08-02T22:20:00 " , " subTasks " : [ {} ] } ã¬ã¹ãã³ã¹ HTTP/ 1 . 1 200 Content-Type: application/json Transfer-Encoding: chunked Date: Sun, 06 Aug 2023 15:34:33 GMT Connection: close [ { " id " : 1 , " usrName " : " test001 " , " taskName " : "" , " date " : " 2023-08-02T22:20:00 " , " subTasks " : [ { " taskName " : null } ] } ] subTaskã®taskNameãæå®ãããŠããªãã«ãããããããããªããŒã·ã§ã³ãšã©ãŒãè¿ã£ãŠããŸããããã®ããšãããSubTaskå
ã®taskNameã«å¯ŸããŠã @NotNull ã¯åããŠããªãããšãããããŸãã ãã®åé¡ã¯ã芪ã¯ã©ã¹ã§ãã£ãŒã«ã倿°ã宣èšããéã«@Valid ã¢ãããŒã·ã§ã³ ãä»äžããããšã§è§£æ±ºã§ããŸãã @Valid private List<SubTask> subTasks; ããã«ããããªããžã§ã¯ãã®ãã£ãŒã«ã倿°ã«å¯ŸããŠã ã¢ãããŒã·ã§ã³ ãã§ãã¯ãè¡ãããããã«ãªããŸãã ãªã¯ ãšã¹ ã POST http: //localhost:8000/todo-app/todo-list/1 Content-Type: application/json { "taskName" : "" , "date" : "2023-08-02T22:20:00" , "subTasks" : [ {} ] } ã¬ã¹ãã³ã¹ HTTP/ 1.1 400 Content-Type: text/plain;charset=UTF- 8 Content-Length: 11 Date : Wed, 02 Aug 2023 15 : 33 : 01 GMT Connection : close bad request ããªããŒã·ã§ã³ãã§ãã¯ãè¡ãããŠããããšã確èªã§ããŸããã ãŸãšã ãã®èšäºã§ã¯ãSpring bootã«ãããå
¥åå€ã®ããªããŒã·ã§ã³ã«ã€ããŠã調ã¹ãŠçµæã玹ä»ããŸããã ãŸãããµã³ãã«ã¢ããªãçšããŠãå
¥åå€ã®ããªããŒã·ã§ã³ãå®è·µããŸããã Spring Bootã®ããªããŒã·ã§ã³ã®çè§£ã®äžå©ã«ãªãã°å¹žãã§ãã åèæç® https://access.redhat.com/documentation/ja-jp/red_hat_jboss_enterprise_application_platform/7.4-beta/html/development_guide/jakarta_bean_validation https://spring.pleiades.io/specifications/platform/10/apidocs/jakarta/validation/package-summary.html https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html https://spring.pleiades.io/specifications/platform/10/apidocs/jakarta/validation/constraints/package-summary.html
ããã«ã¡ã¯ã ã©ã¯ ã¹ ã€ã³ãã©ããŒã æå±ã®as119119ã§ãã ä»åã¯ãã¿ã€ãã«ã®éãããžãã¹ã®å Žé¢ã§éèŠãªã¹ãã«ãšããããŠãã ããžã«ã«ã·ã³ãã³ã° ç ä¿®ãéå¬ããä»¶ã«ã€ããŠåãäžããŠã¿ãããšæããŸãã ä»åã®ããã°æ§æã«ã€ããŠã¯ä»¥äžã®éããšãªããŸãã ããžã«ã«ã·ã³ãã³ã°ãšã¯ ç ä¿®å®æœã®èæ¯ ç ä¿®ã®å
容 ç ä¿®ã宿œããŠã¿ãŠ ããžã«ã«ã·ã³ãã³ã° ãšã¯ äžéã§ããèã ããžã«ã«ã·ã³ãã³ã° ãšã¯ããããã©ã®ãããªãã®ãªã®ã§ããããã æ¥æ¬èªããã®ãŸãŸåœãŠã¯ãããšãè«ççæèããšãªãããã§ãã ãããããè«ççæèããšãã£ãŠãããŸãã«ãæŒ ç¶ãšããŠããŸããã å°ãªããšãå人çã«ã¯ããæããŸãã å··ã«ããµããæ
å ±ã®äžããè«ççæèãšã¯äœããšèª¿ã¹ãŠã¿ããšã æŠã次ã«ãããããªé¡äŒŒã®å®çŸ©ã«ãã©ãçããŸãã ãè«ççæèããšã¯ãã€ãŸããšããçŽæãæèŠçãªãšããã§ç©äºãæããã®ã§ã¯ãªããçéãç«ãŠãŠå
容ã«ççŸãç Žç¶»ããªãããã«çå±ãåãããã«èãã çµè«ãå°ãããšãšããå®çŸ©ã«éçŽã§ãããšæããŸãã ç ä¿®å®æœã®èæ¯ éšçœ²å
ã«ã¯æ°åãäžéãããã©ã³ãªã©å€çš®å€æ§ãªã¡ã³ããŒãããäžã§èª²é¡èšå®ã課é¡è§£æ±ºèœåã«ã°ãã€ãããããã¡ã³ããŒéã®é£æºå
±æãããã¹ã ãŒãºã«å®æœããããã«ã¯ã©ãããã°ããããšããç¹ã«ç«¯ãçºããŠããŸãã ããã§ããžãã¹ãããäžã§éèŠãªã¹ãã«ã§ãã ããžã«ã«ã·ã³ãã³ã° ç ä¿®ãã¡ã³ããŒåãã«å®æœããããšã§ãã¡ã³ããŒéã®ããžãã¹ã¹ãã«ã®åºäžããå³ããšãšãã«ãããŒã å
éšã§å
±éã®ã¹ãã«ã身ã«çããããšã§æ
å ±é£æºåã®åäžã¯å³ãããšããã®ãäž»å¬ã®èæ¯ãšãªããŸãã ãã®æå³ã§ã¯ããã®ãããªã€ã³ãã©ã«é¢é£ããŠããªã詊ã¿ã§ããã£ã¬ã³ãžïŒã¹ã¢ãŒã«ã¹ã¿ãŒããšèšããã§ãããïŒã§ããåå£ããããšããç¹ã¯ ã©ã¯ ã¹ã®åŒ·ã¿ã§ããããšèšããŸãã ç ä¿®ã®å
容 ããŠãäœãç ä¿®ã§æ±ã£ããã«ã€ããŠãããã§ã¯åãäžããŠãããããšæããŸãã ç ä¿®ãšããŠã¯ãæ¥åæéãæå¹ã«æŽ»çšãã€ã€ã1åããã90åãå
š3åã2é±éãã3é±éããã«å®æœãããããã2ãµæä»¥å
ã§å
šå
å®¹ãæ¶åãã圢ãšãªããŸãã æ¯åãç ä¿®äžã«ãã³ãºãªã³åœ¢åŒã®èª²é¡ã«åãçµã¿ã€ã€ãååã®çµäºåŸã次åãŸã§ã«å¿
é 課é¡ããããããåå è
ã«ãšã£ãŠã¯éåžžæ¥åçã
ãããªãã€ã€ããªããªããããŒãªå
容ã§ãã£ããšæããŸãã ã€ã¡ãŒãžããããããã«ãåèãŸã§ã«äœ¿çšããããã¹ãã®ãµã³ãã«ãã玹ä»ããããšæããŸãã ããžã«ã«ã·ã³ãã³ã° ãæ€èšããäžã§ãæ§ã
ãªããŒã«ã䜿çšãããšäŸ¿å©ã§ããããšãããã£ãŠããã®ã§ãç ä¿®ã§ã¯äžè¬çãªããžãã¹æŠå¿µã§ãã MECE ãããžãã¯ããªãŒãªã©ã®ããŒã«ãçšããŠãæ§ã
ã¯ãã³ãºãªã³ã宿œããŸããã ä»åã¯ãããã©ã³ããè¥æãŸã§å€æ§ãªã¡ã³ããŒãåå ããŠããããšãããããã³ãºãªã³ã«ãããæèŠäº€æã¯æŽ»çºã«å®æœããããšãããè¥æã«ãšã£ãŠã¯è²ã
ãªæèŠã«è§Šããããæ©äŒã«ãªã£ãã®ã§ã¯ãªãããšæããŸãã ç ä¿®ã宿œããŠã¿ãŠ ç ä¿®ã ãã¡ã·ãªããŒã¿ãŒ ãšããŠå®æœããã®ãåããŠã§ãç ä¿®ã宿œããããã®æºåã«ã€ããŠããããªãã«å¥ã®ããã©ã³ããæå°ãåããã€ããã§ããããæé管çããã³ãºãªã³ã®ã³ã³ ãããŒã« ãªã©ã¯ãªããªãã¹ã ãŒãºã«ãããªããšãããå€ã
ãããŸããã ããããå
šäœãéããŠã¯å®æœãã䟡å€ã¯ãã£ããšç¢ºä¿¡ããŠããŸãã å®éãåå è
ã«å¯ŸããŠæ¯åãç ä¿®ã®æåŸã«ã¢ã³ã±ãŒããäŸé ŒããŠããã®ã§ãããæŠã奜è©ã§ãä»ã®ãšã³ãžãã¢ã«ãåè¬ãèŠãããšããæèŠãå€ãåºãŠããŸããã ããçšåºŠã å®é åã§ãã广ãåºããã®ã§ã¯ãªãããšæããŠããŸãã ãšããã®ããç ä¿®ã®ææç©ã®äžç°ãšããŠãåå è
ã«ãååŸç¢ºèªã·ãŒãããšåŒã°ãããã®ãç ä¿®åãšç ä¿®åŸã«äœæãäŸé Œãããšãããåœç ä¿®ã§åŠãã ããšã掻çšããŠæ¥åå
ã«ãããå幎å
ãŸã§ã®ç®æšèšå®ã«æŽ»çšããŠããææãèŠåãããããããšãªããŸãã ä»åã ããžã«ã«ã·ã³ãã³ã° ç ä¿®ãå
補åãããããªåœ¢ã§å®æœããããšãèžãŸããæ¯èŒçç¿åŸãããã¹ãã«ãç¥èã¯ããããæ¬¡ç¬¬ã§ã§ããç°å¢ãæŽåãããŠãããšæããŸããã 仿¹ã§æ°åãªã©ã®è¥æãããã©ã³ã®åãéãŠãªãå¿
èŠãªç ä¿®ãæäŸã§ããç¹ã¯ãå人çã«ã貎éãªçµéšãç©ãæ©äŒãšãªã£ãã®ã§ã¯ãšæããŸããã ãããŸã§ç®ãéããŠé ããããããšãããããŸããã
ãŠãŒã¶ãŒã«ããã«ã¹ã¿ãã€ãº åãšå®äœïŒã¯ã©ã¹ãšã€ã³ã¹ã¿ã³ã¹ïŒ Type Object ãã¿ãŒã³ äŸ ç³è«æžã¯ã©ã¹ æ¢å®ã®ç³è«æžã®ã¯ã©ã¹ ã«ã¹ã¿ã ç³è«æžã®ã¯ã©ã¹ã®æ€èš Type Object ãã¿ãŒã³ãé©çš ãŸãšã é¢é£ãããã¶ã€ã³ãã¿ãŒã³ Flyweight ãã¿ãŒã³ Interpreter ãã¿ãŒã³ãCommand ãã¿ãŒã³ åèæç® ãŠãŒã¶ãŒã«ããã«ã¹ã¿ãã€ãº 楜楜粟ç®éçºéšã® id:smdr3s ã§ãã䞻㫠Java ã䜿ã£ããµãŒããŒãµã€ããæ
åœããŠããŸãã åŒç€Ÿã®ãµãŒãã¹ã§ãã æ¥œæ¥œç²Ÿç® ã¯ããã®åã®ãšããçµè²»ç²Ÿç®ã®ãµãŒãã¹ã§ãã 亀éè²»ãåºåŒµè²»ã亀éè²»ãšãã£ãããŸããŸãªçµè²»ãç³è«ã§ããäžåžã çµç æ
åœéšçœ²ã«ããæ¿èªãçµãŠã çµç åŠçã®å®äºãŸã§ããµããŒãããŠããŸãã åºæ¬çã«ã¯çµè²»ç²Ÿç®ã«é¢ããåŠçãäž»ãªæ©èœã§ãããäžèšäžã®ç³è«ïœæ¿èªã®åŠçãããããæ¿èªãããŒãçµè²»ç²Ÿç®ä»¥å€ã®æ¥åã«äœ¿çšããããšãã§ããŸãããã®æ©èœã¯ æ±çšã¯ãŒã¯ãã㌠ãšåŒã°ããã客æ§ïŒç®¡çè
ãŠãŒã¶ãŒïŒãèªç±ã«ç³è«æžã®çš®å¥ãäœæãäžèº«ãã«ã¹ã¿ãã€ãºããæ¿èªãããŒãé¢é£ã¥ããŠããããšãã§ããŸãã äŸãã°çšè°æžãæŒå°ç³è«ãéèŠè³ç£ã¢ã¯ã»ã¹ç³è«ãªã©ãããŸããŸãªçš®å¥ã®ç³è«æžãäœæã§ããŸãã ãããŠïŒäžè¬ãŠãŒã¶ãŒãïŒããããã®çš®å¥ã®ç³è«æžã䜿çšããŠç³è«ãè¡ããèšå®ãããæ¿èªãããŒã«æ²¿ã£ãŠæ¿èªã決è£ãè¡ãããšãã§ããŸãã ãã®ããã«ãããžãã¹ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãŠãŒã¶ãŒãèªç±ã«ã«ã¹ã¿ãã€ãºããé圢ãäœæãããã®é圢ãã倿°ã®æžé¡ãäœæããããšãã£ãèŠæ±ãããããšããããŸãã ç¹ã« B2B ã® SaaS ãããã¯ãã§ã¯ãŠãŒã¶ãŒäŒæ¥ããšã«èŠçšãç°ãªããã®ã®ãåå¥ã«å®è£
ãè¡ãããšã¯ãªãããããŠãŒã¶ãŒèªèº«ãã«ã¹ã¿ãã€ãºãè¡ããæ©èœã®å¿
èŠæ§ã¯é«ãŸããŸãã åãšå®äœïŒã¯ã©ã¹ãš ã€ã³ã¹ã¿ã³ã¹ ïŒ ããŠãå€ãã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ã決ããããåã«æ²¿ã£ãå®äœãçæãããã®å®äœãåŠçããŠããŸãã ã¯ã©ã¹ããŒã¹ã® ãªããžã§ã¯ãæåèšèª ã§æžãããããã°ã©ã äžã§ã¯ãåãã¯ã©ã¹ãå®äœã ã€ã³ã¹ã¿ã³ã¹ ã«ãªããŸãã çµè²»ç²Ÿç®ã¢ããªã±ãŒã·ã§ã³ã§èšãã°ã亀é費粟ç®ç³è«æžããšãããåãã衚ãã¯ã©ã¹ãå®è£
ãããŠãããåã
ã®ç³è«ããšã«ãã®ã¯ã©ã¹ã®å®äœã§ãã ã€ã³ã¹ã¿ã³ã¹ ãäœæïŒ new ïŒããŠåŠçããŸãã äžæ¹ãå
ã»ã©ã®æ±çšã¯ãŒã¯ãããŒæ©èœã§äœæããç³è«æžã®çš®å¥ã®ãããªããŠãŒã¶ãŒãèªç±ã«äœæãããåãã¯ããã®ãŸãŸã¯ã©ã¹ãšããŠå®è£
ããããšã¯ã§ããŸããã ã¯ã©ã¹ã¯å®è£
æã«äœæããå¿
èŠããããŸããããã®ä»æ§ã¯å®è¡æã«ãŠãŒã¶ãŒãæå®ãããŸã§ããããªãããã§ãã Type Object ãã¿ãŒã³ ãã®ãããªå Žåã«åœ¹ç«ã€ã®ã Type Object ãã¿ãŒã³ ã§ãã Type Object ãã¿ãŒã³ã§ã¯ãå®è¡æã«äœæããããåãã®æ
å ±ãããªããžã§ã¯ããã«å
¥ããŠä¿æãããã®ãªããžã§ã¯ããä»ã®ãªããžã§ã¯ãïŒ ã€ã³ã¹ã¿ã³ã¹ ïŒããåç
§ãããããšã§ãåããšããŠã®æ
å ±ãäžããŸããåã®ã¡ã¿æ
å ±ããªããžã§ã¯ãã«ããŠãããšãèšããŸãã äŸ çµè²»ç²Ÿç®ã¢ããªã±ãŒã·ã§ã³ãäŸã«ãType Object ãã¿ãŒã³ã䜿çšããŠã¿ãŸãã ã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ã¯ä»¥äžã®ãšããã§ãã æ¢å®ã§äº€é費粟ç®ãšçµè²»ç²Ÿç®ã®ç³è«æžãäœæã§ããã 亀é費粟ç®ã®ç³è«æžã«ã¯ãè¡å
ã äº€éæ©é¢ ãéé¡ãã®å
¥åé
ç®ãããã çµè²»ç²Ÿç®ã®ç³è«æžã«ã¯ãååãåäŸ¡ãæ°éãéé¡ãã®å
¥åé
ç®ãããã èªç±ã«ç³è«æžã®çš®å¥ã远å ã§ãããïŒã«ã¹ã¿ã ç³è«æžïŒ ã«ã¹ã¿ã ç³è«æžã«ã¯ãç³è«æžåãèšå®ã§ããã ã«ã¹ã¿ã ç³è«æžã«ã¯ãä»»æã®æ°ã®å
¥åé
ç®ã远å ã§ããããããã«é
ç®åãèšå®ããã ç³è«æžã¯ã©ã¹ ãŸãã¯åç³è«æžã®å
±éã®æ§æãæãåºãããããããšã«ç³è«æžã®èŠªã¯ã©ã¹ãäœæããŸãã ç³è«æžåïŒç³è«æžã®çš®å¥ããšã«æ±ºãŸã£ãŠããïŒ è€æ°ã®å
¥åé
ç® é
ç®åïŒç³è«æžã®çš®å¥ããšã«æ±ºãŸã£ãŠããïŒ é
ç®å€ïŒåã
ã®ç³è«æžããšã«å
¥åããïŒ public abstract class Application { private Map<String, Object> fields = new HashMap<>(); // å
¥åé
ç® public abstract String getApplicationName(); // ç³è«æžå public abstract String[] getFieldNames(); // é
ç®åãªã¹ã // é
ç®å€èšå® public void setField(String name, Object value) { if (Arrays.asList(getFieldNames()).contains(name)) { fields.put(name, value); } } // é
ç®å€ååŸ public Object getFieldValue(String name) { return fields.get(name); } } æ¢å®ã®ç³è«æžã®ã¯ã©ã¹ ç³è«æžã®çš®å¥ïŒåããšèãããšãæ¢å®ã®çš®å¥ã®ç³è«æžã§ããã°åã®ä»æ§ã¯ãã§ã«ç¢ºå®ããŠãããããã¯ã©ã¹ãå®è£
ããããšãå¯èœã§ãã 亀é費粟ç®ã¯ã©ã¹ãçµè²»ç²Ÿç®ã¯ã©ã¹ã¯ä»¥äžã®ããã«å®è£
ã§ããŸãã // 亀é費粟ç®ã¯ã©ã¹ public class TransportApplication extends Application { @Override public String getApplicationName() { return "亀é費粟ç®" ; } @Override public String[] getFieldNames() { return new String[] { "è¡å
" , "äº€éæ©é¢" , "éé¡" }; } } // çµè²»ç²Ÿç®ã¯ã©ã¹ public class ExpenseApplication extends Application { @Override public String getApplicationName() { return "çµè²»ç²Ÿç®" ; } @Override public String[] getFieldNames() { return new String[] { "åå" , "å䟡" , "æ°é" , "éé¡" }; } } ãã¡ããããããã®ã¯ã©ã¹ã¯ new ã§ ã€ã³ã¹ã¿ã³ã¹ ãäœæããããšãã§ãããã® ã€ã³ã¹ã¿ã³ã¹ ã¯åœç¶ãã®ã¯ã©ã¹ã®æ
å ±ãæã£ãŠããŸãã public class Main { public static void main(String[] args) { // 亀é費粟ç®ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ãäœæ Application app1 = new TransportApplication(); // 亀é費粟ç®ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ã¯äº€é費粟ç®ã®åã®æ
å ±ãæã€ System.out.println(app1.getApplicationName()); // "亀é費粟ç®" System.out.println(app1.getFieldNames()[ 0 ]); // "è¡å
" // çµè²»ç²Ÿç®ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ãäœæ Application app2 = new ExpenseApplication(); // çµè²»ç²Ÿç®ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ã¯çµè²»ç²Ÿç®ã®åã®æ
å ±ãæã€ System.out.println(app2.getApplicationName()); // "çµè²»ç²Ÿç®" } } ã«ã¹ã¿ã ç³è«æžã®ã¯ã©ã¹ã®æ€è𠿬¡ã«ã«ã¹ã¿ã ç³è«æžã®å®è£
ãè¡ããŸãã åœç¶ãã«ã¹ã¿ã ç³è«æžã¯å®è£
æã«ã¯ç³è«æžã®åã®ä»æ§ã決ãŸã£ãŠããªããããçš®å¥ããšã®å€ãããŒãã³ãŒãããããšã¯ã§ããŸããã // ã«ã¹ã¿ã ç³è«ã¯ã©ã¹ïŒå®è£
äžå¯ïŒ public class CustomApplication extends Application { @Override public String getApplicationName() { return ????; // å®è£
æã«ç³è«æžåã¯äžæ } @Override public String[] getFieldNames() { return ????; // å®è£
æã«ã©ããªé
ç®ããããäžæ } } ç³è«æžã®å®äœçææã«ã«ã¹ã¿ã ç³è«æžã®åã®æ
å ±ãæž¡ããŠçŽæ¥ ã€ã³ã¹ã¿ã³ã¹ ãçæããã®ã¯ã©ãã§ããããã // ã«ã¹ã¿ã ç³è«ã¯ã©ã¹ïŒçŽæ¥çæïŒ public class CustomApplication extends Application { private final String applicationName; // ã«ã¹ã¿ã ç³è«æžã®ç³è«æžå private final String[] fieldNames; // ã«ã¹ã¿ã ç³è«æžã®é
ç®åãªã¹ã // çææã«åã®æ
å ±ãæž¡ã public CustomApplication(String applicationName, String[] fieldNames) { this .applicationName = applicationName; this .fieldNames = filedNames; } @Override public String getApplicationName() { return applicationName; } @Override public String[] getFieldNames() { return fieldNames; } } ããã§ã ã€ã³ã¹ã¿ã³ã¹ ã«ã«ã¹ã¿ã ç³è«æžã®åã®æ
å ±ãæãããããšã¯ã§ããŠããŸãããããã¯åã«ãã«ã¹ã¿ã ç³è«ã¯ã©ã¹ã® ã€ã³ã¹ã¿ã³ã¹ ããäœæããŠããã ãã«ãªã£ãŠããŸãããã® ã€ã³ã¹ã¿ã³ã¹ ãã©ã®ã«ã¹ã¿ã ç³è«æžã®çš®å¥ããããªãã¡ãåãèªäœã®æ
å ±ããªããªã£ãŠããŸã£ãŠããŸãã ïŒãã®äŸã§ã¯ applicationName ã§ã«ã¹ã¿ã ç³è«æžã®çš®å¥ãå€å¥ã§ããå¯èœæ§ããããŸãããããã¯ããŸããŸãããªã£ãŠããã ãã§ãåã®èå¥åãšããŠã¯äžååã§ããïŒ Type Object ãã¿ãŒã³ãé©çš ããã§ãType Object ãã¿ãŒã³ãé©çšããŸãã ãŸãããåãã衚ãã¯ã©ã¹ãäœæããŸããããã§ã¯ã«ã¹ã¿ã ç³è«æžã®çš®å¥ããšã®ãåãã§ãã®ã§ããã®èšå®ãå
¥ããããã¯ã©ã¹ã«ããŸãã // ã«ã¹ã¿ã ç³è«æžã®åã¯ã©ã¹ public class CustomType { private final String applicationName; // ã«ã¹ã¿ã ç³è«æžã®ç³è«æžå private final String[] fieldNames; // ã«ã¹ã¿ã ç³è«æžã®é
ç®åãªã¹ã // çææã«åãšããŠã®æ
å ±ãæž¡ããä¿æãã public CustomType(String applicationName, String[] fieldNames) { this .applicationName = applicationName; this .fieldNames = fieldNames; } public String getApplicationName() { return applicationName; } public String[] getFieldNames() { return fieldNames; } } ãããŠããã®åã¯ã©ã¹ã®ãªããžã§ã¯ããžã®åç
§ãæã€ã«ã¹ã¿ã ç³è«æžã¯ã©ã¹ãäœæããŸãã // ã«ã¹ã¿ã ç³è«æžã¯ã©ã¹ public class CustomApplication extends Application { private final CustomType customType; // åãªããžã§ã¯ããžã®åç
§ãæã€ // çææã«åãªããžã§ã¯ããæž¡ããåãæããã public CustomApplication(CustomType customType) { this .customType = customType; } @Override public String getApplicationName() { return customType.getApplicationName(); } @Override public String[] getFieldNames() { return customType.getFieldNames(); } } åºæ¬çãªã¯ã©ã¹ã®æºåã¯ä»¥äžã§ããå®éã«ã«ã¹ã¿ã ç³è«æžã®çš®å¥ãäœæãããã®ç³è«æžã® ã€ã³ã¹ã¿ã³ã¹ ãäœæããŠã¿ãŸãã public class Main { public static void main(String[] args) { // ã«ã¹ã¿ã ç³è«æžã®çš®å¥ãçšè°æžããäœæ CustomType proposal = new CustomType( "çšè°æž" , new String[] { "ä»¶å" , "å
容" }); // çšè°æžã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ãäœæ CustomApplication app1 = new CustomApplication(proposal); // çšè°æžã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ã¯çšè°æžã®åã®æ
å ±ãæã€ System.out.println(app1.getApplicationName()); // "çšè°æž" System.out.println(app1.getFieldNames()[ 0 ]); // "ä»¶å" // åãçš®å¥ã®è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãäœæå¯èœ CustomApplication app2 = new CustomApplication(proposal); // å¥ã®çš®å¥ãæŒå°ç³è«ããäœæå¯èœ CustomType stamp = new CustomType( "æŒå°ç³è«" , new String[] { "æžé¡çš®å¥" , "çžææ¹ç€Ÿå" }); // æŒå°ç³è«ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ãäœæ CustomApplication app3 = new CustomApplication(stamp); // æŒå°ç³è«ã®ç³è«æžã€ã³ã¹ã¿ã³ã¹ã¯æŒå°ç³è«ã®åã®æ
å ±ãæã€ System.out.println(app3.getApplicationName()); // "æŒå°ç³è«" } } CustomType ã® ã€ã³ã¹ã¿ã³ã¹ ã«æ³šç®ããŠãã ããã ããããåã衚ããªããžã§ã¯ã Type Object ãšã㊠CustomApplication ã® ã€ã³ã¹ã¿ã³ã¹ ã«ã«ã¹ã¿ã ç³è«æžã®çš®å¥ãšãããåããäžããŠããŸãã ããã«ãã CustomApplication ã® ã€ã³ã¹ã¿ã³ã¹ ã¯äžããããåã®æ
å ±ãæã€ããã«ãªã£ãŠããŸãã åã衚ããªããžã§ã¯ãã§ãã CustomType ã® ã€ã³ã¹ã¿ã³ã¹ ã¯äœ¿ãåããå¯èœã§ãã ïŒãããåãåã§ããã° CustomType ã® ã€ã³ã¹ã¿ã³ã¹ ã¯åäžã§ããããšãæãŸããã§ããã·ã¹ãã å
šäœã§ãŠããŒã¯ãšãªããã管çãå¿
èŠã§ããïŒ ãã®ã³ãŒãã§ã¯èª¬æã®ãã CustomApplication ã® ã€ã³ã¹ã¿ã³ã¹ ã CustomApplication ãšããŠæ±ã£ãŠããŸããããã¡ãã芪ã¯ã©ã¹ã§ãã Application ãšããŠæ±ãããšãã§ããŸããããããã°ã«ã¹ã¿ã ç³è«æžã®åçš®å¥ããæ¢å®ã®ç³è«æžãåäžã®ã€ã³ã¿ãŒãã§ãŒã¹ã§æ±ãããšãã§ãã ããªã¢ãŒãã£ãºã ãæããŸãã ãŸãšã Type Object ãã¿ãŒã³ ã䜿çšãããšãå®è¡æã«åçã«åãäœæãããã®åã®ãªããšã¯ããäœæããããšãã§ããŸãã äœæããåã¯äžè¬çãªãªããžã§ã¯ãã§ãã®ã§å®¹æã«ç®¡çãåå©çšãå¯èœã§ãã ã¢ããªã±ãŒã·ã§ã³ã«åçã«ã²ãªåœ¢ãäœæããã«ã¹ã¿ãã€ãºæ§ãæ±ãããããšãã«ã¯ãObject Typeãã¿ãŒã³ã§å管çãå°å
¥ã§ããªããããã²æ€èšããŠã¿ãŠãã ããã é¢é£ãã ãã¶ã€ã³ãã¿ãŒã³ Flyweight ãã¿ãŒã³ å
±éã® ã€ã³ã¹ã¿ã³ã¹ ãä»ã®ã¯ã©ã¹ã®è€æ°ã® ã€ã³ã¹ã¿ã³ã¹ ããåç
§ãããšããç¹ã¯ Flyweight ãã¿ãŒã³ãšå
±éã§ãã ãŸããåãªããžã§ã¯ããåããšã«ã·ã³ã°ã«ãã³ã«ããéã« Flyweight ãã¿ãŒã³ã®å®è£
ãåèã«ãªããããããŸããã Interpreter ãã¿ãŒã³ãCommand ãã¿ãŒã³ åããšã«ã¯ã©ã¹ãå®è£
ããéã«ã¯å®è£
ã¯ã©ã¹ããšã«ã¡ãœããã«èªç±ã«ããžãã¯ãèšè¿°ããããšãã§ããŸãããType Object ãã¿ãŒã³ã§ã¯åå¥ã«ã¡ãœãããèšè¿°ããããšã¯ã§ããªããããåãªããžã§ã¯ãããšã«ããžãã¯ãã«ã¹ã¿ãã€ãºããããšã¯ã§ããŸããã åãªããžã§ã¯ããäœæããéã«èšå®ã§ããæ
å ±ã¯ã³ã³ã¹ã ã©ã¯ ã¿ã¡ãœããã«æž¡ãããããªç¬¬äžçŽãªããžã§ã¯ãã«éãããŸãã®ã§ãåããšã«ããžãã¯ãå€ãããå Žå㯠Interpreter ãã¿ãŒã³ã Command ãã¿ãŒã³ãªã©ãšçµã¿åãããã®ãæå¹ã§ãã åèæç® Nystorm, Robert. Game Programming Patterns. Genever Benning, 2014, 354p. https://gameprogrammingpatterns.com/ Johnson, Ralph; Woolf, Bobby. "The Type Object Pattern". 1996. http://www.cs.ox.ac.uk/people/jeremy.gibbons/dpa/typeobject.pdf Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. ãªããžã§ã¯ãæå ã«ãããåå©çšã®ããã® ãã¶ã€ã³ãã¿ãŒã³ ïŒæ¹èšçïŒ. åç°åæš¹, æ¬äœç°çäžç£ä¿®. SBã¯ãªãšã€ãã£ã , 1999, 418p.
ããã«ã¡ã¯ãneige_ gnome ã§ãã ãã©ã€ããŒãã§ã¯ïŒå
ã®æ¯ã§ãåã©ãã«èªå®
ã®å£ãããã³ãã³ã«ãããŠããŸãã äŒç€Ÿã§ã¯éçºç®¡ç課ãšããéšçœ²ã§ãPSIRT(â»)ã®ãããªããšããã£ãŠãŸãã éçºç®¡ç課ã¯ãéçºéšã®äžã®ïŒéšçœ²ã§ãããšã³ãžãã¢ãåããããç°å¢ãæäŸããææã®æå€§åã«è²¢ç®ããããMissionã«ãåœç€Ÿã®æäŸãããµãŒãã¹éçºã«ãããã»ãã¥ãªãã£ã»å質é¢ã®ãµããŒããè¡ã£ãŠããéšçœ²ã§ãã ä»åã¯ã ã©ã¯ ã¹ã«ããããããã¯ãã»ãã¥ãªãã£å¯Ÿçã«ã€ããŠãç§ãã¡ã®æŽ»åå
容 ããã§ã³ã£ãšã ãã玹ä»ããŸãã â»PSIRTãšã¯ïŒè£œå(Product)ã¬ãã«ã®ã»ãã¥ãªãã£æ
åœè
ã®ããšãæå³ããŸãã ãäŒç€Ÿã¬ãã«ã®ã»ãã¥ãªãã£æ
åœã§ããCSIRTãããã¹ã³ãŒããéçºå¯ããªåã ãéçºã«ç¹åããã»ãã¥ãªãã£å¯Ÿçãè¡ã人ãšã€ã¡ãŒãžããã ããã°ãšæããŸãã ã¯ããã« åæèª¬æ ã»ã©ã¯ã¹ã®çµç¹äœå¶ãçŽ¹ä» ã»OSSãšã¯ æ¬é¡ â ã©ã€ã»ã³ã¹ãã§ãã¯ã®ãªããïŒ â¡è匱æ§ãã§ãã¯ã®ãªããïŒ â¢EOLãã§ãã¯ã®ãªããïŒ ä»åŸã®èª²é¡ 課é¡ãã®ïŒïŒäººå察å¿ãå€ã 課é¡ãã®ïŒïŒã¹ããŒã¯ãã«ããå¯å€åŒ 課é¡ãã®ïŒïŒãŠã©ãããã¹ãæè¡é åãåºãããã ãããã« ã¯ããã« æšä»ãæ®å¿µãªããšã« ãã«ãŠã§ã¢ ããã£ãã·ã³ã°è¢«å®³ã®ã€ã³ã·ãã³ããã¥ãŒã¹ãèããªãæ¥ã¯ãããŸããã èªç€Ÿãµã€ãã ãã«ãŠã§ã¢ ã®çºä¿¡æºã«ãããŠããããšãã話ãèããŸãã ãããªç¶æ³ã®äžã§ãç§ãã¡ã¯æ»æè
ãã¡ããã©ã®ããã«èªç€Ÿãå®ãã°è¯ãã®ã§ããããã ä»åã¯æã
(以äžãPSIRTæ
åœãšèšèŒ)ã®ã³ãããã¡ã³ãã倧ããã OSS ã® èåŒ±æ§ ãEOLãã©ã€ã»ã³ã¹ã®ãã§ãã¯ãã«çµã£ãŠ ã©ã¯ ã¹ã®äºäŸãã玹ä»ããŸãã åæèª¬æ æ¬é¡ã®åã«ïŒç¹ã ã©ã¯ ã¹ã®çµç¹äœå¶ãšã OSS ã«ã€ããŠèª¬æãå
¥ããããŠé ããŸãã äœãã£ãŠããã ãç¥ããã人ã¯é£ã°ããŠãæ¬é¡ããèŠãŠãã ãããïŒ ã» ã©ã¯ ã¹ã®çµç¹äœå¶ãçŽ¹ä» åœç€Ÿã¯äŒæ¥ã®æé·ãæ¯æŽããITãµãŒãã¹ãæäŸããäŒç€ŸãšããŠãããã¯ãªãã£ã¹ç³»ã® SaaS ãµãŒãã¹ãå±éããŠããŸãã ããŠåé¡ã§ããåœç€Ÿãå
¬éããŠãã SaaS ãµãŒãã¹ã®æ°ããåãã§ããããã æ¥œæ¥œç²Ÿç®ã楜楜æçްãããã¯TV CMã埡芧ã«ãªã£ãæ¹ãå±
ããšæããŸãããä»ã«ã沢山ãããã§ãã ãŸããå
¬éããŠãããµãŒãã¹ã ãã§ã¯ãªããããè¯ããµãŒãã¹ãäžã«åºãããã«æ¥ã
ç ç©¶ãéçºãéããŠããŸãã 詳ããã¯ã³ãã©â クラウド事業 | 株式会社ラクス ãããŠãããã® SaaS ãµãŒãã¹ãéçºããã«ã¯ãããã°ã©ã èšèªãã¯ãããšããéçºç¥èã ãã§ã¯ãªã é¢é£æ³ãã察象補åã«å¯Ÿããæ·±ãçè§£ãå¿
èŠã«ãªããŸãã ãã®ããã ã©ã¯ ã¹ã§ã¯ãµãŒãã¹ããšã«å°éã®éçºéšéãååšããŸãã ãããïŒãã¹ãã»ãªãã»ããªãŒãã§éçºãé²ããæ¹éã®éœåäžã åãµãŒãã¹ã«æé©ãªæè¡ãåãå
¥ããŠããããããµãŒãã¹éã§ã·ã¹ãã æ§æãç°ãªããŸãã ç§ãã¡PSIRTæ
åœã¯ãããã£ãã人ãã·ã¹ãã æ§æãç°ãªãå
šãµãŒãã¹éçºæ
åœè
ã«åããŠã 暪æçã«ã»ãã¥ãªãã£ãã©ã€ã»ã³ã¹ã®æ¹éãäœã£ãããæ¹éé©çšã®ãµããŒããããŠããŸãã äœå¶å³ ã» OSS ãšã¯ OSS ã¯äžè¬å
¬éãããŠããããã°ã©ã ã®ããšãèšããŸãã ãµãŒãã¹éçºãå®¶ã®å»ºç¯ã«äŸãããªãã OSS ã¯æŽé¢å°ããŒãããã€ã¬ããŒãã®ãããªãã®ã§ãã ããŒããæã£ãŠããŠçµã¿èŸŒãããšã§ããã€ã¬ãèªåã§ïŒããäœãããããé¥ãã«å¹ççã«å®¶ãäœãããšãåºæ¥ãŸãããã ããã°ã©ã ãåãã§ãã ãããæåã®æŽé¢å°ããã€ã¬ãšã¯éãã OSS ã¯ç¹å®ã®æ¡ä»¶ã®åºã§ããã°ç¡åã§å©çšã§ããã±ãŒã¹ãããããšãç¹åŸŽã§ããåãã§ãããã ãããªçŽ æµãª OSS ã§ãããåæã§å
¬éãããŠããæ§è³ªäžãéçºã®é²ã¿ãé
ãã£ããã EOL(=éçºãã¹ããã) ããå¯èœæ§ããããŸãã é
·ãã±ãŒã¹ã ãšãæããã«å€§ã㪠èåŒ±æ§ (=ã»ãã¥ãªãã£çãªäžå
·å) ããã£ãŠããæŸçœ®ããç¶ããå ŽåããããŸãã æŽã«ãæ¯æ¥æ°ãããã¿ãŒã³ã® èåŒ±æ§ ãçºèŠãããŠãããããã㟠èåŒ±æ§ ã®ç¡ã OSS ã§ãææ¥ã«ã¯ã©ããªããåãããŸããã ãããã£ãæ°ãã èåŒ±æ§ ãæã€ OSS ããEOLãã OSS ã¯ã¯ã©ãã«ãŒãã¡ã®æ Œå¥œã®æ»æã¿ãŒã²ããã«ãªããŸãã ã€ãŸãã OSS ãå®å¿ããŠäœ¿ãç¶ããã«ã¯ã OSS ãEOLããã èåŒ±æ§ ãçºçããŠããªããããã³ã³ã¹ã¿ã³ãã«ãã§ãã¯ããŠå¯Ÿå¿ããåãå¿
èŠã«ãªãã®ã§ãã å¿è«ã ã©ã¯ ã¹ã§ãæ°çŸã«ãäžã OSS ãå©çšããŠããŸãã®ã§ãç¶ç¶çã«ç£èŠã»å¯Ÿå¿ããŠããŸãã ãªãã OSS ã¯"ç¹å®ã®æ¡ä»¶ã®åºã§ããã°"ç¡åã§å©çšã§ãããšæžããŸãããã ãã®"ç¹å®ã®æ¡ä»¶"ãšããã®ãã"ã©ã€ã»ã³ã¹ãšå©çšæ¡ä»¶"ã§ãã ç¹ã« ã©ã€ã»ã³ã¹ ã¯ãããããã©ã€ã»ã³ã¹ã ãã§ã600以äžã®çš®é¡ããããããããã§ã©ããªå©ç𿹿³ãOK/NGãªã®ããç°ãªããŸãã ç¬èªã®ã©ã€ã»ã³ã¹ãæã€ OSS ãå€ãããã䜿ããã OSS ãæ¬åœã«äœ¿ããã®ãã確å®ã«ãã§ãã¯ããããšãéèŠã§ãã ã©ã¯ ã¹ã§ã¯ãNGãªå©ç𿹿³ãããªããããPSIRTæ
åœããã§ãã¯ããŠããŸãã æ¬é¡ ããŠããã§ã¯ã ã©ã¯ ã¹ã«ããã OSS ã®ã©ã€ã»ã³ã¹ã èåŒ±æ§ ãEOLã®ãã§ãã¯ã®ãªãããã玹ä»ããŸãã äž»ãªç»å Žäººç©ã¯ãPSIRTæ
åœãšãµãŒãã¹éçºæ
åœã®ïŒè
ã§ãã â ã©ã€ã»ã³ã¹ãã§ãã¯ã®ãªããïŒ ã©ã€ã»ã³ã¹ãã§ãã¯ãã㌠ãµãŒãã¹éçºæ
åœãå©çš OSS æ
å ±ãPSIRTæ
åœã«å
±æãâãPSIRTæ
åœãã©ã€ã»ã³ã¹ãã§ãã¯ãâããµãŒãã¹éçºæ
åœãžãã£ãŒããã㯠ãšãªã£ãŠããŸãã æ°åºãã¿ãŒã³ã®ã©ã€ã»ã³ã¹ãåºãŠããå Žåã¯ããã®ãããŒã«æ³åæ
åœéšçœ²ãå ãããPSIRTæ
åœãšèªèãããããããŸãã â¡ èåŒ±æ§ ãã§ãã¯ã®ãªããïŒ èåŒ±æ§ ãã§ãã¯ãã㌠(â ã§PSIRTæ
åœãå©çš OSS ãææ¡)ãâãPSIRTæ
åœãæ
å ±åéã»ãµãŒãã¹éçºæ
åœãžéç¥ãâããµãŒãã¹éçºæ
åœã«ãŠåœ±é¿ç¢ºèªã»å¯Ÿå¿ã»æ
å ±å
±æ ãšãªã£ãŠããŸãã ãµãŒãã¹éçºæ
åœã¯ãå¯Ÿå¿æ¹éãæ±ºãããéçºã»PSIRTæ
åœå
šäœã«å
±æããŸããã ãã®é ãå¯Ÿå¿æ¹éãæ±ºããã®ã¯éç¥ããæé
ã§ãXæé以å
ã ã¯ãªãã£ã«ã«ãª èåŒ±æ§ ããã£ãå Žåã« OSS ã®ã¢ããããŒããé©çšãã補åããªãªãŒã¹ããã®ã¯Xæ¥ä»¥å
ã ãšãã ã©ã¯ ã¹ç¬èªã®ã«ãŒã«ã«åŸããŸãã现ããæ°åã¯ã»ãã¥ãªãã£ã«åœ±é¿ããããèšããŸãããã Xã«å
¥ãæ°åã¯çžåœçãããšã ãæžãããŠé ããŸãã(ãµãŒãã¹éçºæ
åœè
ã®æè¡åã䌺ããŸããã) ãªãPSIRTæ
åœã®æ
å ±åéæºã¯å€å²ã«ããããŸãã åçšããŒã«ã ãã§ãªãã èåŒ±æ§ ã®äžèЧãµã€ã(NVD, JVN )ã Apache ãªã©ãã³ããŒã®ãµã€ãã RSSãã£ãŒã ããçŽæ¥æŸãããšããããŸãã ããŒã«ãå©çšããŠããŸãããæ©æ¢°ãã§ãã¯ã§ã¯èª€æ€ç¥ãå€ãããã人ã®ç®ã§ããçšåºŠãã£ã«ã¿ãªã³ã°ããåŸã«ãµãŒãã¹éçºæ
åœãžéç¥ããããã«ããŠããŸãã (å®ã¯ãã®éšåã«ãPSIRTæ
åœã»ãµãŒãã¹éçºæ
åœã®åæ¹ãå°ãåãŸã§å€å€§ãª å·¥æ° ããããŠããŸããã ãããå
æ¥èªååããå¹Žéæ°çŸæéã® å·¥æ° åæžã«æåããŸããâ
ãã®ã話ã¯ãŸãåŸæ¥ã) â¢EOLãã§ãã¯ã®ãªããïŒ èåŒ±æ§ ãã§ãã¯ãšåãã§ãã®ã§ãå³ã¯å²æãããŠããã ããŸãã PSIRTæ
åœãEOLã®æ
å ±åéãããäžã§ããªãããŒãªãã€ã³ãããããŸãã å®ã¯EOLäºå®ãšãããã®ã¯ã OSS ã®å
¬éããŒãžã«çŽæ¥èšèŒãããŠãããã®ããäžåæžãããŠããªããã®ãŸã§ãæ§ã
ã§ãã ããã§ã ã©ã¯ ã¹ã§ã¯ç¬èªã«ãX幎以äžéçºãã¹ãããããŠãã OSS ã¯EOLãšèŠåãããšããåºæºãèšããŠã EOLäºå®ãè¿ã OSS ã宿çã«ãªã¹ãã¢ãããéçºãžéç¥ããŠããŸãã ãµãŒãã¹éçºæ
åœã¯ãEOLãæ¥ãææãèŠæ®ããŠå¥ã® OSS ã«ä¹ãæããããå°ããæ©èœã§ããã°èªç€Ÿéçºãããªã©ããŠåããŸãã 以äžãã ã©ã¯ ã¹ã«ããã OSS ã®ã©ã€ã»ã³ã¹ã èåŒ±æ§ ãEOLã®ãã§ãã¯äœå¶ã§ãã ã¡ãªã¿ã«äžèšïŒã€ã®äœå¶ã«ãããŠãåœç€Ÿã§ã¯æ
å ±å
±æã«åœç€Ÿè£œåãæ¥œæ¥œè²©å£²ããå©çšããŠããŸãã æ¥œæ¥œè²©å£²ã¯ API 察å¿ãããŒã³ãŒãã§è²ã
ãªåŠçãèªååã§ããŠãæ¿èªããã»ã¹ãã±ã¢ã§ãã䟿å©ãªããŒã«ã§ãã ãå©çšã»ãæ€èšé ããŠãã客æ§ãž CRM 以å€ã«ããæŽ»çšé ããŸããããšããããšã§ã玹ä»ãããŠããã ããŸããã ä»åŸã®èª²é¡ ãããŸã§ãåœç€Ÿã®ã©ã€ã»ã³ã¹ã» èåŒ±æ§ ã»EOL管çã«ã€ããŠã玹ä»ããŠããŸãããã æã
ãPSIRTæ
åœãšããŠä»ç€Ÿã®äŸã«æŒããã課é¡ãæ±ããŠããŸãã å人çã«å€§ãããšæã£ãŠãã課é¡ãïŒç¹ãæããŠã¿ãŸããã 課é¡ãã®ïŒïŒäººå察å¿ãå€ã æäžã«ãè¥å¹²èšèŒããéããèªååã¯é©å®é²ããŠããŸãã ãŸã ãŸã æåã®ç®æãå€ããPSIRTæ
åœãšããŠçç£çãªæŽ»åã«å»»ãããªãœãŒã¹ãå°ãªãç¶æ³ã§ãã ãã®ãããåè³ªã¯æ
ä¿ãããŸãŸãããŒã«ãªã©ã掻çšãã©ã€ã»ã³ã¹ãã§ãã¯ïœ èåŒ±æ§ æ€ç¥ãããŒã¿ã«ã§å¹çåã§ããªããæ€èšäžã§ãã 課é¡ãã®ïŒïŒã¹ããŒã¯ãã«ããå¯å€åŒ ã»ãã¥ãªãã£ã«ãŒã«ã®çå®ã»å€æŽã«å¯ŸããŠã10以äžã®é¢é£çµç¹(ç·å¢300åïœ)ã«100%ã³ã³ã»ã³ãµã¹ãåŸãã®ã¯ç¡çã§ãã ããšãã£ãŠéçšãšã®ä¹é¢ã¯åºããããªãã®ã§ãããçšåºŠã¯ããŽããããšããã§ãã ããããªãããèŠä»¶æ¬¡ç¬¬ã§ã©ã®çµç¹ã®èª°ã«èšãã°æ
å ±ãããã®ã/èª°ã«æ¿èªè²°ãã°è¯ãããå€ããããã ãããããªçŸå Žã§çžç°ãªããæèŠãããã ããå Žåã¯ãæ¹éãåãçºããã®ã«èŠåŽããããšããããŸãã (ãããã£ãéãçŽã£ãŠãåããç¯å²ã§èª¿æŽããäžã§ãµããµãšã«ãŒã«ãå
šäœåšç¥ããŠããŸãã ææãåããã°å³æ¯æ£ããæ¹ãåœç€Ÿã®å€åã®ã¹ããŒãæã«åã£ãŠããããã»ã»ãšæã£ãŠããŸãã) 課é¡ãã®ïŒïŒãŠã©ãããã¹ãæè¡é åãåºãããã ãã®æã
ã§çæ³ãšãããã·ã¹ãã æ§æãäžéã®ããŒãºã«è¿œéããããã ã©ã¯ ã¹ã®ãµãŒãã¹ã§æ±ãæè¡é åã¯æ¥ã
åºãã£ãŠããŸãã å€ãè¯ããªã³ãã¬ã® ãã¡ã€ã«ã·ã¹ãã ã ã¯ã©ãŠã ãã¢ãã€ã«ã¢ããªãDockerãšãã»ãã¥ãªãã£é¢ã§ã«ããŒãã¹ãç¯å²ããã®éœåºŠåºãã£ãŠããŸããã åæè¡ã«å
±éããã»ãã¥ãªãã£ã«ãŒã«ã¯å€ããã®ã®ãæ°æè¡ç¬èªã®ã«ãŒã«ãæŽåããŠããå¿
èŠããããŸãã ãã ãæ°ããã«ãŒã«ãäœããšããŠããããã§ãã¯ã§ããäœå¶ãæ·ããã°ãªããŸããã ãã®äžæ¹ã§ãæ°æè¡ã®ç¢ºç«ã§é³è
åããŠããŸã£ãã«ãŒã«ãããã°ãæ©æ¥ã«æ¹åããå¿
èŠããããŸãã ãããã£ãæè¡ãã¬ã³ãã®å€åã«å
šãŠãªã³ã¿ã€ã ã§ã«ãŒã«ãæŽåããã®ã¯å³ãããã®ããããŸãã ç¹ã«ã倿°ã®ãµãŒãã¹éçºè
ã«ã³ã³ã»ã³ãµã¹ãåŸãå Žåã¯äœèšã«æéãããããŸãã åªå
åºŠãæ±ºããŠé 次察å¿ããŠããŸããããããŸã§ã¯åå¥ã«ååããé£çµ¡å¯Ÿå¿ãããå¿
èŠããããµãŒãã¹éçºæ
åœã®æ¹ã«ç³ãèš³ãªãæã£ãŠããŸãã çæç³»AIãšå°ãã®ã³ãŒãã£ã³ã°ã§ããããã£ãã«ãŒã«ã®ã¢ããããŒãã ããŽã·ãšãŒã·ã§ã³ ã 倧å¹
ã«èªååã§ããã®ã§ã¯ãªãããšåŠæ³ã¯ããŠããŸãããä»ã¯ãŸã ãæãåºããŠããŸããã ãããã« ã»ãã¥ãªãã£å¯Ÿçã¯ããµãŒãã¹éçºå¹çãšã® ãã¬ãŒããªã ã®åŽé¢ããããŸãã ããéããçµæãéçºå¹çããµãŒãã¹ã¬ãã«ãäžããŠããŸãã®ã¯å¯èœãªéãé¿ããã¹ãã§ãã ãšã¯ããã ã»ãã¥ãªãã£ã€ã³ã·ãã³ã ã®ãã¥ãŒã¹ã¯å¢ããäžæ¹ã§ãã®ã§ãMAXã«èŠæããå¿
èŠããããŸãã ãããèžãŸããŠãç§ãã¡éçºç®¡ç課ã¯ããµãŒãã¹éçºæ
åœãšã®æ
å ±å
±æãå¯ã«è¡ããææµãšäºæ¥èŠæš¡ã«åã£ãæšæºå/æ¹éçå®ãããããšã§ãèªç€Ÿã«æé©ãªã»ãã¥ãªãã£åŒ·åãå³ã£ãŠãããããšæã£ãŠããŸãã ãšãçé¢ç®ãªããšãã€ãã€ããšæžããŸããããçŸå Žã§ã¯æ¯æ¥ãåæ°ãããããšæ¹åã«åããŠåãçµãã§ããŸãã ç¹ã«ã倱æããã£ãŠã蚱容ããŠããã瀟颚ã®ãé°ã§æ°æ¥œã«ãã©ã€&ãšã©ãŒãåºæ¥ãŠå©ãã£ãŠããŸãã ãã£ã¬ã³ãžãšãåããšå匷ã奜ããªæ¹ããã€ã§ããåŸ
ã¡ããŠããŸãã â
éçºç®¡ç課ã§ã¯äžç·ã«åãã¡ã³ããŒãåéããŠãŸãïŒïŒâ
âãâãâ ãããã¯ãã»ãã¥ãªãã£ãšã³ãžãã¢ãã®é
ããåç
§é¡ããŸãã 募集職種 | 株式会社ラクス キャリア採用
ã¯ããã« PHP_CodeSnifferãšã¯ éçšãã㌠åé¡ç¹ PHP_CodeSnifferã®ææããŸãšããŠåãåã PHP_CodeSnifferã®ææã確èªããããã«ãéœåºŠCIãå®è¡ããªããã°ãªããªã æ¹å PhpStormã«PHP_CodeSnifferãèšå®ãã å°å
¥ PHP_CodeSnifferãã€ã³ã¹ããŒã«ãã PhpStorm ã®èšå®ç»é¢ãéããPHP_CodeSniffer ã®å®è¡èšå®ãè¡ã ã€ã³ã¿ããªã¿ã®èšå®ã远å ãã®åŸ å®è£
äžã«PHP_CodeSnifferã®ç¢ºèªãã§ããããã«ãªã£ã CIã®èªåãã§ãã¯å®äºãŸã§ã«ã¿ã€ã ã©ã°ããããåŸ
ã¡ã®æéãã§ããåé¡ã«ã€ã㊠ãŸãšã ã¯ããã« ããã«ã¡ã¯ãé
é
ã¡ãŒã«éçºããŒã ã«æå±ããŠããmrstsgkã§ãã 2023幎3æ23æ¥ãã3æ25æ¥ã«éå¬ãããPHPerKaigiã«åå ããŸããïŒ ïŒLTæ ã§ç»å£ããŸããïŒãšãŠã楜ããã£ãã§ãïŒïŒ speakerdeck.com çºè¡šåŸã PHP _CodeSnifferã«ã€ããŠé²å±ããã£ãã®ã§ããã®ããã°ã§ç޹ä»ããããŸãã PHP _CodeSnifferãšã¯ ã³ãŒãã£ã³ã°èŠçŽã®éåãæ€åºããã©ã€ãã©ãªã§ãã PSRã PEAR ãªã©ã®æ§ã
ãªã³ãŒãã£ã³ã°èŠçŽãæå®ããŠæ€æ»ã宿œããŠããŸãã PSR ãšã¯ïŒ PHP Standards Recommendationsã®ç¥ã§ã PHP -FIGïŒThe PHP Framework Interop GroupïŒãçå®ããŠãã PHP ã®èŠçŽã§ãã PEAR ãšã¯ïŒ PHP Extension and Application Repositoryã®ç¥ã§ã PHP ã§å©çšããäºãã§ããã©ã€ãã©ãªïŒããã±ãŒãžïŒãæäŸããŠãããµãŒãã¹ã®ããšã§ãã 䌌ãååã§ PECL ããããŸããããã¡ã㯠Cèšèª ã§æžãããæ¡åŒµã©ã€ãã©ãª (extension) ãæäŸãããµãŒãã¹ã®ããšã§ãã ç¬èªã®èŠçŽã远å ããããšãå¯èœã§ãã ç§ãã¡ã®ããŒã ã§ã¯ãç¬èªã®ã«ãŒã«ã»ãããæ¡çšããŠããŸãã åå PSR12 ã«æºæ ããã«ãŒã«ã»ããã«ãªã£ãŠããŸããã else if ã®ä»£ããã« elseif ã䜿çšãããªã©æ¢åã³ãŒãã®åœ±é¿ã§å€§éã«ææãåºãããªã«ãŒã«ã¯é€å€ããŠããŸãã éçšãã㌠CIã§ã®èªåãã§ãã¯ã 芪ãã©ã³ããšæ¯èŒããŠå¢å ãããšã©ãŒã®ã¿ãåºåãããŸãã \ åé¡ç¹ çŸç¶ã®éçšãããŒã§ã®åé¡ç¹ PHP _CodeSnifferã®ææããŸãšããŠåãåã ããŒã ã®éçºã®æµããšããŠãå®è£
å®äºæã«ä»ãŸã§ã® commit ããŸãšããŠGitLabã« push ããããšãå€ããããŸããã ãªã®ã§ã PHP _CodeSnifferã®ææããŸãšããŠåããããã察å¿ã§ å·¥æ° ãå¢å ããåé¡ãçºçããŸããã PHP _CodeSnifferã®ææã確èªããããã«ãéœåºŠCIãå®è¡ããªããã°ãªããªã ã PHP _CodeSnifferã®ææããŸãšããŠåãåãããšããåé¡ã解決ããããã«ãããŸãã«GitLabã« push ããããã«ãªããŸããã ãããCIã§ã®èªåãã§ãã¯ãå®äºãããŸã§ã«ã¿ã€ã ã©ã°ããããåŸ
ã¡ã®æéãã§ããŠããŸããŸããã CIå®è¡äžã«ã»ãã®äœæ¥ã«çæããã®ã§ã¹ã€ããã³ã°ã³ã¹ãã®å¢å ãèŠãããå®è£
ã«éäžãã«ããç°å¢ã«ãªã£ãŠããŸããã æ¹å PhpStormã« PHP _CodeSnifferãèšå®ãã çŸç¶ã®éçšãããŒã ãšã PHP _CodeSnifferã確èªã§ããã®ãGitLabã« push ããããšã ãã ã£ãã®ã§ã 確èªã§ããæ®µéããã£ãšæ©ãããããã«PhpStormã« PHP _CodeSnifferãå°å
¥ããããšã«ãªããŸããã ãŸããPHPerKaigiåŸã«å¯ãããããã£ãŒãããã¯ã確èªããŠãããšã以äžã®ãã£ãŒãããã¯ãããã ããŸããã ïŒãã£ãŒãããã¯ããããšãããããŸãïŒïŒïŒ IDE ã«çµã¿èŸŒãã°CIã«ãããåã«æå
ã§ãã§ãã¯ã§ããã®ã§ããã£ãŒãããã¯ãµã€ã¯ã«ãæ©ããããŠãããšæããŸããã PhpStormã« PHP _CodeSnifferãèšå®ããéã¯ãå
¬åŒã®ããã¥ã¡ã³ããåèã«ããã°å°å
¥ãããããšæããŸãã pleiades.io å°å
¥ PHP _CodeSnifferãã€ã³ã¹ããŒã«ãã å
¬åŒã®ããã¥ã¡ã³ãã«ãããš PHP _CodeSnifferãComposerãšå
±ã«ã€ã³ã¹ããŒã«ãããšãPhpStormã¯å¿
èŠãª ã¹ã¯ãªãã ãèªåçã«ããŠã³ããŒããã IDE ã«ç»é²ãããªãã·ã§ã³ã§å¯Ÿå¿ããã³ãŒãã€ã³ã¹ãã¯ã·ã§ã³ãæå¹ã«ããŠæ§æããŸãã ãšã®ããšãªã®ã§ãcomposerãã€ã³ã¹ããŒã«ããŸãã php composer.phar install PhpStorm ã®èšå®ç»é¢ãéãã PHP _CodeSniffer ã®å®è¡èšå®ãè¡ã SettingsãéããŸãã PHP > Quality Toolså
ã« PHP _CodeSnifferãããã®ã§ãããããèšå®ããããšãã§ããŸãã ã€ã³ã¿ããªã¿ ã®èšå®ã远å â»èšå®äŸ PHP _CodeSniffer pathïŒ /usr/local/phpcs/vendor/bin/phpcs Path to phpcbfïŒ /usr/local/phpcs/vendor/bin/phpcbf ãã®åŸ å®è£
äžã« PHP _CodeSnifferã®ç¢ºèªãã§ããããã«ãªã£ã PhpStormã« PHP _CodeSnifferãå°å
¥ããããšã§ãåé¡ç¹ã§ãã£ãã PHP _CodeSnifferã確èªã§ããã®ãGitLabã« push ããããšã ããã解決ããããšãã§ããŸããã PHP _CodeSnifferãCIã«çµã¿èŸŒãã ãšãã«åºãè¯ãå¯ç£ç©ãšããŠã éçºäžã«çްããCommitç²åºŠã§GitLabãžpushããããã«ãªãããéçºâCIã§ã³ãŒãã確èªâä¿®æ£ãã®ãµã€ã¯ã«ã§å®è£
ã«éäžããããç¶æ
ã«ãªããŸãããã PhpStormã« PHP _CodeSnifferãå°å
¥ããããšã§ããéçºâéçè§£æâä¿®æ£ãã®ãµã€ã¯ã«ãåãããšãã§ããããã«ãªããããå®è£
ã«éäžããããç°å¢ã«ãªããŸããïŒïŒ CIã®èªåãã§ãã¯å®äºãŸã§ã«ã¿ã€ã ã©ã°ããããåŸ
ã¡ã®æéãã§ããåé¡ã«ã€ã㊠ãã¡ãã®åé¡ã¯ãPhpStormã« PHP _CodeSnifferãå°å
¥ããŠã解決ããããšã¯ã§ããŸããã æ ¹æ¬çãªåå ãšããŠãCIã®ãžã§ãããã€å®äºããŠãããããããªãã®ã§å®æçã«GitLabã確èªããªããã°ãªããŸããã§ããã ãªã®ã§ãCIã®ãžã§ããå®äºãããé£çµ¡ãæ¥ãä»çµã¿ãäœã£ãŠå¯Ÿå¿ããŠããŸãã ãŸãšã éçè§£æããŒã«ã¯ãã¯ãæé«ã§ããïŒïŒ ã³ãŒãã£ã³ã°æã®æ©ã段éã§ãšã©ãŒãæ€åºã§ããããããã°ä¿®æ£ã³ã¹ããæå¶ã§ããããšããå
±éã®ã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ãæšé²ã§ãããããã³ãŒãã®å¯èªæ§ãä¿å®æ§ãåäžãããªã©ã®å€ãã®å©ç¹ããããŸãã çãããæ¯éãéçè§£æããŒã«ãå©çšããŠå¿«é©ãªéçºã©ã€ãããéãããã ããã ãã ãããžã§ã¯ãã«ããããŸããã PHP _CodeSnifferã¯ã IDE ãžã®å°å
¥ããCIã§ã®èªåãã§ãã¯ããCIã®ãžã§ãé£çµ¡ããã®ïŒã€ãæãããšã§çã®å¿«é©ããåŸããããšæããŸããã
ã¯ããã« ã¯ãããŸããŠã ã©ã¯ ã¹ããã³ããšã³ãéçºèª²ã®æè€ã§ãã æ®æ®µããã³ããšã³ãéçºèª²ã§ã¯ãäžéšã®ãããã¯ãã«ãããŠæ°ããéçºããæ©èœãå®è£
ããç»é¢ããããã©ãŒãã³ã¹ã®å£åãæžå¿µãããç»é¢ã«å¯ŸããŠãæ§èœèšæž¬ãè¡ã£ãŠããŸããä»åã¯ããã³ããšã³ãéçºèª²ã ã©ã®ãããªWebããã©ãŒãã³ã¹ææšãèšæž¬ããŠããã®ã ã ãªããã®ææšãæ¡çšããã®ã ã ã©ã®ããã«èšæž¬ããŠããã®ã ã玹ä»ããããšæããŸãããŸããããã©ãŒãã³ã¹ãèšæž¬ããŠããäžã§ äžäŸ¿ã«æã£ãŠããããš ã æ¹åããŠããããããš ã«ã€ããŠãã玹ä»ããŸãã æ³šæç¹ãšããŠä»å玹ä»ããææšãèšæž¬ããŒã«ã¯ããããŸã§ã ã©ã¯ ã¹ã®ãããã¯ãã«åãããŠéžå®ãããã®ã§ãããããä»ç€Ÿæ§ããããã¯å人ã«ãšã£ãŠæé©ãªãã®ãšèšããããã§ã¯ãããŸãããåèçšåºŠã«ãèªã¿é ããã°å¹žãã§ãã ã¯ãã㫠察象èªè
ãã®èšäºã§æ±ããªãããš çµè« èšæž¬ããææšãšç®æšã¹ã³ã¢ã®äžäŸ èšæž¬ããŒã« éžå®çç± åææšã®æŠèŠãšéžå®çç± FCP (First Contentful Paint) æŠèŠ éžå®çç± åèã¹ã³ã¢ LCP (Largest Contentful Paint) æŠèŠ éžå®çç± åèã¹ã³ã¢ TTI(Time to Interactive) æŠèŠ éžå®çç± åèã¹ã³ã¢ TBT(Total Blocking Time) éžå®çç± åèã¹ã³ã¢ CLS(Cumulative Layout Shift) éžå®çç± åèã¹ã³ã¢ Response æŠèŠ éžå®çç± ç®æš Animation æŠèŠ éžå®çç± ç®æš èšæž¬æé webããã©ãŒãã³ã¹èšæž¬ç°å¢ã®æºå èšæž¬å¯Ÿè±¡ç»é¢ devtoolsã®èšå® view portã®èšå® ã¹ãããã«ã®èšå® åwebããã©ãŒãã³ã¹ææšã®æž¬å® LCP, TTI, LCP, CLSã®æž¬å® TBTã®æž¬å® Responseã®æž¬å® Animation ããã©ãŒãã³ã¹æž¬å®ã·ãŒã çŸç¶åé¡ã«æããŠããããš ããã©ãŒãã³ã¹èšæž¬ãå§ããŠããã£ãããš ãããã« åèæç® 察象èªè
ããã³ããšã³ãã®ããã©ãŒãã³ã¹ãèšæž¬ãããããã©ã®ææšãèšæž¬ããã°ãããããããªãæ¹ ããã³ããšã³ãã®ããã©ãŒãã³ã¹ãèšæž¬ãããããã©ã®ããŒã«ã䜿ã£ãŠèšæž¬ããã°ãããããããªãæ¹ ããã³ããšã³ãã®ããã©ãŒãã³ã¹æž¬å®ã«ã€ããŠèå³ãããæ¹ ãã®èšäºã§æ±ããªãããš Webããã©ãŒãã³ã¹ã®æ¹åæ¹æ³ çµè« èšæž¬ããææšãšç®æšã¹ã³ã¢ã®äžäŸ WANT MUST FCP <= 1.8s <= 3.0s LCP <= 2.5s <= 4.0s TTI <= 3.8s <= 7.3s TBT <= 200ms <= 600ms CLS <= 0.1 <= 0.25 Response <= 100ms <= 1000ms Animation <= 16.7ms(60FPS) <= 33.3ms(30FPS) â»ç®æšã¹ã³ã¢ã¯ãããŸã§ãäžäŸã«ãªããŸããå®éã«ã¯ãããã¯ãããšã«ç°ãªãå€ãšãªã£ãŠããŸãã èšæž¬ããŒã« ããã©ãŒãã³ã¹ææšèšæž¬ã«ã¯ä»¥äžããŒã«ãçšãã Chrome devtools: Performance Insight 枬å®å¯Ÿè±¡ïŒFCP, LCP, TTI, CLS Chrome devtools: Performance 枬å®å¯Ÿè±¡ïŒTBT, Response, Animation éžå®çç± devtoolsã«å
å
ãããæ©èœã®ãã宿œã³ã¹ããäœã ãããã¯ãŒã¯ã»CPUã®ã¹ãããã«ãè¡ããããå®ãŠãŒã¶ãŒç°å¢ã«è¿ãèšæž¬ãè¡ãã web.dev ã§ç޹ä»ãããŠããææšã«å ãã RAILã¢ãã« ã®æž¬å®ãè¡ãããã åææšã®æŠèŠãšéžå®çç± ãŠãŒã¶ãŒãããã©ãŒãã³ã¹ãã©ã®ããã«èªèããŠãããã«é¢ããææšãšããŠã以äžã®é
ç®ã æããããŠããŸãã 䜿çšå¯èœæ§ ïŒãŠãŒã¶ãŒãããŒãžãæäœã§ããŠããããã ãžãŒ ç¶æ
ã«ãªã£ãŠããªããã å¿«é©ã ïŒé
å»¶ããšã©ãŒããªããã¹ã ãŒãºã§èªç¶ãªæäœãã§ããŠãããã ç¥èŠãããèªã¿èŸŒã¿é床:  ããŒãžããã¹ãŠã®èŠèŠèŠçŽ ãèªã¿èŸŒã¿ãç»é¢ã« ã¬ã³ããªã³ã° ããé床ã èªã¿èŸŒã¿ã®å¿çæ§:  ã³ã³ããŒãã³ã ããŠãŒã¶ãŒã®æäœã«å¯ŸããŠãã°ããå¿çããããã«ãããŒãžãå¿
èŠãª JavaScript ã³ãŒããèªã¿èŸŒãã§å®è¡ããé床ã å®è¡æã®å¿çæ§:  ããŒãžã®èªã¿èŸŒã¿ãå®äºããåŸãããŒãžããŠãŒã¶ãŒã®æäœã«ã©ã®çšåºŠãã°ããå¿çã§ããããç€ºãææšã èŠèŠçãªå®å®æ§:  ãŠãŒã¶ãŒãäºæããªããããªææ³ã§ããŒãžäžã®èŠçŽ ãç§»åãããŠãŒã¶ãŒã®æäœã«æ¯éããããå¯èœæ§ããããã©ãããç€ºãææšã æ»ããã:  ãã©ã³ãžã·ã§ã³ ãã¢ãã¡ãŒã·ã§ã³ãäžå®ã®ãã¬ãŒã ã¬ãŒãã§ ã¬ã³ããªã³ã° ãããããç¶æ
ããå¥ã®ç¶æ
ãžãšæµããããã«ç§»åããŠãããã©ãããç€ºãææšã ããã³ããšã³ãéçºèª²ã§ã¯äžèšãç¶²çŸ
çã«æž¬å®ããããšãç®æãåææšãéžå®ããŠããŸãã FCP (First Contentful Paint) æŠèŠ FCPã¯ããŠãŒã¶ãŒãã¢ã¯ã»ã¹ãããŠã§ããµã€ãã§æåã«è¡šç€ºãããã³ã³ãã³ããã©ããããæ©ãæç»ãããããç€ºãææšã§ãããã®ææšã«ããã "ã³ã³ãã³ã" ã¯ãããã¹ããç»å (èæ¯ç»åãå«ã)ã <svg> èŠçŽ ãçœä»¥å€ã® <canvas> èŠçŽ ã®ããšãæããŠããŸãã åŒçšå
ïŒ https://web.dev/fcp/ äžèšã®ã¿ã€ã ã©ã€ã³ã§ã¯2ãã¬ãŒã ç®ã«ã³ã³ãã³ããåããŠè¡šç€ºãããŠããŸãããã®ããã«FCPã¯webãµã€ããèªã¿èŸŒãã§ããäžéšã®ã³ã³ãã³ãã衚瀺ããããŸã§ã®æéãèšæž¬ããŸããå
šãŠã®ã³ã³ãã³ãã ã¬ã³ããªã³ã° ãããæéã§ã¯ç¡ãããšã«æ³šæããŠãã ããã éžå®çç± èªã¿èŸŒã¿ã®å¿çæ§ã枬å®ãããã åèã¹ã³ã¢ MUSTïŒ3ç§ä»¥äž WANTïŒ1.8ç§ä»¥äž åèïŒ https://web.dev/fcp/#fcp-ã«ãããè¯ãã¹ã³ã¢ãšã¯ïŒ LCP (Largest Contentful Paint) æŠèŠ LCPã¯ããã¥ãŒããŒãå
ã§æã倧ããªã³ã³ãã³ããã©ãã ãæ©ãæç»ãããããç€ºãææšã§ãããã®ææšã«ããã "ã³ã³ãã³ã" ã¯ã以äžã®èŠçŽ ãæããŸãã <img> èŠçŽ <svg> èŠçŽ å
ã® <image> èŠçŽ <video> èŠçŽ (ãã¹ã¿ãŒç»åã䜿çšãããŸã) ããã¹ã ããŒãããã®ä»ã®ã€ã³ã©ã€ã³ã¬ãã«ã®ããã¹ãèŠçŽ ã®åèŠçŽ ãå«ããããã¯ã¬ãã«èŠçŽ h1, h2, h3 p articleãªã© LCPãšããŠã¬ããŒããããèŠçŽ ã®ãµã€ãºã¯ãéåžžãã¥ãŒããŒãå
ã§ãŠãŒã¶ãŒã«å¯ŸããŠè¡šç€ºããããµã€ãºãšãªããŸããèŠçŽ ããã¥ãŒããŒãããã¯ã¿åºããŠããããèŠçŽ ã®äžéšãåãåãããŠããããç»é¢ã«è¡šç€ºãããªããªãŒããŒãããŒãçºçãããããŠãããããªå Žåããããã£ãéšåã¯èŠçŽ ã®ãµã€ãºã«ã¯å«ãŸããŸãããããããèŠçŽ ã«ãããŠã CSS ãä»ããŠé©çšãããŠããããŒãžã³ãããã£ã³ã°ãããŒããŒã¯ãã¹ãŠèæ
®ãããŸããã åŒçšå
ïŒ https://web.dev/lcp/ äžèšã®äŸã§ã¯LCPã¯5ãã¬ãŒã ç®ã§çºçããŠããŸããæåŸã®å€§ããªç»åã衚瀺ããããŸã§ã¯ããã¹ãèŠçŽ ãLCPã®ã¿ãŒã²ãããšãªã£ãŠããŸããããããŒãžã®èªã¿èŸŒã¿ãé²ã¿ãæçµçãªLCPã®ã¿ãŒã²ãããå€åããäŸã§ãã é
ããŠèªã¿èŸŒãŸããã³ã³ãã³ãã®æ¹ããã§ã«ããŒãžäžã«è¡šç€ºãããŠããã³ã³ãã³ãããããµã€ãºã倧ãããšãã£ãã±ãŒã¹ã¯ããèŠãããŸãããå¿
ããããããªãããã§ã¯ãããŸãããæ¬¡ã® 2 ã€ã®äŸã§ã¯ãããŒãžãå®å
šã«èªã¿èŸŒãŸããåã« LCPãçºçããŠããŸãã åŒçšå
ïŒ https://web.dev/lcp/ éžå®çç± ç¥èŠãããèªã¿èŸŒã¿éåºŠãæž¬å®ãããã åèã¹ã³ã¢ MUSTïŒ4ç§ä»¥äž WANTïŒ2.5ç§ä»¥äž åèïŒ https://web.dev/lcp/#lcp-ã«ãããè¯ãã¹ã³ã¢ãšã¯ïŒ TTI(Time to Interactive) æŠèŠ TTI ã¯ãããŒãžã®èªã¿èŸŒã¿ãéå§ãããŠããäž»ãªãµããªãœãŒã¹ã®èªã¿èŸŒã¿ãå®äºãããŸã§ã®ææšã§ããæ¹åããããšã§ããŒãžããŠãŒã¶ãŒã®å
¥åã«å¯ŸããŠãã°ãã確å®ã«å¿çã§ããããã«ãªããŸãã TTIã¯ä»¥äžã®æé ã«æ²¿ã£ãŠèšæž¬ãããŸãã FCPããæéã®èšæž¬ãéå§ããŸãã å°ãªããšã 5 ç§éã®ãèœã¡çããŠããæéïŒä»¥äžquiet windowïŒããæéã®çµéé ã«æ¢ããŠãããŸããquiet windowã¯ä»¥äžã®ããã«å®çŸ©ãããŠããŸãã LongTaskïŒ50msãè¶
ããŠå®è¡ãããã¿ã¹ã¯ïŒããªã å®è¡äžã®ãããã¯ãŒã¯ GET ãªã¯ ãšã¹ ãã 2 ä»¶ä»¥äž quiet windowããåã®æéå
ã§ãäžçªæåŸã«çŸããé·ãæéãããã£ãŠããã¿ã¹ã¯ãèŠã€ãåºããŸããé·ãæéãããã£ãŠããã¿ã¹ã¯ãèŠã€ãããªãå Žåã«ã¯ãFCP ãŸã§é¡ããŸãã quiet windowããåã®æéå
ã§äžçªæåŸã«çŸããé·ãæéãããã£ãŠããã¿ã¹ã¯ã®çµäºæéããTTI ãšãªããŸãã(é·ãæéãããã£ãŠããã¿ã¹ã¯ãèŠã€ãããªãå Žåã«ã¯ãFCP ãšåãå€ã«ãªããŸã)ã 以äžã®å³ã¯ãäžèšã®æé ãèŠèŠåãããã®ã§ãã åŒçšå
ïŒ https://web.dev/tti/ éžå®çç± å®è¡æã®å¿çæ§ã枬å®ãããã åèã¹ã³ã¢ MUSTïŒ7.3ç§ä»¥äž WANTïŒ3.8ç§ä»¥äž åèïŒ How Lighthouse determines your TTI score TBT(Total Blocking Time) TBTã¯ãèªã¿èŸŒã¿ã®å¿çæ§ã枬å®ããããã«éèŠãšãªãææšã§ããããŒãžã確å®ã«æäœå¯èœã«ãªããŸã§ã®éã®æäœäžå¯èœæ§ã®é倧ãã®æ°å€åã«åœ¹ç«ã¡ãTBT ãäœããã°äœãã»ã©ããŒãžã確å®ã«äœ¿çšå¯èœãšãªãããšã瀺ããŠããŸãã ã¡ã€ã³ã¹ã¬ããäžã«LongTaskïŒ50msãè¶
ããŠå®è¡ãããã¿ã¹ã¯ïŒãååšããå Žåããã®ã¡ã€ã³ã¹ã¬ããã¯"ãããã¯ããã" ãšã¿ãªãããŸãã"ãããã¯ããã" ãšè¡šçŸãããã®ã¯ã ãã©ãŠã¶ãŒ ãé²è¡äžã®ã¿ã¹ã¯ãäžæããããšãã§ããªãããã§ãããããã£ãŠãLong Taskå®è¡äžã«ãŠãŒã¶ãŒãããŒãžãæäœããå Žåã ãã©ãŠã¶ãŒ ã¯å¿çããåã«ã¿ã¹ã¯ã®çµäºãåŸ
ããªããã°ãªããŸãããããã«ãããŠãŒã¶ãŒããèŠããšããŒãžãé
ãããŸãã¯è³ªãäœããšæããŠããŸãå¯èœæ§ããããŸãã TBTã¯ãFCPãšTTIã®éã§çºçããåé·ãã¿ã¹ã¯ã® ãããã¯æéã®åèšã«ããèšç®ãããŸãã ããšãã°ãããŒãžãèªã¿èŸŒãã§ããæäžã® ãã©ãŠã¶ãŒ ã®ã¡ã€ã³ ã¹ã¬ããã®å³ã¯ã以äžã®ããã«ãªããŸãã åŒçšå
ïŒ https://web.dev/tbt/ äžèšã®ã¿ã€ã ã©ã€ã³äžã«ã¯ 5 ã€ã®ã¿ã¹ã¯ãããããã®ãã¡ã® 3 ã€ã¯ç¶ç¶æéã 50 ms ãè¶
ããŠãããããé·ãæéãããã£ãŠããã¿ã¹ã¯ãšãªããŸãã以äžã®å³ã¯ãé·ãæéãããã£ãŠããã¿ã¹ã¯ããããã®ãããã¯æéã瀺ããŠããŸãã åŒçšå
ïŒ https://web.dev/tbt/ ãã®ãããã¡ã€ã³ ã¹ã¬ããã§ã®ã¿ã¹ã¯å®è¡ã®ç·æé㯠560 ããªç§ã§ããããã®ãã¡ã® 345 ããªç§ã®ã¿ããããã¯æéãšããŠã¿ãªãããŸãã ã¿ã¹ã¯ã®ç¶ç¶æé ã¿ã¹ã¯ã®ãããã¯æé ã¿ã¹ã¯ 1 250 ããªç§ ã¿ã¹ã¯ 2 90 ããªç§ ã¿ã¹ã¯ 3 35 ããªç§ ã¿ã¹ã¯ 4 30 ããªç§ ã¿ã¹ã¯ 5 155 ããªç§ åèšãããã¯æé 345 ããªç§ éžå®çç± äœ¿çšå¯èœæ§ãèªã¿èŸŒã¿ã®å¿çæ§ã枬å®ãããã åèã¹ã³ã¢ MUSTïŒ600ããªç§ä»¥äž WANTïŒ200ããªç§ä»¥äž åèïŒ how-lighthouse-determines-your-tbt-score CLS(Cumulative Layout Shift) CLSã¯ãèŠèŠçãªå®å®æ§ã枬å®ããããã®ææšã§ããç»é¢ã«è¡šç€ºãããã³ã³ãã³ãã®ãŠãŒã¶ãŒã®äºæããªãçªç¶ã®ç§»åããºã¬ãã¬ã€ã¢ãŠãã·ãããšåŒã³ãŸãããã®ã¬ã€ã¢ãŠãã·ããã«ééããé »åºŠã®æ°å€åã«åœ¹ç«ã€ææšãCLSã§ãããCLS ãäœããã°äœãã»ã©ããã®ããŒãžãå¿«é©ã§ããããšãä¿èšŒãããŸãã CLSã¹ã³ã¢ã¯ä»¥äžã®èšç®åŒã§ç®åºãããŸãã ã¬ã€ã¢ãŠãã·ããã®åœ±é¿ãåããé¢ç©ãÃãå®éã«ãããŠåããè·é¢ 以äžã®ããã«ããã¹ãã衚瀺ãããããšã«ãClick Meããã¿ã³ã衚瀺ãããèŠçŽ ã®ãºã¬ãèµ·ãã£ãå ŽåãèããŸã åŒçšå
ïŒ https://web.dev/cls/ ã¬ã€ã¢ãŠãã·ããã®åœ±é¿ãåããé¢ç©ïŒèµ€ç¹ç·éšã«å²ãŸããåïŒã¯ãã¥ãŒããŒãå
šäœã®50%ãå ãããã0.5ãšãªããŸãããŸãå®éã«ãããŠåããè·é¢ïŒçŽ«è²ã®ç¢å°ã®é·ãïŒã¯ãã¥ãŒããŒãå
šäœã®15%ãå ããŸãããããã£ãŠCLSã¹ã³ã¢ã¯æ¬¡ã®ããã«èšç®ã§ããŸãã 0.5ïŒã¬ã€ã¢ãŠãã·ããã®åœ±é¿ãåããé¢ç©ïŒÃã0.15ïŒå®éã«ãããŠåããè·é¢ïŒïŒ0.075 ã¬ã€ã¢ãŠãã·ãããè€æ°ç®æã§çºçããå Žåã¯äžèšèšç®åŒã®åèšå€ãCLSã¹ã³ã¢ãšãªããŸãã åèïŒ https://gmotech.jp/semlabo/seo/blog/cwv_cls/ éžå®çç± èŠèŠçãªå®å®æ§ã枬å®ãããã åèã¹ã³ã¢ MUSTïŒ0.25ä»¥äž WANTïŒ0.1ä»¥äž åèïŒ https://web.dev/cls/#cls-ã«ãããè¯ãã¹ã³ã¢ãšã¯ïŒ Response æŠèŠ Responseã¯ããŠãŒã¶ãŒãã¢ã¯ã·ã§ã³ãèµ·ããããšãWebãµã€ããåå¿ãããŸã§ã枬å®ããææšã§ãã100ms以å
ã«å®äºããããšã§ããŠãŒã¶ãŒã¯ãããšããç¬æã«è¡ãããŠãããšæããŸããäŸãã°ä»¥äžã®ã¢ã¯ã·ã§ã³æéãæž¬å®ããŸãã ãã§ãã¯ããã¯ã¹ ã«ãã§ãã¯ãå
¥ããŠãããã§ãã¯ç¶æ
ãåæ ããããŸã§ ãªã³ã¯ãã¯ãªãã¯ããŠããç»é¢ãé·ç§»ãããŸã§ ãã¿ã³ãã¯ãªãã¯ããŠãããã€ã¢ãã°ã衚瀺ããããŸã§ API ãå©ããŠããäœããã®éç¥ïŒã¹ããã¯ããŒãããŒã¹ãçïŒã衚瀺ããããŸã§ éžå®çç± å¿«é©ããå®è¡æã®å¿çæ§ã枬å®ãããã ç®æš MUSTïŒ1000msä»¥äž WANTïŒ100msä»¥äž åèïŒ https://web.dev/i18n/ja/rail/#ãŠãŒã¶ãŒã«çŠç¹ãåããã Animation æŠèŠ Animationã¯ãã¢ãã¡ãŒã·ã§ã³åäœã®åãã¬ãŒã ã®åäœæéãæž¬å®ããææšã§ãããã®ææšã¯ã¢ãã¡ãŒã·ã§ã³ã®èŠèŠçãªæ»ããããæ°å€åãããã®ã§ãã éžå®çç± æ»ããããæž¬å®ãããã ç®æš MUSTïŒ16.7msä»¥äž WANTïŒ33.3msä»¥äž â» ãããã30FPS/60FPSãæºããç®æš åèïŒ https://web.dev/i18n/ja/rail/#ã¢ãã¡ãŒã·ã§ã³ïŒãã¬ãŒã ã10ããªç§ã§çæãã äžèšä»¥å€ã«ãéèŠãªææšãšããŠFIDãæããããŸããFIDã¯ããŠãŒã¶ãŒãæåã«ãµã€ããæäœãããšã ããããã®æäœã«å®éã«å¿çãããŸã§ã®æéãæž¬å®ããææšã§ãããã®ææšã¯ å®éã®ãŠãŒã¶ãŒç°å¢ã§æž¬å®ããææšã§ãã ããæž¬å®é£æåºŠãé«ããªããŸãããããã£ãŠãFIDã®ä»£ããã«TBTãæž¬å®ããããšã§å¯ŸåŠããäºãšããŸãã TBTã¯FIDãšçžé¢æ§ãé«ãããã€æ€èšŒç°å¢ã§ã®æž¬å®ãå¯èœ ãªããšãçç±ã§ãã èšæž¬æé webããã©ãŒãã³ã¹èšæž¬ç°å¢ã®æºå webããã©ãŒãã³ã¹ãèšæž¬ããããã«ä»¥äžã®æ¡ä»¶ãæºããç°å¢ãçšæããŸã æ€èšŒç°å¢ æ¬çªãã«ããã€BEãšçéãè¡ããç°å¢ãçšæããŸã ãã ãããã³ããšã³ãã®ããã©ãŒãã³ã¹æž¬å®ã®ã¿ã«çŠç¹ãåœãŠãå Žåãããã¯ãšã³ãã¯ã¢ãã¯ç°å¢ã§ãOKãšããŸãããã®å Žåã§ãããã³ããšã³ãã¯æ¬çªãã«ããè¡ã£ãç°å¢ã§æž¬å®ããŠãã ããã çç±ïŒãŠãŒã¶ãŒã䜿çšããå®éã®ç°å¢ã«è¿ãæ¡ä»¶ã§æž¬å®ãããã çè«äžè¡šç€ºã§ããæå€§æ°ã®ããŒã¿ãçšæãã äŸãã°ïŒã€ã®ããŒãžã§æå€§500ä»¶ã®æ€çŽ¢çµæã衚瀺ã§ãããããªä»æ§ã®å ŽåããããŒããŒã¿ã500件以äžçšæããã€ããã®å
šãŠã衚瀺ããäžã§èšæž¬ãè¡ããŸã æå€§è¡šç€ºä»¶æ°ã決ãŸã£ãŠããªãããŒãžã«é¢ããŠã¯ããã¥ãŒããŒãå
šäœã«è¡šç€ºã§ããæ°ã®ãããŒããŒã¿ãçšæããã°OKãšããŸã çç±ïŒäºæž¬ãããæå€§ã® ã¬ã³ããªã³ã° ã³ã¹ãããããç°å¢ã®ããã©ãŒãã³ã¹æ¹åãè¡ãããšãã§ããã°ããã®ç»é¢å
šäœã®webããã©ãŒãã³ã¹åäžãæåŸ
ã§ãããã èšæž¬å¯Ÿè±¡ç»é¢ æ°ããæ©èœã远å ããç»é¢ã«ãããŠãããã©ãŒãã³ã¹ã®äœäžãæžå¿µãããç»é¢ æ°ããäœæããç»é¢ é¡äŒŒããç»é¢ãè€æ°å®è£
ããå Žåãããã1ã€ã§OKãšããŸã devtoolsã®èšå® webããã©ãŒãã³ã¹ã®èšæž¬ãè¡ãåã«devtoolsã®èšå®ãè¡ããŸãã view portã®èšå® view portã«ããwebããã©ãŒãã³ã¹ã®æž¬å®çµæã¯å€åããããview portãåºå®ããŸãã devtoolsãéããToggle device toolbarããæŒäžããŸãã ç»é¢ãµã€ãºãä»»æã®å€ã«èšå®ããŸããåºæ¬çã«ã¯æäŸããã¢ããªã±ãŒã·ã§ã³ã®æšå¥šããç»é¢ãµã€ãºã«èšå®ããŸãã ã¹ãããã«ã®èšå® åæãå©çšãããŠãŒã¶ãŒãçšããPCã¯ãšã³ãžãã¢ã®éçºçšPCãšæ¯èŒããŠæ§èœãäœãããšãæžå¿µãããŸãããããã£ãŠãŠãŒã¶ãŒã®å®ç°å¢ã«è¿ãæ¡ä»¶ã§webããã©ãŒãã³ã¹ã®æž¬å®ãè¡ããããdevtoolsã§ã¹ãããã«ã®èšå®ãè¡ããŸãã devtoolsã®ãPerformance Insightsãããã«ãéããŸãã ã»ã¬ã¯ãããã¯ã¹ãæŒäžãNetworkãCPUãæ³å®ãããŠãŒã¶ãŒã®ç°å¢ã«åãããŠèšå®ããŸãããŠãŒã¶ãŒã¯åºæ¬çã«ãã£ãã·ã¥ãããç¶æ
ã®ããŒãžãåç
§ããã®ã§ããDisable cacheãã®ãã§ãã¯ã¯å€ããŸãã åæ§ã«devtoolsã®ãPerformanceãããã«ãéããŸãã èšå®ãã¿ã³ãæŒäžããŸãã CPUãNetworkãèšå®ããŸãã åwebããã©ãŒãã³ã¹ææšã®æž¬å® LCP, TTI, LCP, CLSã®æž¬å® LCP, TTI, LCP, CLS㯠Chrome DevToolsã®ãPerformance Insightsãããã«ã§æž¬å®ããããšãã§ããŸãã Chrome DevToolsãéãããPerformance Insightsãããã«ãæŒäžããŸãã ãMeasure page loadããæŒäžãããã©ãŒãã³ã¹æž¬å®ãè¡ããŸãã devtoolsã«è¡šç€ºãããFCP,LCP,TTIã«ããŠã¹ãããŒãããšåå€ã衚瀺ãããŸãã CLSã¯ç»é¢ã«ã¬ã€ã¢ãŠãã·ãããçºçããŠããå Žåã®ã¿èªåã§èšæž¬ãããŸãããInsightsãã¿ãããå€ã確èªã§ããŸãã TBTã®æž¬å® TBT㯠Chrome DevToolsã®ãPerformanceãããã«ã§æž¬å®ããŸãã Chrome DevToolsãéãããPerformanceãããã«ãæŒäžããŸãã ç»é¢å·Šäžã®ãStart profiling and reload pageããæŒäžããŸãã devtoolsäžéšã«è¡šç€ºããããTotal blocking timeãã®å€ãTBTã§ãã Responseã®æž¬å® Response㯠Chrome DevToolsã®ãPerformanceãããã«ã§æž¬å®ããŸãã ä»åã¯ãã¿ã³ãæŒããŠãããã€ã¢ãã°ãéããŸã§ã® å¿çæé ã®æž¬å®ãäŸã«ãšããŸãã Chrome DevToolsãéãããPerformanceãããã«ãæŒäžããŸãã ãScreenshotsãã«ãã§ãã¯ãå
¥ããŸãã devtoolså·Šäžã®ãrecordããæŒäžããŸãã ã¢ããªã±ãŒã·ã§ã³äžã§ãã¿ã³ãæŒäžãããã€ã¢ãã°ã衚瀺ãããŸãã devtoolså·Šäžã®ãstopããæŒäžããŸãã ã¹ã¯ãªãŒã³ã·ã§ãã ã確èªããªãããã¿ã³ãæŒããŠãããã€ã¢ãã°ã衚瀺ããããŸã§ã®ç¯å²ããã©ãã°ããŠçµã蟌ã¿ãŸãã TotalãResponseã®æž¬å®å€ã«ãªããŸãã Animation Animation㯠Chrome DevToolsã®ãPerformanceãããã«ã§æž¬å®ããŸãã ä»åã¯ãã€ã¢ãã°ãéãéã®ã¢ãã¡ãŒã·ã§ã³ã枬å®ããŸãã 1~5ãŸã§ã¯Responseã®æž¬å®ãšåæ§ ã¹ã¯ãªãŒã³ã·ã§ãã ã確èªããªããã¢ãã¡ãŒã·ã§ã³åäœäžã®åãã¬ãŒã ã®åäœæéãèšé²ãã 2ã§èšé²ããåãã¬ãŒã ã®åäœæéã®å¹³åå€ãAnimationã®æž¬å®å€ã«ãªããŸããïŒ1ãã¬ãŒã ãã€ç¢ºèªããã®ã¯éå¹çãªããã±ã£ãšèŠã§ãOKïŒ ããã©ãŒãã³ã¹æž¬å®ã·ãŒã ããã³ããšã³ãéçºèª²ã§ã¯åwebããã©ãŒãã³ã¹ææšã®æž¬å®çµæã以äžã®ãã㪠ã¹ãã¬ããã·ãŒã ã«ãŸãšããŠããŸãã å
šæž¬å®å€ã®ãã¡75ããŒã»ã³ã¿ã€ã«ä»¥äžã®å€ãåæ ŒåºæºãæºãããŠããã°ããã®ææšã¯åæ ŒãšãªããŸããäŸãã°æž¬å®åæ°ãå
šéšã§4åã®å Žåããã®ãã¡ã®3åãåæ ŒåºæºãæºãããŠããã°OKãšããããšã«ãªããŸãïŒ åè ïŒãåæ Œåºæºã«æºããªãå Žåã§ããèš³ããåæ ŒããšããŠåæ Œãšããããšãã§ããŸããçŸå®çã«ã¯å
šããŒãžãå
šæ©èœã§åæ Œåºæºãéæããããšã¯é£ããã§ããéæãé£ããæ¹åã§ããªãåççãªçç±ã説æã§ããã®ã§ããã°ãèš³ããåæ Œããšããããšãã§ããããã«ããŠããŸãã çŸç¶åé¡ã«æããŠããããš ãããŸã§èªãã§ããã ããŠããå Žåãã§ã«ãå¯ããããããŸããããåããã©ãŒãã³ã¹ãæåã§èšæž¬ããŠãããã 宿œã³ã¹ããé«ã ã§ããå°ãã§ã枬å®ã³ã¹ããæžãããããAnimationã®ææšã¯æž¬å®ããŠãªãã£ããïŒ SaaS ãããã¯ãã«ãããŠéèŠåºŠã®é«ããªãææšã®ããïŒãBEã MSW ã§ã¢ãã¯ããç°å¢ã§æž¬å®ãè¡ãããšããããŸããä¿¡é Œæ§ã®é«ãããŒã¿ã枬å®ããããšãšããã©ãŒãã³ã¹ã枬å®ããã³ã¹ã㯠ãã¬ãŒããªã ã®é¢ä¿ã«ããã®ã§ã å·¥æ° ãšçžè«ããªããèšæž¬ããŠããã®ãçŸå®ã§ããä»åŸã®å±æãšã㊠Lighthouse CI ã Sentry çãçšããŠèªåçã«ããã©ãŒãã³ã¹æž¬å®&ã¬ããŒãäœæãã§ããªããæ€èšŒãé²ããŠããããã§ãã ããã©ãŒãã³ã¹èšæž¬ãå§ããŠããã£ãããš åWebããã©ãŒãã³ã¹ã®ææšã«åºã¥ããŠå
·äœçãªæ°å€ãèšæž¬ãããããããã©ãŒãã³ã¹å£åã® ããã«ãã㯠ãã©ãã«ããããç¹å®ãããããªã£ãã®ã§è¯ãã£ãã§ããããªããšãªãããŒãžãé
ãæ°ãããããšãã£ãæèŠå€ãããLCPã®å€ãåºæºå€ãâ¯%äžåã£ãŠããããããã©ãŒãã³ã¹ãæªããã®ããã«å®æž¬å€ã§å€æã§ããããã«ãªããŸãããããã«ããããã®ããŒãžã®ããã©ãŒãã³ã¹ãæ¹åããããã«ã¯ãã£ã³ã¯åå²ã广çãªã®ã§ã¯ãªããããšå
·äœçãªæ ¹æ ãæã£ãŠä»®èª¬ãç«ãŠãããšãã§ããããã«ãªããå¹ççã«æ¹åã«åãçµããŠããŸãããŸãããã©ãŒãã³ã¹æ¹åãè¡ãªã£ãåŸããäžåºŠèšæž¬ãè¡ãããšã§ãå
·äœçã«ã©ã®é
ç®ãã©ãã ãæ¹åãããã®ãããããããã«ãªã£ããããããã©ãŒãã³ã¹æ¹åã®ããã«è¡ãªã£ãããšãæ¬åœã«å¹æããã£ãã®ãæ€èšŒããã®ã«ã圹ç«ã£ãŠããŸãã ãããã« ã©ã¯ ã¹ã®ããã³ããšã³ãéçºèª²ã枬å®ããWebããã©ãŒãã³ã¹ææšãšæž¬å®æ¹æ³ã玹ä»ããŸãããèšæž¬ã¯ãŸã å§ããã°ããã§éå¹çãªéšåãæããŠããŸããå°ããã€æ¹åããªãã宿œã³ã¹ããäžãã€ã€ã宿çã«ããã©ãŒãã³ã¹æž¬å®ãè¡ãããšã§ãããå質ã®é«ã補åããªãªãŒã¹ããŠããããã§ãã åèæç® ãŠãŒã¶ãŒãäžå¿ãšããããã©ãŒãã³ã¹ææš RAILã¢ãã«ã§ããã©ãŒãã³ã¹ãè©äŸ¡ãã Core Web Vitals ãæž¬å®ããããã®ããŒã« Lighthouseã®èšæž¬çµæãèŠãŠãã ã³ã¢ãŠã§ããã€ã¿ã«ã®CLSãšã¯ïŒ The Science Behind Web Vitals How Percentile Approximation Works Web Vitals Webããã³ããšã³ã ãã€ããã©ãŒãã³ã¹ ãã¥ãŒãã³ã°
PHP ã§ãæååã«ç¹å®ã®ããŒã¯ãŒããå«ãŸããŠããããããæååäžã«ç¹å®ã®æååãå«ãããã確èªãããå Žåãã©ã®ãããªã³ãŒããæžãã ãããïŒ ãããããªãã strpos() ã strstr() ãäœ¿ãæ¹æ³ãæãã€ããã®ãªããããã ãã¯èŠããŠåž°ã£ãŠã»ããã æååæ€çŽ¢ã«ã¯ str_contains() ã䜿ã ã çµè«ïŒæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ã ãµã³ãã« æã¯strpos()ãstrstr()ãªã©ã䜿ã£ãŠãã strpos() ã strstr() ã§ã¯ãã¡ãªã®ãïŒ strpos() ã䜿ãã¹ãã§ãªãçç± strstr() ã䜿ãã¹ãã§ãªãçç± preg_match()ã䜿ãã¹ãã§ãªãçç± ããããããŒã¯ãŒããå
é ã«ããããç¥ããããã ããšããäººã¯ ãæ¥æ¬èªã§ã䜿ããã®ïŒããšã®çåã«ã€ã㊠ãã£ãšè©³ããïŒ ããã§ããã£ãã ãã çµè«ïŒæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ã str_contains() ã¯ããæå®ããéšåæååããæååäžã«å«ãŸãããã調ã¹ããããã®é¢æ°ã§ããããã®é¢æ°ã¯PHP8.0 ã§è¿œå ãããã php .netïŒ str_contains str_contains(string $haystack, string $needle): bool needle ã haystack ã«å«ãŸãããã調ã¹ãŸãã 倧æåå°æåã¯åºå¥ãããŸãã ãäžç¥ã haystack ã« needle ãå«ãŸããŠããå Žå true ããã§ãªãå Žåãfalse ãè¿ããŸãã ãµã³ãã« <?php if ( str_contains ( "ãªãã ãåãã¡ïŒ" , "ãªãã " ) ) { echo "ãªãã ããã ãšèããããã" ; // 衚瀺ããã!! echo "çããŠããããäžã®æ
ã" ; } if ( str_contains ( "誰ã ãåãã¡ïŒïŒ" , "ãªãã " ) ) { echo "ãªãã ããã ãšèããããã" ; // 衚瀺ãããªã echo "çããŠããããäžã®æ
ã" ; } <?php $ result = str_contains ( "ãªãã ãåãã¡ïŒ" , "ãªãã " ) ; var_dump ( $ result ) ; // bool(true) $ result = str_contains ( "誰ã ãåãã¡ïŒ" , "ãªãã " ) ; var_dump ( $ result ) ; // bool(false) äžèšã®éããæ€çŽ¢çµæã bool ã§è¿ã£ãŠããããšãŠãæç¢ºãªä»æ§ã ã ååããã°ãããã contains ïŒå«ããå
å«ããïŒãšããã®ã§ãèªãã°äœããã颿°ãããããããã å°ãªããšã strpos() ã strstr() ããã¯çŽæçã ã ãã£ãŠãæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã æã¯ strpos() ã strstr() ãªã©ã䜿ã£ãŠãã ãããã Google æ€çŽ¢ã§ä»¥äžã®ãããªæ€çŽ¢ãè¡ããš strpos() ã strstr() ïŒããã㯠mb_strpos ã mb_strstr ïŒãææ¡ãããµã€ããåºãŠããã PHP ã§æååãæ€çŽ¢ãã PHP ã§æååãå«ããæ€çŽ¢ãã PHP ã§æååã®æç¡ã確èªãã ãªããïŒ ãã㯠str_contains() ã 2020/11/26 ã«ãªãªãŒã¹ããã PHP8.0 ã§å°å
¥ããã颿°ã ãã ã ã *1 *2 ãã以åã® PHP ã«ã¯ str_contains() ãååšããã strpos() ã strstr() ã代æ¿åãšããŠäœ¿ãææ³ãäžè¬çã ã£ãã®ã ã ãããã2023幎7æçŸåšãµããŒããããŠãã PHP8.0ã8.1ã8.2 ã«ã¯ str_contains() ãååšããã ã€ãŸãã str_contains() ã䜿ããªãããŒãžã§ã³ã® PHP ã¯ããEOLãè¿ããŠããã®ã ã *3 ãã®ããæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã strpos() ã strstr() ã§ã¯ãã¡ãªã®ãïŒ ä»ãŸã§äœ¿ã£ãŠãã strpos() ã strstr() ããªããªãããã§ã¯ãªããããä»ãŸã§éã䜿ã£ãŠãåé¡ãªãã§ããïŒïŒ ã²ãã£ãšããããããªãã¯ããæããããããªãã確ãã«ãã£ãšãã ã ããããããããèããŠæ¬²ãããããšããš strpos() ã¯ãæååå
ã®éšåæååãæåã«çŸããäœçœ®ãèŠã€ãããããã®é¢æ°ã ã *4 ãŸãã strstr() ããæååãæåã«çŸããäœçœ®ãèŠã€ããããããæååã®çµãããŸã§ãè¿ã颿°ãã§ããã *5 ã€ãŸãã ãããã®é¢æ°ã¯ãæååãå«ãŸããŠãããã確èªãã颿°ã§ã¯ãªã ãæ¬æ¥ã®ç®çãçŽç²ãªæ€çŽ¢ã§ã¯ãªãã®ã ã çŽãåãããã«å
äžã䜿ã£ãŠãã人ãèŠãããããããµãã䜿ããªãïŒããšèšããããªãã ããïŒãããšäŒŒãæèŠã ã éåæãäŒãã£ãã®ã§ããã°ãæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã strpos() ã䜿ãã¹ãã§ãªãçç± ãã£ãšçŸå®çãªçç±ãããã ããã¯ã strpos() ãªã©ãæååæ€çŽ¢ã«äœ¿ããšããã°ãçã¿åºãå¯èœæ§ãé«ããªã£ãŠããŸãããšã ã strpos() ãªã©ã®æ»ãå€ã¯ãFALSE ã ãã§ãªã 0 ãè¿ãããšãããã®ããã®åå ã ã ãŸãã strpos() ã®å®çŸ©ã確èªãããã php .netïŒ strpos strpos(string $haystack, string $needle, int $offset = 0): int|false æåå haystack ã®äžã§ã needle ãæåã«çŸããäœçœ®ãæ¢ããŸãã ãäžç¥ã needle ãèŠã€ãã£ãäœçœ®ãã haystack æååã®å
é (offset ã®å€ãšã¯ç¡é¢ä¿) ããã®çžå¯Ÿäœçœ®ã§è¿ããŸãã æååã®éå§äœçœ®ã¯ 0 ã§ããã1 ã§ã¯ãªãããšã«æ³šæ ããŸãããã needle ãèŠã€ãããªãå Žå㯠false ãè¿ããŸãã ããã¥ã¡ã³ãã«ã¯äžèšã®èª¬æã«åãããŠã以äžã®ããã«èŠåãèšèŒãããŠããã ã€ãŸãã strpos() 颿°ã¯ã ãæååã®å
é ã«ããŒã¯ãŒããååšããå Žå㯠0ããè¿ãããæååã«ããŒã¯ãŒããååšããªãå Žå㯠FALSEããè¿ã ã®ã ã ãããã©ãã ãå±éºãªããšããããªãã PHPer ã§ããã°ãããã ããã â strpos() ãæå³ããªãåããããã³ãŒã <?php if ( strpos ( "ãåãã¡ã¯èª°ã ïŒ" , "ãªãã " ) ) { echo "ãªãã ããã ãšèããããããããã" ; // 衚瀺ãããªã echo "çããŠããããäžã®æ
ã" ; // ïŒæå³éãïŒ } if ( strpos ( "ãªãã ãåãã¡ïŒ" , "ãªãã " ) ) { echo "ãªãã ããã ãšèãããã \n " ; // 衚瀺ãããªã!! echo "çããŠããããäžã®æ
ã" ; // ïŒ"ãªãã "ãå«ãã®ã«...ïŒ } <?php $ result = strpos ( "ãåãã¡ã¯èª°ã ïŒ" , "ãªãã " ) ; var_dump ( $ result ) ; // bool(false) â "ãªãã "ããªãã®ã§ FALSE ãè¿ã $ result = strpos ( "ãªãã ãåãã¡ïŒ" , "ãªãã " ) ; var_dump ( $ result ) ; // int(0) â "ãªãã "ãæååã®å
é ã«ååšããã®ã§ 0 ãè¿ã! äžèšã®éããæååã®å
é ã«ããŒã¯ãŒããååšããå Žå㯠0 ãè¿ã£ãŠããã®ã§ã ãã®ãŸãŸæ¡ä»¶åŒãšããŠå©çšãããšã"æé»ã®å倿"ãè¡ããæå³ããŠããªãæ¯èŒçµæã«ãªã£ãŠããŸãã ãã®åé¡ã¯ããŸããŸãªèšäºã§åãäžããããŠããããã«ã !== ã«ãããå³å¯ãªæ¯èŒããè¡ãããšã§åé¿ã¯å¯èœã ã ããã«ãããå³å¯ã« FALSE ãè¿ã£ãŠããæã®ã¿æ€ç¥ããããšãã§ããã â
strpos() ãæå³éãã«åããã³ãŒã <?php if ( strpos ( "ãªãã ãåãã¡ïŒ" , "ãªãã " ) !== FALSE ) { echo "ãªãã ããã ãšèãããã \n " ; // 衚瀺ããã echo "çããŠããããäžã®æ
ã" ; // ïŒæå³éãã®æåïŒ } ãã¡ããããã®ãšã != ã¯äœ¿ã£ãŠã¯ãããªãã0 ãè¿ã£ãŠãããšãã« true ãšå€å®ããŠããŸãããã ã ãããã ãããïŒ strpos() ãæååæ€çŽ¢ç®çã«å©çšããå Žåãããã ãã®ããšãçè§£ããäžã§å©çšããå¿
èŠãããã ãŸãããããã®èæ
®ããã£ããå¿ãããšããããŒã¯ãŒããæååã®å
é ã«ãããšãã ãæå³ããªãæåããããã°ããçã¿åºãããšã«ãªãã ããã äœèšãªããšãèããªããå®è£
ãããããã ã£ãããæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã strstr() ã䜿ãã¹ãã§ãªãçç± strstr() ãåãã ãæ¯èŒçµæãæå³ããªãå€ã«ãªãå¯èœæ§ãããã strstr() ã®å®çŸ©ã¯ä»¥äžã®ãšããã php .netïŒ strstr strstr(string $haystack, string $needle, bool $before_needle = false): string|false haystack ã®äžã§ needle ãæåã«çŸããå Žæãå«ããŠããããæååã®çµãããŸã§ãè¿ããŸãã ãäžç¥ã éšåæååãè¿ããŸãã needle ãèŠã€ãããªãå Žå㯠false ãè¿ããŸãã strpos() ã®å Žåã¯ä»¥äžã®ãããªã³ãŒããæžãããšã§æå³ããªãåããããŠããŸãã以äžã®äŸã§ã¯ã æ€çŽ¢å¯Ÿè±¡ã§ãã "0" ãæååäžã«ååšããã®ã«é¢ããããæååã衚瀺ãããŠããŸãã â strstr() ãæå³ããªãåããããã³ãŒã <?php if ( strstr ( "ä»ããè²·ãã¹ãæè¡æžããã10" , "0" ) ) { echo "æååäžã« 0 ãããã!" ; // æå³ãã衚瀺ãããªã!! } <?php $ returnVal = strstr ( "ä»ããè²·ãã¹ãæè¡æžããã10" , "0" ) ; var_dump ( $ returnVal ) ; // string(1) "0" äœãã strstr ãšããååãæ€çŽ¢ã£ãœããªããããããæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ããã preg_match() ã䜿ãã¹ãã§ãªãçç± åçŽãªæååæ€çŽ¢ã§ããã°ã preg_match() ã䜿ãã¹ãã§ãªãã php .netïŒ strpos preg_match( string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0 ): int|false pattern ã§æå®ãã æ£èŠè¡šçŸ ã«ãã subject ãæ€çŽ¢ããŸãã ãäžç¥ã preg_match() ã¯ãpattern ãæå®ãã subject ã«ãããããå Žåã« 1 ãè¿ããŸãã ãããããªãã£ãå Žå㯠0 ãè¿ããŸãã 倱æããå Žåã« false ãè¿ããŸã ããã§ã®ã倱æããå Žåããšã¯ãæå®ãã æ£èŠè¡šçŸ ã®ãã¿ãŒã³ãäžæ£ãªå Žåãå«ãŸããã ã€ãŸãã preg_match() ã§ã¯ æå®ãã æ£èŠè¡šçŸ ãééã£ãŠããå Žå㯠FALSE ãè¿ããæååã«ãããããªãã£ãå Žå㯠0 ãè¿ã ã®ã ã ãã£ãŠåè¿°ã®é¢æ°ãšåãããã«çµæã®æ¯èŒã§èª€ã£ãå®è£
ãè¡ãªã£ãŠããŸãå¯èœæ§ãé«ããªã£ãŠããŸããé»ã£ãŠæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã¹ãã ã ããããããŒã¯ãŒããå
é ã«ããããç¥ããããã ããšãã人㯠å°ãªããšã strpos() ã¯å±ãªããæååã®å
é ã«ããŒã¯ãŒãããããšã㯠0 ãããŒã¯ãŒããååšããªãå Žå㯠FALSE ãè¿ãããæ¯èŒæã«ãã°ãçºçãããããªãã ãã®å Žåã¯ãåãã PHP8.0 ã§è¿œå ããã str_starts_with () ã䜿ãããæ»ãå€ã bool ã®ã¿ã§ããå®å
šã«ãªãã ããã *6 ãæ¥æ¬èªã§ã䜿ããã®ïŒããšã®çåã«ã€ã㊠ãã¡ãã䜿ããã str_contains() ã® RFC ã«ãã«ããã€ãæååã«ã€ããŠã®èšèŒãããã *7 å®å¿ããŠæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã ãã£ãšè©³ããïŒ ãã®é¢æ°ã PHP8.0 ã§å®è£
ãããããšã«ãªã£ã詳ããçµç·¯ã¯ãåœæã® RFC ã ããŒãžãªã¯ ãšã¹ ãã確èªãããšããã ããã ã¹ã¢ãŒã«ã¹ã¿ãŒãã«ãããã倧æåå°æåãåºå¥ãã仿§ã®ã¿å®è£
ããããšãããã«ããã€ãæåãžã®å¯Ÿå¿ã«ã€ããŠã®æèŠãªã©ã確èªã§ããã PHP RFC: str_contains Internals Mailing Lists ææ¡ãšè°è« æç¥šéå§ æç¥šå®äº ããŒãžãªã¯ãšã¹ã ãã£ãããšè°è«ãè¡ãããããšã確èªããããæååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã ããã§ããã£ãã ãã æååæ€çŽ¢ã«ã¯ str_contains() ã䜿ãã¹ãçç±ãããã£ãã ããã str_contains() ã®æ¹ãä»ã®é¢æ°ã䜿ãããçŽæçã§ããããªã«ããç¡çšãªå¿é
ãããªããŠæžãã ãªãä»ãŸã§ãã®é¢æ°ããªãã£ãã®ãäžæè°ã ããå®è£
ãããããã«ã¯ç©æ¥µçã« str_contains() ã䜿ãã ãïŒãªãã ã£ãŠïŒ str_contains() ã undefined function ã§ãšã©ãŒã«ãªãïŒïŒ ... PHP ã®ããŒãžã§ã³ã 7.4ïŒ ãªãã»ã©ããããããããããããªãã諊ãã¯å¿ã®é€çãšãããã®ã ã www.php.net Written by: Y-Kanoh *1 : https://www.php.net/archive/2020.php#2020-11-26-3 *2 : https://www.php.net/manual/ja/function.str-contains.php *3 : https://www.php.net/supported-versions.php *4 : https://www.php.net/manual/ja/function.strpos.php *5 : https://www.php.net/manual/ja/function.strstr.php *6 : https://www.php.net/manual/ja/function.str-starts-with.php *7 : https://wiki.php.net/rfc/str_contains
ã¯ããã« ã¿ãªããããã«ã¡ã¯ã€ã³ãã©ãšã³ãžãã¢ã®a_renrenã§ãã æ¥ã
ããµãŒããéçšãããæ¹ã§ããã°ããµãŒãã®äžå
·åãé«è² è·ãªã©ã§åŒãèµ·ããããã¢ã©ãŒãã®å¯Ÿå¿ããŠããããšæããŸãã ãã®å¯Ÿå¿æé ã¯æé æžãšããŠãŸãšãŸã£ãŠããããšãå°ãªããä»ãŸã§ã®çµéšåã«åºã¥ããŠå¯Ÿå¿ãè¡ã£ãããããã©ã³ã¡ã³ããŒã«é Œã£ããããŠãããšãããå°ãªããªãããšæããŸãã èªåã®ããŒã ãåã
ã§æé ãããŠããŠããŸãšãããããŠããŸãããå
±éã®æé ãã»ãŒãªãç¶æ³ã§ããããã®ãããªçŸç¶ãæéãããããã¢ã©ãŒãã®å¯Ÿå¿æé ãäœæããã®ã§ãä»åã¯ãã®æã®æ¯ãè¿ãããããããšæããŸãã æåã°ããã«ãªã£ãŠããŸããèªã¿ã«ããããšæããŸããã容赊ãã ããã â» é害ãçºçããéã¯å¥é察å¿ãããŒãæé ããããŸãã®ã§ã察象å€ãšããŠããŸã â» äžéšãå®éã®éçšæ¹æ³ãšå€ããŠèšèŒãããããŠããŸãã®ã§ããäºæ¿ãã ãã ã¯ããã« ã¢ã©ãŒãã®å¯Ÿå¿æ¹æ³ ãªãåãçµãã ã®ã äœæãããã® ã¢ã©ãŒãå¯Ÿå¿æé ãäœæããŠã¿ãŠ ä»åŸã«ã€ã㊠ã¢ã©ãŒãã®å¯Ÿå¿æ¹æ³ ãŸãã¯ãèªåã®ããŒã ã§ã©ãããæãã§ã¢ã©ãŒãã察å¿ããŠããã軜ãã玹ä»ããŸãã èªåãæå±ããããŒã ã§ã¯2ã€ã®åæãæ
åœããŠããããã®2ã€ã®åæã®ã¢ã©ãŒãã®å¯Ÿå¿ããããªã£ãŠããŸãã åãµãŒãã¹ããšãµãŒãç£èŠã·ã¹ãã ïŒZabbixïŒã䜿çšããŠãµãŒãã®éçšç®¡çãè¡ã£ãŠããããã®ã·ã¹ãã ããã®ã¢ã©ãŒããããªã¬ãŒã«å¯Ÿå¿ãéå§ããŠããŸãã ãããã¢ã©ãŒãå¯Ÿå¿æ¹æ³ãããããªãã倿ã§ããªãå Žåã¯ãããŒã å
ã§ç¢ºèªãã詳ããã¡ã³ããŒã«å€æä»°ããªãã察å¿ãè¡ã£ãŠããŸãã ãªãåãçµãã ã®ã ãã®åãçµã¿ãããåã¯ä»¥äžã®ãããªèª²é¡ããããŸããã æ°ããã¡ã³ããŒãã¢ã©ãŒãã®å¯Ÿå¿ãè¡ãã«ãã 人ã«ãã£ãŠã¢ã©ãŒãã®å¯Ÿå¿æ¹æ³ã«å·®ããã ã¢ã©ãŒã察å¿ã®ããŠããŠãããŸãå
±æã§ããŠããªã äžéšã®ã¢ã©ãŒãã®å¯Ÿå¿ãå±äººåããŠãã ããŒã å€ã®äººãã¢ã©ãŒãã®å¯Ÿå¿ãè¡ãã«ãã çµéšãæµ
ããšããã«å¯Ÿå¿ãå¿
èŠãªãã®ãšããã§ãªããã®ã®å€æãé£ãã ãããã®èª²é¡ãå
æããããã«ãã¢ã©ãŒãã®å¯Ÿå¿æé ãä»åäœæããŸããã ç®çããŸãšãããšä»¥äžã®ãããªæãã§ãã ã¢ã©ãŒãã®å¯Ÿå¿æ¹æ³ãçµ±äžåãã察å¿ãã人ã«ããã°ãã€ãããªãã åã¡ã³ããŒãæã£ãŠããã¢ã©ãŒãã®å¯Ÿå¿æé ãå
±æã§ããå Žãã€ãã æ°ããã¡ã³ããŒãããŒã å€ã®ã¡ã³ããŒã§ãã¢ã©ãŒãã®1次察å¿ãã¹ã ãŒãºã«è¡ããããã«ãã ã¿ãŒã²ãããæ°ããã¡ã³ããŒãããŒã å€ãªã©ã®ããŸãåæã®ç¥èããªã人ã«ãããªãã¹ã倿ã«è¿·ããªãå
·äœçãªæé ãæèããŠäœæãè¡ããŸããã ãŸããå¯Ÿå¿æé ãšèšã£ãŠãæãšå Žåã«ãã£ãŠå¯Ÿå¿æ¹æ³ãå€ãããããæäœã§ããã®æé ãèŠãã°1次察å¿ãè¡ããããã«ããŸããã äœæã¯ããçšåºŠãèªåã®çµéšãªã©ãããšã«ãããå°ãã€ãããæ
å ±ãè¶³ããªããã°è©³ãã人ã«ç¢ºèªãã€ã€äœæãè¡ããŸããã äœæãããã¹ãŠã®ã¢ã©ãŒãã®å¯Ÿå¿æé ãããŒã å
ã§ã¬ãã¥ãŒäŒãéããŠæèŠãåããæçµçãªåœ¢ã«ããŠãããŸããã äœæãããã® ä»åãã¢ã©ãŒãå¯Ÿå¿æé ã¯ã Markdown 圢åŒã§äœæããããã瀟å
ã®GitLabã«ãããŠç®¡çããããã«ããŸããã Markdown ã«ããã®ã¯ãã·ã³ãã«ã«äœæã§ããããçšåºŠé圢ãäœæããŠããã°ãä»åŸä»ã®ã¡ã³ããŒãäœæããéã ããŸãè² æ
ããªãããšæã£ãããã§ãã GitLabã§ç®¡çããã®ã¯ã倿Žã®å·®åã管çããããã Markdown 圢åŒã§è¡šç€ºãããŠèŠãããããã§ãã ä»åäœæãããã©ãŒãããã¯ä»¥äžã®ãããªæãã§ãã å®éã®ã¢ã©ãŒãå¯Ÿå¿æé ã¯ãèŠãã§ããªãã®ã§ããã©ãŒããããšãµã³ãã«æ
å ±ã§ãèš±ããã ããããã ()å
ã®ã¯èª¬æã§å®éã«ã¯èšèŒããŠããŸããã ã¢ã©ãŒãã®å€§ãŸããªåé¡ä»¥å€ã¯ç®æ¬¡ã«ãªããªãããã« Markdown äžã§å¥éèšå®ããŠããŸãã ## ãã£ã¹ã¯é¢é£ã(ã¢ã©ãŒãã®å€§ãŸããªåé¡ ãã£ã¹ã¯é¢é£ã®ã¢ã©ãŒãã¯ãã®åé¡ã®äžã«ãŸãšãã) ### ã»Free disk space is less than 10% on volume /testã(éç¥ãããã¢ã©ãŒãã®ã¿ã€ãã«) #### ã察象ãµãŒãã WebãµãŒã #### ãã¢ã©ãŒãå
容ã /testã®ãã£ã¹ã¯å®¹éã10%以äžã®ç¶æ
(ã¢ã©ãŒãã®çºå ±æ¡ä»¶ãã¢ã©ãŒããçºå ±ãããããšã§ã©ãããç¶æ
ãªã®ããèšèŒ) #### ãã¢ã©ãŒãçºçåå ã - ç¡é§ãªãã¡ã€ã«ãé
眮ããç¶ããŠãã - Bã®åŠçã§äžå
·åãçºçããŠãã (èããããåå ãèšèŒ) (調æ»ã®éã«ããã«èšèŒããèããããåå ãã調æ»ãè¡ããããããã«ãã) #### ãã¢ã©ãŒãå¯Ÿå¿æé ã (ã¢ã©ãŒãã®å¯Ÿå¿æé ãèšèŒ) 1. ãã£ã¹ã¯äœ¿çšéã確èªãã ç£èŠã·ã¹ãã ã§çŽè¿ã®/testã®ãã£ã¹ã¯ã®äœ¿çšéããã€ããã©ã®ãããå¢ããŠããã®ã確èªãã 1. åé€ããŠãããäžèŠãªãã¡ã€ã«ã確èªãã äžèŠãªãã¡ã€ã«ã®å€æãã§ããªãå Žåã¯ããŒã å
ã«ç¢ºèªãã âåé€ããŠããããã¡ã€ã« ã»ãã¡ã€ã«åã«testãå«ãŸããŠãããã® ã»æçµæŽæ°æ¥ã1幎åã®ãã® ```bash /testã®çŸç¶ã®ç©ºã容éãç¢ºèª $ df -h /test /testé
äžã«ãããã¡ã€ã«ã確èªããäžèŠãªãã¡ã€ã«ããªã¹ãã¢ãããã $ ls -la /test ``` 1. äžèŠãªãã¡ã€ã«ãåé€ãã ```bash äžèšã§ç¢ºèªããäžèŠãªãã¡ã€ã«ãåé€ãã $ sudo rm /test/äžèŠãªãã¡ã€ã« ``` 1. Bã®åŠçãæ£åžžã«åããŠãããã°ãã確èªãã ãšã©ãŒãåºãŠããããã§ããã°ãããŒã å
ã«å
±æããåå ã®èª¿æ»ããããªã ```bash Bã®åŠçã®ãã°ã確èªãããšã©ãŒãåºåãããŠãªãã確èªãã $ grep 'error' /var/log/B.log ``` GitLabäžã§ã¯ã以äžã®ããã«è¡šç€ºãããŸãã GitLabã§ã®è¡šç€ºå
容 ã¢ã©ãŒãå¯Ÿå¿æé ãäœæããŠã¿ãŠ ä»åã¢ã©ãŒãã®å¯Ÿå¿æé ãäœæããŠããããŸã ææ¥ã¯çµã£ãŠããªããããããŸã掻èºã¯ã§ããŠãªãããã§ããã 以åããã¢ã©ãŒãå¯Ÿå¿æ¹æ³ãçµ±äžã«ãªã£ãããããŠããŠã®å
±æãè¡ãããããªã£ããã æ°ã¡ã³ããŒãžã®ã¬ã¯ãã£ãŒãè¡ãããããªã£ãããšæããŸãã äžèšä»¥å€ã«ããã¢ã©ãŒãã®å¯Ÿå¿æé ãäœæããŠããéçšã§ã¡ãªããããããŸããã äžã€ç®ã¯ãäžèŠãªã¢ã©ãŒããæŽãåºããåé€ããããšãåºæ¥ãããšã§ãã ã¢ã©ãŒãã®å¯Ÿå¿æé ãäœæããŠããäžã§ããããããªã¢ã©ãŒããèŠã€ãããŸããããã äœã®ããã®ã¢ã©ãŒããªã®ãããããªãã¢ã©ãŒã ä»ã¯ããäžèŠã«ãªã£ãããåé€ãããæ®ãç¶ããŠããã¢ã©ãŒã åããããªããšãç£èŠããŠããã¢ã©ãŒããªã© äžèšã®ããã«å¿
èŠãªã¢ã©ãŒã以å€ã«æ§ã
ãªã¢ã©ãŒããèŠã€ãããŸããããã®èŠçŽãããã®æ©äŒã«è¡ããããšã§ãäžèŠãªã¢ã©ãŒããåæžããããšãã§ããäžå¿
èŠãªå¯Ÿå¿ããè² æ
ãæžããŸããããŸããããè¯ãç£èŠæ¹æ³ãèŠã€ãã£ãããšãããŸã泚ç®ãããŠããªãã£ãç®æã«ã¡ã¹ãå
¥ããããšãã§ããŸãããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããããã äºã€ç®ã¯ãã¢ã©ãŒãããªããªãããä»çµã¿ã¥ããã®èŠçŽãããããããšãã§ããããšã§ãã ã¢ã©ãŒãã®äºæž¬ãããçºçåå ãæ¢ã£ãŠããäžã§çŸç¶ã®èšå®å€ããã¹ãã§ãªãããšã«æ°ã¥ããèšå®å€ã®æ¹åããããªã£ããã ããæ¡ä»¶ã§å€±æããå¯èœæ§ããã ã¹ã¯ãªãã ã®åŠçã倱æããªãããã« ã¹ã¯ãªãã ã®å®è£
æ¹æ³ãå€ãããªã©ã®èŠçŽããè¡ãããšãã§ããŸããã ãŸããäœæããŠãããªãã§å¯Ÿå¿ããããªãã£ã課é¡ããããŸããã 䌌ããããªã¢ã©ãŒãã®å¯Ÿå¿æé ãäžã€ã«ãŸãšãããããã¢ã©ãŒãããšã«äžéšäŒŒããããªå¯Ÿå¿æé ãããããã«èšèŒãããããã¡ã³ããã³ã¹æ§ãæªãç¶æ
ã«ãªããŸããã 䌌ããããªæé ãå€åºããããããšãæã£ãã®ã§ããã察å¿ããã¡ã³ããŒãããããªãã¡ã€ã«ãè¡ã£ããæ¥ãããããšå¯Ÿå¿ãã«ããããšæãããããŠå€åºãã¯ããŸããã§ããã ä»åŸã察å¿ã§ãããµãŒããå¢ããã«ã€ããã¢ã©ãŒãã®çš®é¡ãå¢ããããã¡ã³ããã³ã¹æ§ãæªããªããããªã®ã§ãæ©ãã«äœæè
ãšå¯Ÿå¿è
ã®ã©ã¡ãã®è² æ
ã軜æžã§ããããã«æ§æãå€ããŠããå¿
èŠãããããã§ãã ä»åŸã«ã€ã㊠ä»åã¯ãäžéšã®ãµãŒãã®ã¢ã©ãŒãå¯Ÿå¿æé ããäœæã§ããªãã£ããããä»åŸãäžèšã®èª²é¡ã解決ãã€ã€ãåŒãç¶ãæ®ãã®ãµãŒãã®ã¢ã©ãŒãå¯Ÿå¿æé ãäœæãããŒã ã§é²ããŠãããããšæããŸãã ãŸãã䞊è¡ããŠã¢ã©ãŒãã®åæžãã¢ã©ãŒã察å¿ã®èªååãªã©ã®æ ¹æ¬çãªå¯Ÿå¿ãé²ããŠãããã°ãšæã£ãŠããŸãã çããããã®æ©äŒã«ãã²ã¢ã©ãŒãã®èŠçŽããå¯Ÿå¿æé ã®äœæã«åãçµãã§ã¿ãŠã¯ãããã§ããããã æåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã
ã¯ãããŸããŠãé
é
ã¡ãŒã«éçºèª²æå±Jazumaã§ãã æ¬çš¿ã§ã¯æšå¹Ž2022幎ã«åœç€Ÿãããã¯ãé
é
ã¡ãŒã«ã«ãããŠCI/CDãã€ãã©ã€ã³ãæŽåããéçšããã®çµæã«ã€ããŠã玹ä»ããŸãã CIããŒã«ã®äœ¿ãæ¹ãCI/CDãšã¯äœããšãã£ãå
容ã¯åãæ±ããŸãããããããããäºæ¿ãã ããã ãããã¯ãã«ã€ã㊠2022幎éå§æç¹ã®ç¶æ³ æœç1: éçšã«ãŒã«ã®æŽåãšCIããŒã«ã®ç§»è¡ æœç1ã®çµæ æœç2: ãµãã·ã¹ãã æ§ç¯ã«äŒŽããŠããããã¹ãã»éçè§£æã®æŽå æœç2ã®çµæ æœç3: ãµãã·ã¹ãã ã®æ€èšŒç°å¢ãžã®èªåããã〠æœç3ã®çµæ æœç4: ã¡ã€ã³ã·ã¹ãã ã®æ€èšŒç°å¢ãžã®èªåããã〠æœç4ã®çµæ æœç5: ã¢ãŒããã¯ãã£ãã¹ãã®å°å
¥ã»éçè§£æã®æ¡å
æœç5ã®çµæ çŸæç¹ã®èª²é¡ 1. æããããã³ãŒãã«ã¯ãã¹ãã远å ã§ããŠããªã 2. èªåãããã€ã®ã¹ã³ãŒããã¢ããªã±ãŒã·ã§ã³ã®ã¿ã«çãŸã£ãŠãã æåŸã« ãããã¯ãã«ã€ã㊠åŒç€Ÿãããã¯ãé
é
ã¡ãŒã«ã¯2007幎ãµãŒãã¹éå§ã®é·å¯¿ãµãŒãã¹ã§ãã www.hai2mail.jp é·ããã客æ§ã«ãæé¡§ããã ããŠããŸããããCIç°å¢ãæªæŽåã» ãŠããããã¹ã ãå°ãªãã»éçè§£æããªãç®èŠã§ã³ãŒãã¬ãã¥ãŒããçéçºç°å¢ã»äœå¶ã«èª²é¡ããããŸããã ããã§ãéçºäœå¶ãæ¹åãã¹ã2022幎床ã«CIç°å¢ãæ¡å
ããŸããã 2022幎éå§æç¹ã®ç¶æ³ ãŠããããã¹ã ã¯ã¡ãã£ãšãã E2Eãã¹ãã¯æŽåãããŠãã éçè§£æã¯ååšããªã Jenkinsã§pushã®åºŠã«ãã¹ããå®è¡ããŠããããããŸãéçšãããŠããªã æœç1: éçšã«ãŒã«ã®æŽåãšCIããŒã«ã®ç§»è¡ ãŸãã¯4ã€ç®ã®åé¡ãè§£æ¶ããããã«CIã®éçšã«ãŒã«ãæŽåããŸããã ã«ãŒã«ãšèšã£ãŠãè€éãªãã®ã§ã¯ãªããããã¹ãã倱æãããã¡ã³ããŒã®ã¡ãŒã«ã¢ãã¬ã¹ã«éç¥ãé£ã¶ãéç¥ãåãããåå ã調æ»ããããšããã·ã³ãã«ãªãã®ã§ããã ãšã¯ããã«ãŒã«ãæŽåãããããšã§ãã¹ãã倱æããæã®å¯Ÿå¿æŒããæžããŸããã ãŸããåãããŠCIããŒã«ãJenkinsããGitLabCI/CDã«ç§»è¡ããŸããã çç±ã¯ä»¥äžã®éãã§ãã Jenkinsfileãããgitlab-ci.ymlã®æ¹ãèªã¿æžããããããšããæèŠããããããã«å¯Ÿããåè«ãç¹ã«ãªãã£ã JenkinsãšGitLabã飿ºããæéãæžã GitLabCI/CDã®æ¹ãUIãæŽç·ŽãããŠãã䜿ãããã æœç1ã®çµæ ãã¹ããæ¡å
ããããã§ã¯ãªããããåçãªå¹æã¯ãããŸããã§ããã ãšã¯ãããã®æœçã«ãã£ãŠããŒã ã®CIåºç€ãæŽã£ããããåŸã®æ¹åã®åå°ãšãªãéèŠãªæ¹åã ã£ããšèšããŸãã æœç2: ãµãã·ã¹ãã æ§ç¯ã«äŒŽã ãŠããããã¹ã ã»éçè§£æã®æŽå 2022幎8æã«ãæ¥ç𮿥æ
ã»é
ä¿¡ç®çå¥ã¹ã³ã¢ã®ç¢ºèªããšããæ©èœããªãªãŒã¹ããããšã«ãªããŸããããã®æ©èœã§ã¯ãå
šãµãŒãå
šã¢ã«ãŠã³ãã®ã¹ã³ã¢(ã¡ãŒã«ã® éå° çãæ¿å
¥ãããURLã®ã¯ãªãã¯ç)ãéèšããããšããèŠä»¶ãæ±ããããŸããã www.hai2mail.jp ãã®èŠä»¶ãæºããããã«ãããŒã¿éèšçšã®æ°èŠãµãã·ã¹ãã ãæ§ç¯ããããšã«ãªããŸããã æ°èŠãµãã·ã¹ãã ã¯æ¢åã·ã¹ãã ã®ã³ãŒãã ã¢ãŒããã¯ã㣠ã®åœ±é¿ãåããªããšããããšã§ããéçè§£æãš ãŠããããã¹ã ããã£ãããšäœã蟌ããããšããæ¹éã§éçºãé²ããŸããã æ°èŠãµãã·ã¹ãã ã¯ã¡ã€ã³ã·ã¹ãã ãšåæ§ã« PHP ã§éçºãããã ãŠããããã¹ã ã«ã¯ PHPUnit ã»éçè§£æã«ã¯PHPStanãæ¡çšããŸããã ãã®èŸºãã¯æ¥µããŠãªãŒãœããã¯ã¹ãªæè¡éžå®ã ã£ãã®ã§ã¯ãªãããšæããŸãã CIã®å®è¡ã«ãŒã«ãç¹ã«å€ãã£ããšããã¯ãªããpushãããŒãžã®åºŠã«ãã€ãã©ã€ã³ãå®è¡ãããšãããã®ã§ãã æœç2ã®çµæ ãã®æœçã¯çµæãšããŠã¯æåã ã£ããšèšããŸããå
·äœçã«ã¯2ã€ã®ææã«ã€ãªãããŸããã 1ã€ã¯ãæ¥ç𮿥æ
ã»é
ä¿¡ç®çå¥ã¹ã³ã¢ã®ç¢ºèªãæ©èœãèšç»éããªãªãŒã¹ã§ããäžããã®æ©èœã«é¢ããŠ2023幎6æçŸåšäžå
·åãçºçããŠããªãããšã§ãã ãã®æ©èœã¯é£æåºŠãé«ãèšç»ã®é
ããªã©ãæžå¿µãããŠããŸããããäžèšã®éã倧ããªåé¡ãªããªãªãŒã¹ããããšãã§ããŸããããã®èŠå ã®äžã€ãšããŠéçè§£æãš ãŠããããã¹ã ã§ ãœãŒã¹ã³ãŒã ã®å質ãäœã蟌ãããšãã§ããããšããã£ãã®ã§ã¯ãªãããšæããŸãã ãã1ã€ã¯ã ãŠããããã¹ã ãæžãããšããæåãããŒã å
ã«åºãã£ãããšã§ãããæ¥çš®æ¥æ
ã»é
ä¿¡ç®çå¥ã¹ã³ã¢ã®ç¢ºèªãæ©èœã®æ¬¡ã®ããŒãžã§ã³ã«ãŠããã©ããŒã¡ãŒã«ããšããå€§èŠæš¡ãªæ°æ©èœããªãªãŒã¹ãããŸããããã®æ©èœã®éçºæã«ãå¯èœãªéã ãŠããããã¹ã ãäœæãããŸããã www.hai2mail.jp æœç3: ãµãã·ã¹ãã ã®æ€èšŒç°å¢ãžã®èªåããã〠ãã€ãã©ã€ã³ã«ãµãã·ã¹ãã ãæ€èšŒç°å¢ã«èªåã§ãããã€ããåŠçã远å ããŸããã ãã®æœçã«ã¯æç¢ºãªç®çããã£ãããã§ã¯ãªãããã£ããã®æ©äŒã ãèªååã§ããæã¯ããŠãããããããã®æèã§é²ã¿ãŸããã ä»çµã¿ãšããŠã¯ããã·ã³ãã«ã§ã¿ã°ãäœæãã â ã¢ããªã±ãŒã·ã§ã³ã«å¿
èŠãªãã¡ã€ã«äžåŒãå«ãã tar.gzãã¡ã€ã«ãäœæ â æ€èšŒç°å¢ã«ãããã€ãã ãšãããã®ã§ããã æœç3ã®çµæ ãã®æœçã¯ããŸã广ããããŸããã§ããããµãã·ã¹ãã èªäœã®å€æŽé »åºŠãäœããããã€ãå®è¡ãããæ©äŒãã»ãšãã©ãªãã£ãããšã«å ããä»çµã¿ã宿ããææãé
ããæŽ»çšã§ããå Žé¢ãç¡ãã£ãããšãåå ã§ãã ããããä»ãŸã§CI/CDãã€ãã©ã€ã³ã®å®è£
çµéšãç¡ãã£ãã¡ã³ããŒãæ
åœããããšã§ããŒã å
ã«ç¥èŠãåºãŸã£ãä»ãé説çã«ä»¥äžã®ãããªæèšãåŸãããŸããã èªåãããã€ã¯å€æŽé »åºŠãé«ãã·ã¹ãã ããåªå
çã«å®è£
ãã¹ãã§ãã æ©èœã宿ããŠããèªåãããã€ã®å®è£
ã«çæããŠãé
ããæ©èœéçºãšäžŠè¡ããŠé²ããå¿
èŠããã æœç4: ã¡ã€ã³ã·ã¹ãã ã®æ€èšŒç°å¢ãžã®èªåããã〠2022幎ã®ç§ã« ã·ã¹ãã ãã¹ã ãæ¹åããåãçµã¿ãè¡ããŸããã ããã§ã¯ããã¹ãã®å質ãäžãã( = ãã°ãæ€ç¥ã§ããããã«ãã)ãããã¹ããå¹çåãã( = å·¥æ° ãåæžãã)ããšãã2ã€ã®ç®çã®å
æ¹åäœæ¥ãè¡ããŸããã èªåãããã€ã¯2ã€ç®ã®ç®çãéæããããã«å®æœããŸããã 詊ç®ã§ã¯ ã·ã¹ãã ãã¹ã äžã®ãããã€ããã³ãããã€äœæ¥æŒãã«èµ·å ããææ»ãã幎é10æéçšåºŠããã£ãŠãããããèªååã®å¹æã倧ãããšå€æãããŸããã ä»åã¯æœç3ã®æèšãèžãŸããŠã倿Žé »åºŠã®å€§ããã·ã¹ãã ã察象ã«ãããã ã·ã¹ãã ãã¹ã ãŸã§ã«å®äºãããããšããæ¹éã§é²ããŸããã å
·äœçã«ã¯å¯Ÿè±¡ãã¡ã€ã³ã·ã¹ãã ã«çµãããããã€åŠçã远å ããŸããã ä»åã¯å
šèªååããããšããããšã§ãã¿ã°ã®äœæã§ã¯ãªãããªãªãŒã¹çšã®ãã©ã³ããžã®ããŒãžããããªã¬ãŒãšããŠããã〠ã¹ã¯ãªãã ãèµ·åããå®è£
ãšããŸããã æœç4ã®çµæ ãã®æœçã¯æåããŸããã ã宿çã«ãªãªãŒã¹ãã©ã³ããžã®ããŒãžã確èªããŠæ€èšŒç°å¢ãžã®ãããã€ãå®è¡ããããšããéåãç¡ããªã£ãããšã§çšŒåã«ç©ºããã§ããä»ãå²ã蟌ã¿äœæ¥ããªããªããŸããã ãŸããæ€èšŒç°å¢ãåžžã«ææ°ã®ç¶æ
ã«ä¿ãããŠããããšãæ
ä¿ãããããã«ãªã£ããã äžå
·åãèŠã€ãã£ãå Žåã®åå 調æ»ãã¹ã ãŒãºã«ãªããŸããã æœç5: ã¢ãŒããã¯ã㣠ãã¹ãã®å°å
¥ã»éçè§£æã®æ¡å
2023幎5æã«æ·»ä»ãã¡ã€ã«ãçŽæ¥ã¡ãŒã«ã«æ·»ä»ããã«éä¿¡ããæ©èœããªãªãŒã¹ããŸããã www.hai2mail.jp ãã®æ©èœã«ãããŠããµãã·ã¹ãã ãæ°ããæ§ç¯ããŸããã ä»åã¯æœç2ã®ãã㪠ãŠããããã¹ã ã»éçè§£æã«å ããŠæ°ãã2ã€ã®ããšã詊ã¿ãŸããã 1ã€ã¯ ã¢ãŒããã¯ã㣠ãã¹ãã§ãã deptrac ãšããããŒã«ãçšããŠã¯ã©ã¹éã®äŸåé¢ä¿ãæ€æ»ããããã«ããŸããã ããã«ããã颿°ãã¯ã©ã¹åäœã®å質ã ãã§ã¯ãªããã¯ã©ã¹å士ã®äŸåé¢ä¿ãé©åã«èšå®ãããŠãããããšããç¹ãŸã§æ
ä¿ã§ããããã«ãªããŸããã ãã1ã€ã¯éçè§£æã®æ¡å
ã§ããæœç2ã§å°å
¥ããphpStanã§ã¯äž»ã«åå®çŸ©ãæªå®çŸ©å€æ°ã®æ€åºçãäžè¬çãªèгç¹ãæ€æ»ããŸããã ä»åã¯ã³ãŒã èŠçŽéå ã®æ€åºãªã©ãããããŒã ã®å®æ
ã«å³ãã芳ç¹ãæ€æ»ããããšã«ãªããŸããã éçè§£æããŒã«ãšããŠã¯ PHP_CodeSniffer ãæ¡çšããŸããã (éçè§£æã¯ããŸãã«å®è¡ã§ããæ¹ãææ»ãã®ã³ã¹ããå°ããæžãã®ã§ã PHP _CodeSnifferã¯CIã«å ã㊠IDE äžã§ãå®è¡ã§ããããã«ããŸãããæ¬çš¿ã®è¶£æšããã¯éžããŸãã®ã§è©³ããã¯åãäžããŸããã) æœç5ã®çµæ ãã®æœçãæœç2ãšåæ§ã«æåããŸãããç¹ã« PHP _Codesnifferå°å
¥ã®æ©æµã倧ããã£ãã§ãã ä»ãŸã§ã¯ç®èŠã§ç¢ºèªããŠããé
ç®ã æ©æ¢°ç ã«æ€åºã§ããããã«ãªã£ããããã³ãŒãã¬ãã¥ãŒã®è² æ
ã倧ããæžããŸããã PHP _Codesnifferå°å
¥ã«ã€ããŠã¯ãã¡ãã®èšäºã§ãè§ŠããŠããŸãã®ã§ãã²ãäžèªãã ããã tech-blog.rakus.co.jp çŸæç¹ã®èª²é¡ 2022幎ã«ã¯é
é
ã¡ãŒã«éçºããŒã ã«ãããŠCI/CDãã€ãã©ã€ã³ã倧ããæ¡å
ãããŸããã ãããã課é¡ãå€ãæ®ã£ãŠããŸãã 1. æããããã³ãŒãã«ã¯ãã¹ãã远å ã§ããŠããªã ãã¹ãã³ãŒãã¯äž»ãšããŠæ°èŠã«è¿œå ãããã³ãŒãã察象ã«å®è£
ãããŸããã ããããé
é
ã¡ãŒã«ã®ã³ã¢æ©èœãæ¯ãç¶ããŠããå€ãã³ãŒãã«ã¯ã»ãšãã©ãã¹ãã³ãŒãã远å ããããšãã§ããŠããŸããã æããããã³ãŒãã¯è€é床ãé«ãã£ããå¯çµåã ã£ããããŠããããã¹ãã³ãŒããæžãããšãã§ããªãç¶æ
ã§ãã ãã¹ããæžãããã« ãªãã¡ã¯ã¿ãªã³ã° ããããšããŠã圱é¿ç¯å²ã倧ãããªããªãæãåºããªããšãã(ãããã) ãžã¬ã³ãã«çŽé¢ãç¶ããŠããŸãã 2. èªåãããã€ã®ã¹ã³ãŒããã¢ããªã±ãŒã·ã§ã³ã®ã¿ã«çãŸã£ãŠãã çŸç¶ã§ã¯èªåãããã€ã®å¯Ÿè±¡ã¯ã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®ã¿ã§ããç°å¢èšå®ãããŒã¿ããŒã¹ã» ããã«ãŠã§ã¢ ã®å€æŽã¯æåã§è¡ãå¿
èŠããããŸãã æ¬æ¥ã§ããã°ç°å¢ã»ããŒã¿ããŒã¹ã» ããã«ãŠã§ã¢ å«ããŠåžžã«æ£ããç¶æ
ãåçŸã§ããããã«ãªã£ãŠããã¹ãã§ããã皌åã«äœè£ããªãã»ããŠããŠãè¶³ããªãããæãåã£ãŠããŸããã æåŸã« ãããŸã§ãèªã¿ããã ãããããšãããããŸããã ä»åŸãé
é
ã¡ãŒã«éçºããŒã ã§ã¯CI/CDãã€ãã©ã€ã³ã掻çšã㊠ããé«å質ãªãããã¯ããéçºã§ããããã«åªããŠãããŸãã