Comparators―比べてみればわかること

第3回 ブランチvs.フラグ

この記事を読むのに必要な時間:およそ 3 分

Facebook Gatekeeper

FacebookもFeature Flippersに類するしくみを持つことが知られています。同社のリリースエンジニアリングに関する講演では,Gatekeeperと呼ばれるフラグのフレームワークを紹介していますリスト1⁠。講演によると,Gatekeeperはユーザのプロフィール情報に応じてフラグの値を設定できると言います。Facebookの広告の設定と似ているかもしれません。講演の中では,ハイテクニュースブログTechCrunchの社員だけにフェイク機能をリリースして間違った記事を書かせた逸話が披露されています。

リスト1 Gatekeeperの疑似コード

if (gatekeeper_allowed('my_project_name', $viewing_user_or_application)) {
  run_this_tested_code();
} else {
  run_this_old_code();
}

Cookpad Chanko

Cookpadは,Ruby on Rails向けの拡張機能としてフラグを実装しています。Chankoと呼ばれるそのフレームワークはオープンソースで公開されています。Chankoでは,フラグに隠された各機能をunitと呼ばれる独立したモジュールとして扱います。各unitにはそれぞれ別のディレクトリが与えられます。

Chankoのデザインは,実験支援としてのフラグを強調しています。unitはクリーンに分離されるため,失敗した実験を削除するのが簡単です。またunitでエラーが起こった際に規定の動作へフォールバックできるなど,手荒な実験を許す堅牢さも備えています。フラグのアイデアを推し進めた先進的な実装です。

Google gflags

これまでに紹介したフラグは,Webのフレームワークと一体になった実装でした。次に紹介するgflagsは,コマンドラインから渡されたフラグ引数をパースするC++のライブラリです。Rubyのoptparseライブラリなどを想像すればよいでしょう。

gflagsの特徴は,フラグをコード内で分散管理できることです。optparseを始めとする従来のフラグパーサは,フラグの定義を1ヵ所にまとめて定義する必要がありました。gflagsを使うと,宣言を書くだけでプログラム内のどのファイルからも簡単にフラグを追加できます。宣言されたフラグは自動的にパースの対象になりますリスト2⁠。

各モジュールの開発者が簡単に設定項目を追加できるしくみは,巨大なソフトウェアを開発する際に重宝するのでしょう。

リスト2 gflagsを使ったフラグの宣言

DEFINE_bool(big_menu, true, "Include 'advanced' options");
DEFINE_string(languages, "english,french,german",
                         "comma-separated list of languages");

※出典:http://google-gflags.googlecode.com/svn/trunk/doc/gflags.html

Branch By Abstraction

乱雑に散らばったフラグはコードの見通しを下げがちです。フラグを使いつつ,ブランチくらいきっぱりとコードを切り離せないか。リファクタリング技法のBranch By Abstraction(BBA)は解決策の一つです。BBAではフラグに隠したい新旧のバージョンをインタフェースに隠し,実装をサブクラスに切り出します図3⁠。

図3 Branch By Abstraction

図3 Branch By Abstraction

BBAもフラグを使います。ただし使い方には強い規律を求めています。コード内にランダムな条件分岐を埋め込むのではなく,リファクタリングで抜き出したクラスのうちどちらを使うか選ぶところだけでフラグを見るのです。

フラグを使うプログラマはBBAに従うべきなのでしょうか。BBAの出典では,ORMObjectrelational mappingフレームワークの置き換えにBBAを使っています。このように大規模な修正ではBBAが助けになります。

一方,もっと小さく実験的な変更はどうでしょう。たとえば画面のレイアウトを調整して反応を見たくなったとき,BBAは有用でしょうか。テンプレートにフラグの条件分岐を書き足すほうが早そうです。

実験志向とBBA

ORMの置き換えと画面レイアウト調整の違いはなんでしょう。

一つは規模です。大規模な変更には秩序が必要です。良識あるプログラマなら,名前は知らなくてもBBAと似たデザインを選ぶでしょう。

もう一つは投機性です。実験主義者の変更はそれぞれが実験です。そして実験には失敗がつきもの。日々の失敗を小さくとどめるために,開発者は変更を小さくまとめようとします。そうした変更にBBAは大げさ過ぎます。

たとえば実験が終わったあと,開発者はフラグを取り除きます。しかしBBAはフラグ以外に間接化のリファクタリングを持ち込んでいます。フラグ単体と違い,間接化を取り消すのはそう簡単でもありません。結果として不要な間接化がコードの中に残り,見通しを損ねます。そのため規模が小さい実験志向のフラグには,BBAより素朴な条件分岐がうまく働きます。素朴な分岐は不格好ながら取り除くのが簡単なのです。

東京駅vs.新宿駅

継続的デリバリにおけるコード変更が都心の工事だとしたら,BBAはビルを覆う足場とシート。条件分岐は足元注意の標識です。一方は長期戦の下準備,他方はその場限りの仮止めです。

実験志向が支配するソフトウェアは新宿駅に似ています。いつもどこかは工事中で,駅を通り抜けるといつも標識に出くわします。ごちゃごちゃしていて完成が見えません。けれどその混沌はやがて日常に溶け込んでいきます。

BBAを好む手堅いソフトウェアは東京駅に似ています。建物が立派で,たまに始まる大工事では完成予想図をプリントしたシートが駅舎を包みます。人々は完成の予感に胸を踊らせながら,薄暗い駅舎を足早に通りすぎます。

どちらが望ましいかは舞台しだいです。銀行や新聞社,権威ある企業が立ち並ぶ丸の内には秩序が求められます。新興企業から歓楽街まで,雑居ビルひしめく新宿には混沌と変化が似合います。はっきりとした正しさを目指す大きな変更にはBBAが相応しいでしょう。出たとこ勝負で手直しを続ける実験志向には素朴なフラグがお似合いです。街に似合う駅を。目的に合う変更戦略を。私たちのソフトウェアはどんな街に建つのでしょうか。

著者プロフィール

森田創(もりたはじめ)

平日はWebブラウザの開発,休日はWebブラウザの利用に従事。最近の趣味は/etc/hostsファイルに中毒性の高いWebサイトをリストし,127.0.0.1にリダイレクトすること。現在7サイト。スマートフォンの勉強をしなければと思いつつ/etc/hostsにアクセスできない端末を持つのが不安で躊躇している。

http://steps.dodgson.org/