はじめに
「読みやすいコードのガイドライン」という本を読んでいる中で、
ボーイスカウトルール
という作法が紹介されていましたので、記事にしてみたいと思います。
なお今回は、Kotlinで書かれた本著の内容をDartに置き換えて書いてみました。
ボーイスカウトルールとは?
ボーイスカウトがキャンプ場に来た際、
来た時よりもキャンプ場を綺麗にしてから帰る、
というボーイスカウトの心構えや心遣いから転じて、
「出会った当初よりもコードを綺麗にしていく心構えや心遣い」
といった作法のことです1。
この作法がないままに実装を行うと、
どんどん可読性やメンテナンス性、拡張性が落ちていってしまいます...😭
ボーイスカウトルールが無かったら...
/// ボーイスカウトルールによって修正される前のコード
enum ViewType {
A,
B,
Y,
}
void updateViewProperties(ViewType viewType) {
switch (viewType) {
case ViewType.A:
view1.isVisible = true;
view2.text = 'Case A';
break;
case ViewType.B:
view1.isVisible = false;
view2.text = 'Case B';
break;
case ViewType.Y:
view1.isVisible = true;
view2.text = 'Case Y';
break;
}
}
上のコードは一見問題なさそうに思えるかも知れませんが、
- Enumの列挙子が増えたり、減ったりした際の修正反映(影響範囲)が大きい
-
updateViewProperties
関数の処理は結局同じような処理を繰り返しているだけ... - 加えて、列挙子の数に振り回され、関数の振る舞いの見通しが悪くなっている...
こんな問題を抱えてもいます。。。
このまま放置すると、嫌な気配と言うか、面倒臭そうなことが起こりそうですね...😅
ボーイスカウトルールでリファクタリングしてみよう!
そんな気がしたので、綺麗にしてみましょう💪
/// ボーイスカウトルールに則ってリファクタリングしたコード
enum ViewType {
A(true, 'Case A'),
B(false, 'Case B'),
Y(true, 'Case Y');
final bool isView1Visivle;
final String view2Text;
const ViewType(
this.isView1Visivle,
this.view2Text,
);
}
void updateViewProperties(ViewType viewType) {
view1.isVisible = viewType.isView1Visivle;
view2.text = viewType.view2Text;
}
上記のコードであれば、変更箇所はViewType
に新しい列挙子を追加するだけであり、
updateViewProperties
関数に変更は入らないようにすることが出来ます。
こうすれば、面倒なことが起こりにくそうですし、
プロダクトの品質を上げることもできますね🙌
(未来の私たちはちょっと楽ができますしね〜🎶)
参照
-
この考え方はクリーンアーキテクチャで有名なRobert C.Martin氏(通称ボブおじさん)が、ボーイスカウト運動の創始者であるRobert Baden-Powell氏の先述の考え方をソフトウェア開発に応用したもの、とのことです2 ↩
-
読みやすいコードのガイドライン第1章21頁を参照 ↩