More Related Content
Similar to リーンなコードを書こう:実践的なオブジェクト指向設計 (16)
リーンなコードを書こう:実践的なオブジェクト指向設計
- 10. コードを改善する機会
• 変更が必要になった時
– ビジネスルールの変更
– 機能の追加
• 変更がやりやすいように、コードを改善してから
変更する
• 小さな変更依頼が良いチャンス
– 変更の目的が明確
– なぜその変更がたいへんか、原因がわかりやすい
– 改善の before/after を確認しやすい
• 変更するたびに、小さな改善を累積していく
• 大きなブレークスルーが起きる
- 13. 簡単な例
//変更前
void usage( String name, int value)
{
System.out.println( “利用回数” );
System.out.println( new Date() );
}
//詳細表示
System.out.println( “氏名:” + name );
System.out.println( “回数” + value );
//変更後
void usage( String name, int value)
{
System.out.println( “利用回数” );
System.out.println( new Date() );
}
detail(name,value);
void detail( String name, int value )
{
System.out.println( “氏名:” + name );
System.out.println( “回数” + value );
}
- 14. メソッド分割の補足
• 分割しすぎると一連の流れが追いにくい
– Yes
– 一連の流れ(=手続き型プログラミング)だから、変更が大
変になっている
– ばらばらの部品に分けて、変更がやりやすいように組み立
てなおす
– 変更の視点で組み立てなおすと、コードがわかりやすくな
る味を覚えましょう
• 対象が計算式1行だけでも、メソッドにするの?
– Yes
– 他のコードと分離することが大切
• メソッドチェイン
– 1ステップずつ分割したほうが、整理がしやすい
- 17. Detail クラス
class Detail
{
private String name;
private int value;
Detail( String name, int value )
{
this.name = name;
this.value = value;
}
}
void print()
{
System.out.println( “氏名:” + name );
System.out.println( “回数” + value );
}
- 19. Detail クラスを使う
//変更前
void usage( String name, int value)
{
System.out.println( “利用回数” );
System.out.println( new Date() );
}
//変更後
void usage( String name, int value)
{
System.out.println( “利用回数” );
System.out.println( new Date() );
detail(name,value);
void detail( String name, int value )
{
System.out.println( “氏名:” + name );
System.out.println( “回数” + value );
}
}
Detail detail = new detail(name,value);
detail.print();
詳細の印刷内容を変更する時、
Detail クラスに変更を局所化できる
特に効果が大きいのは、
・複数個所に重複している場合
・氏名と回数を使う他のロジックが
ある場合
- 23. 小さなクラスたち
• 基本データ型 ( Integer, String, Date )を1つか2つ
持つ小さなクラスが、変更の対象になることが多
い
• クラス名は、業務要件の基本語彙になる
• 基本語彙クラスがそろってくると、コードは要件
定義書に近づいていく
– 語彙
– 構造
パッケージ
• ドキュメントの改善
– 業務要件をコードに変換するためのプログラム仕様
書は不要になる
– 業務仕様書の重複が、プログラムから発見できる
- 31. for 文とコレクション
• バグと副作用の巣窟です
– コレクションのグローバル参照をやめる
– コレクションを渡すことをやめる
• 変更の対象データがコレクション
– そのコレクションだけを持つクラスを宣言
– そのクラスにロジックを集める
– そのクラスはコレクションを返さない
コレクションを特別扱いにする
ファーストクラスコレクション
- 35. 変更コストは条件分岐との戦い
• スパゲッティコード goto文
– if/switch は、goto文の特殊形態
– if/switch の分岐後のブロックが長くなれば、
goto文使ったスパゲティといっしょ
• 今までのやり方の応用編
– 分岐ごとにメソッドにまとめる
– あちこちで同じ条件分岐したメソッドを集め
るためのクラスを作る
- 36. 分岐ごとにクラスにわける
…
Amount fee(String guestType)
{
if( guestType.equals( "adult“ ) )
return adultFee();
else
return childFee() ; //子供
}
…
private Amount adultFee()
{
return Yen(100);
}
private Amount childFee()
{
return new Yen(50);
}
class Adult
{
Amount fee()
{
return new Yen(100);
}
}
class Child
{
Amount fee()
{
return new Yen(50);
}
}
- 38. Java の 列挙型ならもっと簡単
enum Guest
{
Adult(100), Child(50), Baby(0),Senior(80);
Amount fee ;
Guest(int fee)
{
this.fee = new Amount(fee);
}
}
Amount fee()
{
return this.fee;
}
Javaの列挙型:
Interface 宣言 +
実装クラス宣言 + singleton
型ごとに、振る舞いを
持てる
区分や種別のコードの整理の
特効薬
- 48. ドメインモデル
ほんとうの価値
• 業務の知識の浸透
– ビジネス目標/システムの価値の理解
– 業務の全体像/基本の仕組みの理解
– 業務の現場にある肌感覚、現場の知恵
• 言語表現を超えた暗黙知が育つ
– 業務アプリケーションの設計のコツ、かんどころ、
おとしどころ、…
– 個人に内面化された価値観、方向感
– チームで共有化された価値観、方向感
• 「あたり」がつくようになる
– 的外れの作業/とんでもない勘違い/手戻りが減る
– 進むべき方向がわかりやすくなる
ドメインモデルがリーン開発を加速する