ãã®è¨äºã¯ ã¯ã©ã¹ã¿ã¼ Advent Calendar 2023 19æ¥ç®ã®è¨äºã§ãã æ¨æ¥ã¯ ChameleonO2 ããã®ãä½ããã§ãããå ¬é楽ãã¿ã§ããã
ã¯ã©ã¹ã¿ã¼æ ªå¼ä¼ç¤¾ã§ã½ããã¦ã§ã¢ã¨ã³ã¸ãã¢ã¨ãã¦åãã¦ãã id:Sixeight ã§ãã
ã¯ã©ã¹ã¿ã¼ã§ã¯ãã©ã³ã¯ãã¼ã¹éçºãå®ç¾ããããã«ãã£ã¼ãã£ãã©ã°ã使ã£ã¦ãã¾ãã ãã£ã¼ãã£ãã©ã°ã使ããã¨ã§ãã¨ãéçºãéä¸ã§ãã£ã¦ããå¤æ´ã¯å®å ¨ã«åä½ããç¶æ ã§ãã©ã³ã¯ã«åãè¾¼ã¾ãã¾ãã
ä»åã¯ãã£ã¼ãã£ãã©ã°ã使ã£ã¦éçºããã¨ãã«æèãã¦ãããããããªTIPSãå ±æãã¾ãã
TIPS1: å ã®ã³ã¼ãã¯ãã®ã¾ã¾ã«ãã
ãã£ã¼ãã£ãã©ã°ã§åå²ã追å ããã¨ãã«ãæ°ãå©ããã¦å®æã«ã³ã¼ãã®éè¤ãæ¸ãããã¨ãã¦ã¯ããã¾ããã ãã¨ãã³ã¼ããéè¤ãããã¨ã«ãªã£ãã¨ãã¦ããå¤æ´åã®ã³ã¼ãã¯åºæ¥ãã ããã®ã¾ã¾ã®å½¢ã§æ®ãããã«ãã¾ãããã
ãªããªããã£ã¼ãã£ãã©ã°ãå ¥ãããã¨ã§å ã®ã³ã¼ããå£ãã¦ãã¾ã£ã¦ã¯å ãåããªãããã§ãã ãã£ã¼ãã£ãã©ã°ããªãã®å ´åã«ã¯æåãå¤ãããªããã¨ãæ ä¿ãããã£ã¨ãç°¡åã¯æ¹æ³ã¯ã³ã¼ãã«æãå ¥ããªããã¨ã§ãã
以ä¸ã¯ãã®ãããç°¡åãªä¾ã§ããããªãªã¸ãã«ã®ã³ã¼ãããã£ã¨è¤éã ã£ãã¨ä»®å®ããã¨ãæåã®å¤æ´ã追ããããè² è·ã¯ good å´ã®ã³ã¼ãã®æ¹ãä½ãã®ã§ã¯ãªãã§ããããã
original
total := 0 total += 1 fmt.Printf("%d", total)
bad
total := 0 if featureFlag.IsHoge { total += 2 } else { total += 1 } fmt.Printf("%d", total)
good
if featureFlag.IsHoge { total := 0 total += 2 fmt.Printf("%d", total) } else { total := 0 total += 1 fmt.Printf("%d", total) }
TIPS2: æ¶ãã¨ãã®ãã¨ãèãã¦ãã
ãã£ã¼ãã£ãã©ã°ã«ããåå²ã¯æåããæ¶ããããã¨ã確å®ããã³ã¼ãã§ããæ¶ãã¨ãã®ãã¨ãèãã¦ããã«è¶ ãããã¨ã¯ããã¾ããã
ä¾ãã°ã以ä¸ã®ããã«ãã£ã¼ãã£ãã©ã°ãæå¹ãªã¨ãã«ç¹å®ã®å¦çãããããå ´åãå¦å®ã®æ¡ä»¶ã«ããããªãããããã¾ããã ãããããã£ã¼ãã£ãã©ã°ã使ãå¤ãã®å ´åã¯å¦çã足ããã¤ã¾ãè¯å®ã®æ¡ä»¶ã«ãªããã¨ãå¤ãã§ãã
bad
if !featureFlag.IsA { for _, digit := range digits { result = result * 10 + digit } }
ãã®1ã¤ã ããªãééããªãã¨ã¯æãã®ã§ããã沢山ã®åå²ãæ¶ããã¨ã«ãªãã¨ééãã¦ãã¾ãããããã¾ããã æ¶ãã¨ãã®ãã¨ãèããã¨ã¯ã以ä¸ã®ããã«éä¸ãã¦ã³ã¼ããèªã¾ãªãã¦ãæ¶ããããã«ããã¨ãããã¨ã§ãã
good
if featureFlag.IsA { // DO NOTHING } else { for _, digit := range digits { result = result * 10 + digit } }
追å ããã¨ãã«å°ãè¦å´ããã¨ãã¦ããæ¶ãã¨ãã®ãã¨ãèãã¦ãããæ¹ãäºæ ãæ¸ã£ã¦çµå±ã¯èªåãå©ãããã¨ã«ãªãã§ãããã
TIPS3: ä¾åã®è¡¨ç¾ãããã©ã°ãç¨æãã
ãªãªã¼ã¹ãç´°ããåå²ãããã¨ã¯è¯ããã©ã¯ãã£ã¹ã§ãããã ããããããã®ãªãªã¼ã¹ãä¾åãã¦ããå ´åã¯ãã£ã¼ãã£ãã©ã°ã§ã®åå²ãé£ãããªãã±ã¼ã¹ãçºçãã¾ãã 確å®ã«å段ã®ãã£ã¼ãã£ãã©ã°ãæå¹ã§ããã¤å¯¾è±¡ã®ãã£ã¼ãã£ãã©ã°ãæå¹ã§ãããã¨ãæ ä¿ããããã«ãå°ç¨ã®ãã£ã¼ãã£ãã©ã°ãç¨æããã¨èªç¥è² è·ãæ¸ãããã¨ãåºæ¥ã¾ãã
bad
if featureFlag.IsA && featureFlag.IsB { // ... }
good
// å®ç¾© IsCombinedAB := IsA && IsB // å®è£ if featureFlag.IsCombinedAB { // ... }
TIPS4: ã©ã¡ãããã¹ããã
ã¦ããããã¹ããæ¸ãã¨ãã«ããã£ã¼ãã£ãã©ã°ãæå¹ãªã±ã¼ã¹ã¨ãç¡å¹ãªã±ã¼ã¹ã®ã©ã¡ãã«ããã¹ãã追å ãã¦ã常ã«CIã§ã©ã¡ãã®ã±ã¼ã¹ããã¹ãããããã«ãã¾ãããã ãªã³ã±ã¼ã¹ã§æ°ãã追å ããã³ã¼ããåãã¦ãããã¨ã確èªãããã¨ã¯å½ç¶ãªããããªãã±ã¼ã¹ã§æ¢åã®ã³ã¼ããå£ãã¦ããªããã常ã«ç¢ºèªãã¦ãããã¨èªä¿¡ãæã£ã¦éçºéä¸ã®ç¶æ ã§ããªãªã¼ã¹ã§ããããã«ãªãã¾ãã
ã¤ã©ã¤ã©ä¼¼ããããªã³ã¼ããæ¸ãã®ã¯ãã¹ã®å ãªã®ã§ããã£ã¼ãã£ãã©ã°ã®ãªã³ãªãã±ã¼ã¹ãæ¼ããªãæ¸ãããããªãã«ãã¼ãç¨æãã¦ãä»çµã¿ã¨ãã¦ã©ã¡ãã®ãã¹ããæ¸ããããå¾ãªãç¶æ³ãä½ãã¾ãããã
ä¾
featureFlag.TestHelper(t, featureFlag.IsA func(t *testing.T) { // on case }, func(t *testing.T) { // off case }, }
åããã¦CIã§ã¯å ¨ã¦ã®ãã¹ãã±ã¼ã¹ããã£ã¼ãã£ãã©ã°ã®æ§åãåãæ¿ãã¦å®è¡ããããã«ãã¦ããã¨ããããããã«ãã¼ã使ãå¿ããã¨ãã¹ããè½ã¡ã¦æ°ã¥ããããã«ãªãã¾ãã
TIPS5: ããã«æ¶ã
å½¹ç®ãçµãããã£ã¼ãã£ãã©ã°ã¨ãªãã±ã¼ã¹ã®ã³ã¼ãã¯åºæ¥ãã ãæ©ãæ¶ãã¾ãããã
ãã©ã°ããã®ã¾ã¾ã ã¨åå²ãå¢ãã¦ããã®ã§è¤é度ãä¸ãã£ã¦ãã¾ã£ã¦ãã¦ãç´ æ©ãéçºãé»å®³ãããã¨ã«ãªãããã¾ããã ããã¾ã§ã®TIPSãå®ã£ã¦ããã°ç°¡åã«æ¶ããã¯ãã§ãã®ã§ã·ã¥ãã¨æ¶ãã¦ãã¾ãã¾ãããã
ãã£ã¼ãã£ã©ã°ã追å ãããã±ãããåãã¨ãã«ãä¸ç·ã«åé¤ãããã±ãããåã£ã¦ãã¾ãã®ããã£ã¨ã確å®ã ã¨æãã¾ãã
éçºã®é度ãè½ã¨ããªãããã®ãã£ã¼ãã£ãã©ã°ã足ãå¼ã£å¼µã£ã¦ãã¾ã£ããå ãåããªãã®ã§ãããä¸çªå¤§åã§ãã
ææ¥ã¯ kyokomi ããã®ããªãã£ã¹ã¢ã¯ã¼ããã£ã¦ã¿ã話ãã§ãã