ちなみに

火曜日の空は僕を押しつぶした。

フィーチャフラグを扱うときのささやかなTIPS

この記事は クラスター 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 さんの「オフィスアワーをやってみた話」です。

新しいことを学ぶことを語るときに僕の語ること

こちらは クラスター Advent Calendar 2023(2枚目)の4日目の記事です。 昨日は慕狼ゆにさんの「clusterの若手成長」でした。自分は若いことは目の前のことに必死で先のことを考えられていなかったので、しっかり前を見据えられているのはすごいですね。

枠が空いていたので飛び込みました。


クラスター株式会社のソフトウェアエンジニアは自分の得意領域を持ちつつも、別の領域にもチャレンジをする人が多いです。 プロダクトに対するとオーナーシップが強い人が多いというカルチャー的な要因もあり、少しでもプロダクトをよりよくするために自然と領域の壁を越える人が多い印象です。

かく言う自分もこの半期は得意なサーバーサイドの領域を離れて Unity のタスクに挑戦していました。 もともと Unity 3、4 のころに仕事で触っていたので、素養はあるので完全な初挑戦という訳ではないのですが。

本記事では領域を越えるときにやったことを思い出して書いて見ようと思います。

新しいことに取り組むときの心構え

「どうやるか」(How) よりも「なぜか」(Why) が重要。

なぜそうなっているのかに注力することで、本当にいま覚えるべきことが分かって効率よく習得できると思っています。 また、ここで覚えた考え方は別のところでも役にたてることが出来るかもしれないのでお得です。

コードを書くのなんかは覚える気があれば誰でも出来るし、今度AIが発達すれば覚えなくても出来るようになるでしょう。

社内ドキュメントを読む

基礎知識があったので、ハードルになるのは社内事情だと思ったので、最初に社内ドキュメントを読みました。

基礎知識が必要な人は適当な本を一冊流し読みしてから公式ドキュメントを眺めたりするといいのではと思います。 最初から公式ドキュメントを読んで理解出来る人に憧れたりしますが、自分は何かとっかかりが欲しいので本を読んだりします。

クラスターにはドキュメント文化が根付いているので、様々なドキュメントが存在します。 自分で見つけられない場合も助けてーと言えば誰かが教えてくれるので学ぶ環境として恵まれています。 逆に助けを求められたときは自分が持ってる知識を惜しみなく出すことで良い循環になります。

tech-blog.cluster.mu

Unityの領域では VRM Animation (.vrma)をUnity上で簡単に生成できるようにした話|獏星(ばくすたー) の 獏星(ばくすたー)さんが書いてくださった最高のドキュメントがあるので、まずはこれを読むと良いと思います。 これが 知の高速道路 ってやつですね。

コードだけの変更で済むタスクをもらいにいく

これは Unity 特有の話題だと思うのですが、プレハブなんかを触り始めると急に分からないことが増えるので、まずはコードだけで完結するタスクを紹介してもらいました。 コードを書くだけだったら、言語が C# に変わったとしてもなんとかなる自信があったので、まずはそこから手を出すことで覚えることの範囲を狭くして混乱しないようにしました。 そのタスクを足がかりにしてちょっとずつ周りに手を出すことで「何にも分からない」状態から「ここは分かるけど、ここは分からない」と「分からないことが分かる」状態を保つようにしました。

これは新しいことに挑戦するときには重要だと思っていて、急に何も分からないことに挑戦するとさすがにストレスの方が強くてしんどくなってしまうので、出来るだけ好奇心の方が勝るように調整するようにしています。

質問しまくる

新しいことをやっているときはみんな初心者です。

初心者のときが一番質問がしやすくて、どんなしょうもないことを聞いても相手もまだ心穏やかな状態で答えてくれるバフがかかっていると思っています。 せっかくバフがかかっているので、活用しないのは勿体ないのでどんどん質問しましょう。

普段は15分くらいを基準にしていますが、自分が初心者だと思っている間は10分くらい迷っても分からなかったら即聞くようにしています。 たかが5分ですが、普段は10分くらいで方向性が見えてきて残り5分で答えを見つけるというサイクルな気がしていて、初心者のうちは最初の10分で方向性が見えないことが多く、残りの5分を無駄にしないためにも早めに聞いています。

クラスターでは #pf_unity_入門 みたいな質問専用チャネルがあるのでここで聞くことにしています。他にもコードレビューで突っ込まれたときに

まあどんなときでも、分からないことを質問しないより、質問する方が圧倒的に良いので、常に質問した方が偉いという精神でいきましょう。

〆切がないが広範囲を見る必要があるタスクをとる

「もらいにいく」から「とる」に言葉を変えました。そろそろ勘所が分かってきていると思うので、自分でタスクを取りに行きましょう。タスクの選定をするのでも得るものがあります。

さて、ここで2つのポイントがあります。

  • 〆切がないタスク

これを探すのは大変だとは思うのですが、まともな開発組織だったら、急いでないけどやりたいタスクなんかが転がっているはずなのでそういうのを狙ってください。 完成させることが主目的になるので前提である「なぜ」に注力しにくいので、余裕を持てるタスクがおすすめです。

  • 広範囲を見る必要があるタスク

自分が開発してところととか、不具合を直したところって、目的もなくコードを読んだところとか、教えてもらったことよりも覚えていたりしませんか。 やはり目的があった方が身に付きやすいのですが、目的にするのはやはり仕事としてやるのが一番手っ取り早いし、タスクをやることを周りにも説明しやすいです。 折角、やれるチャンスがあるなら出来るだけ広範囲を触るものを選びましょう。

自分の場合は機能開発のために追加されたフィーチャフラグを消していくタスクを取ることで、その機能で触っているところを満遍なくみていくということをしました。

新しいことに挑戦するのは常に楽しい

「楽しい」を越えて「恐怖」を感じてしまう状況だとあんまり良い学びにつながらないと思います。 今はそのタイミングではないと思うので、楽しいと思えることをやっていきましょう。

ただし「楽しい」と「ぬるい」を勘違いするとコンフォートゾーンを出られないので注意です。


明日のアドベントカレンダーの記事は、決まってないです!誰かー!

買いの苦しみ

買い物によってストレスを発散するタイプの人間なんですが、ブラックフライデープライムデーなどのセールの時は買わないといけないという強迫観念があり苦しい。

要らないものを買う訳にはいかないので、ずっとリストを眺めながら要るものを探している。探して見つけたものは本当に要るものなのかという指摘はあると思う。

郵便局の人がいつもならあり得ない遅い時間に配達に来てくれて申し訳ない気持ちになりました。

困ったことを覚えておく

昔は困ったことを困ったままにして、困った困ったと言っていたのだけれど、最近は困ったことは解決するようにしている。

めちゃくちゃ当たり前のことを言っているようなんだけれど、日々せわしなく生きていると困ったことをそのままにしがち。 そもそも困ったことを覚えてなくて、次に困ったときにそう言えば困っていたのだったと思い出すことになる。

ずっと困ってるわけにもいかないので、解決するようになったのだけれど、一番効いたのは困ったことを覚えておくことだった。

もちろん覚えておくのは大変なのでメモったりはしているのだけれど、なんらかの手段で困ったことを思い出せるようにしている。 そうすると、なんか手が空いたときとかに、困ったことを解決することが出来るようになった。

最近だと、Bartender 5 (正確には macOS Sonoma) になって Update Image Trigger が使えなくなったのがめっちゃ困っていたけど、ある週末にうーんと唸って Script condition で解決したり、マイクのミュートのキーボードショートカットが動かなくなっていたのを直したりした。

直すのは案外なんとかなるのだけれど、覚えておく方がなんか重要な気がしたので書いておきました。

上から全部みる

時折やる気を出して上から全部みることがあります。

例えば、エディタの設定であったり、アプリのプラグインであったり。 しばらく見ていない間にとっても便利なものが増えていたりするので毎回なんらかの発見があります。

新着を見続けてもいいのだけれど、大変だしそのときは欲しくないかもしれない。 同じ労力かけるならやる気があるときに全部見なおした方が効率的だと思っている。

新しいものを見つけるという向きもあるのだけれど、使っていないものを見つけるという意味もある。 自分の設定やプラグインも全部見なおすと使っていないものがけっこう見付かる。 めっちゃ便利やんと思って設定してもほとんどが使わないのである。

そうやって淘汰されていって、快適な環境になっていくのだと思うのです。

でっかい岩

でっかい岩がある神社に行ってきた。でっかいと聞いてイメージしたいたよりもさらにでっかくて普通に興奮してしまった。 ただし岩のところまで行くのにけっこう登らないといけないのでなかなか疲れるのが難点。

www.town.takamori.kumamoto.jp

重力

どうにも体と頭が重くてなかなか起きられなかった。起きたり寝たりで一時くらいからやっと活動できた。疲れたのかなんなのか。 代わりに初めて睡眠のスコアが100点だった。