狠狠撸

狠狠撸Share a Scribd company logo
オブジェクト指向
    エクササイズのススメ



12-A-6   菅野洋史/大村伸吾
         株式会社オージス総研
         オブジェクトの広場
講演者の紹介
株式会社オージス総研

オブジェクトの広場編集部
月間のオンラインマガジン


罢丑辞耻驳丑迟奥辞谤办蝉アンソロジーを
翻訳しました!!
今回はその中の一編
「オブジェクト指向エクササイズ」
を紹介します
罢丑辞耻驳丑迟奥辞谤办蝉アンソロジー

    ThoughtWorks社コンサルタント
●

    の

    骨太なエッセイ集
    様々な   ジャンルを収録
●


    DSL、プログラミング、設計、
    マネジメント、ビルド、デプロイ、テス
    ト...


    オライリーさんブースで
●




    絶賛販売中!
                             3
はじめに

      このセッションでは
 オブジェクト指向プログラミング(=設計)
      について語ります



開発プロセスを支えるのはエンジニアリング!
ところで
オブジェクト指向プログラミング
    していますか?
本当にオブジェクト指向?

    オブジェクト指向言語を使ってる
●



    継承やインタフェースを使ってる
●



    処理とデータを分離することによって、
●


    疎結合かつ再利用性の高い設計に!
    Strutsを使ってるから???
●
それは
オブジェクト指向プログラミング
     では无い
オブジェクト指向でやるなら


  責務を持ったオブジェクトが
コラボレーションすることによって、
 复雑なシステムを构成するべき
オブジェクト指向が出来ない理由
    以前の慣習から抜け出すのが難しい
●



    一部の開発者だけOOを分かっていればいいと
●


    いう風潮(特に設計者やアーキテクト)
    「難しい」という誤解
●



    「マニアック」という誤解
●



    「実践的じゃない」という誤解
●
必ずしも、
オブジェクト指向は銀の弾丸じゃないが、
   武器は多い方が絶対にいい
教育と学习重要!
     一部の開発者だけではなく
  プロジェクトのみんなが学んだときに、
  初めてオブジェクト指向は武器になる


学ぶなら??
単なる耳学問ではなく、
体に叩き込む学習手段が欲しい
そこで
 オブジェクト指向エクササイズ
オブジェクト指向プログラミングを強制的に身に
着けるためにハードなコーディング規約を実際
のプログラムに適用するエクササイズ


「1000行程度のプロジェクトに適用する」
谁がやる?
    開発の仕事には入って数年目の人
●



    ある程度、自分は出来ているという認識を
●


    持ってる人(の鼻っ柱を叩き折る)
    最近、オブジェクト指向で開発していない
●


    なーというオブ厨の人
しばし、オブジェクト指向エクササイズの
     内容説明を???
9つのルール
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する
? 名前を省略しない
? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで         15
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する
? 名前を省略しない
? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで
                               16
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列は
  ラップする
    ファーストクラスコレクションを使用する
?
    名前を省略しない
?
?   别濒蝉别句は使わない
    すべてのエンティティ(要素)を小さく
?
?   1行につき1ドットまで
?   Getter, Setter,プロパティを使用しない
?   1クラスにつきインスタンス変数は2つまで
                                 17
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを
  使用する
    名前を省略しない
?
?   别濒蝉别句は使わない
    すべてのエンティティ(要素)を小さく
?
?   1行につき1ドットまで
?   Getter, Setter,プロパティを使用しない
?   1クラスにつきインスタンス変数は2つまで
                                 18
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する

? 名前を省略しない
? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで
                               19
省略したくなるのはこんな时
                  Before

OrderService os = ...;
os.shipOrderByOrderFromShopToCustomer(o,s,c);

class OrderService{
  void shipOrderByOrderFromShopToCustomer
        (String orderID,
         String shopID,
         String customerID)
  {...}
}
                                                20
责务の配置を考え直せる
            After


Shop shop = ...;
Customer customer = ...;
Order order = ...;
order.ship(shop,customer);


                             21
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する
? 名前を省略しない

? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで
                               22
别濒蝉别句は使わない
         Before


if (age < 20) {
    doNotDrink();
} else {
    drink();
}
                    23
别濒蝉别句は使わない
          After


if (age < 20) {
    doNotDrink();
    return;
}
drink();
                    24
?   1メソッドにつき1インデントまで
    プリミティブ型と文字列はラップする
?
    ファーストクラスコレクションを使用する
?
    名前を省略しない
?
?   别濒蝉别句は使わない
? すべてのエンティティ(要素)
  を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで
                               25
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する
? 名前を省略しない
? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく

? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで
                               26
1行につき1ドットまで
              Before


StringBuilder builder = ...;
builder.append(omura.getName());




                                   27
1行につき1ドットまで
              After
StringBuilder builder = ...;
omura.appendName(builder);

// in class Person...
void appendName(
        StringBuilder builder){
    builder.append(name);
}
                                  28
?   1メソッドにつき1インデントまで
    プリミティブ型と文字列はラップする
?
    ファーストクラスコレクションを使用する
?
    名前を省略しない
?
?   别濒蝉别句は使わない
    すべてのエンティティ(要素)を小さく
?
?   1行につき1ドットまで
? Getter, Setter,プロパティを
  使用しない
? 1クラスにつきインスタンス変数は2つまで
                          29
?   1メソッドにつき1インデントまで
    プリミティブ型と文字列はラップする
?
    ファーストクラスコレクションを使用する
?
    名前を省略しない
?
?   别濒蝉别句は使わない
    すべてのエンティティ(要素)を小さく
?
?   1行につき1ドットまで
?   Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は
  2つまで
                                 30
1クラスにつきインスタンス変数は2つまで


              Before


class Person {
    String firstName;
    String lastName;
    int age;
}


                        31
1クラスにつきインスタンス変数は2つまで

                  After
class Person {
    Name name;
    Age age;
}
class Age {   int age;    }
class Name {
    String firstName;
    String lastName;
}
                              32
9つのルール
? 1メソッドにつき1インデントまで
? プリミティブ型と文字列はラップする
? ファーストクラスコレクションを使用する
? 名前を省略しない
? 别濒蝉别句は使わない
? すべてのエンティティ(要素)を小さく
? 1行につき1ドットまで
? Getter, Setter,プロパティを使用しない
? 1クラスにつきインスタンス変数は2つまで 33
オブジェクト指向エクササイズで
Let's シェイプアップ!

        責務
     クッキリ




  コラボ         コード
 バッチリ        スッキリ
                    34
オブジェクト指向エクササイズで
   スッキリ! クッキリ! バッチリ!
    プリミティブ型はラップする
                               ファーストクラス
                        責務     コレクションを使用
   インスタンス変数
                    クッキリ
     は2つまで
                                   别濒蝉别句は使わない
1行につき1ドットまで
                                      1メソッド
                 コラボ         コード
Getter, Setter                      1インデントまで
                 バッチリ        スッキリ
 を使用しない

    エンティティ(要素)を小さく             名前を省略しない
                                                35
実际にためしてみる
「お题」

   一見OOっぽい感じだけど、
エクササイズの観点で見るとダメダメな、
あるツールをエクササイズのルールに
    従うように書き直す。
Amazon価格調査ツール
以下の仕様を持つ単純なコマンドラインツールを
    リファクタリング
    引数でASINを与えて起動
●



    AmazonマーケットプレイスをWebAPIで呼び出
●


     し、最も安い値段を検索する
    结果出力
●
デモ
当初の构造
シーケンス図
こんなもんでしょうか??


エクササイズの視点で見るとまだまだ余地がある


     まだ人间の限界じゃない!
ルールの適用
今回は、9つ全部は時間が足りないので、
    2つの視点でルール群に注目する
    責務をクッキリと明確にする
●



    オブジェクト同士がバッチリとコラボして
●


     動作するようなモデルにする
责务をクッキリさせる
    すべてのエンティティを小さくすること
●



    すべてのプリミティブ型と文字列型をラップ
●


    すること
    1つのクラスにつきインスタンス変数を2つま
●


    でにすること
Bookクラス
「属性3つ」「titleがString」
 「priceとusedPriceがint」
贩売情报の抽出
    「1つのクラスにつきインスタンス変数は
●


    2つまでにすること」
Moneyによるラップ
「すべてのプリミティブ型と文字列型をラップ」
コードで書くと
public class OfferSummary {
  Money price;
  Money usedPrice;
}
public class Money {
   int value:
}
BookクラスにあったString型のtitle
 にも同様の処理を施して???
最终的なクラス図
最初のBookをコードで書くと
public class Book {
    String title;
    int price;
    int usedPrice;
}
最後のBookをコードで書くと
public class Book {
    BookName title;
    OfferSummary offerSummary;
public class BookName {
    String title;
public class OfferSummary {
    Money price;
    Money usedPrice;
public class Money {
    int price;
结果
    「Book」が持っていた責務を適切に配分する
●


    ことができた
         MoneyのことはMoneyに
     –

    最初の時点では思いつかなかったクラスを抽
●


    出できた
         価格情報を扱うOfferSummary
     –
コラボレーションに関係するルール


オブジェクトをより賢くして、コラボレーション
       によってシステムの機能を実現する


関係するルール
    Getter,Setterを利用しない
●
理由

    Getter,Setterを定義したクラスの
          中身はスカスカになるから
    責務がGetter,Setterを呼び出す側に偏る
●



          「情報を取り出して処理して戻す」など
      –

    本来は、Tell,Don't Ask!
●


     「たずねるな! 命じよ!」
しかし!
例えばBookの情報を画面表示する場合、
 情報取得しないとどうしようも無い



 どうすればいい?
もう一回シーケンス図
考えられる戦略
    妥協する(エクササイズ的にはNG)
●



    DTO的戦略
●



    ダブルディスパッチ戦略
●



    etc??
●
DTO戦略


画面表示に関係する情報を
一つの塊(DTO)にパックして
  表示側に返却する
BookDTO
    画面表示用のオブジェクトをBookクラスが作って返却
●
コード例
class Book {
  public BookDTO represent() {
    return
      new BookDTO(
        title(),price(),usedPrice());
  }
class BookDTO {
    String title;
    String price;
    String usedPrice;
     //略
    public String toString() {
        //いい感じに文字列編集して返却
Mainで表示する
AmazonWebService servce =
        new AmazonWebService();
Book book = service.readBookInfo(args[0]);
BookDTO dto = book.represent();
System.out.println(dto);
疑問


  Getter,Setterを
使った場合とどう違うの?
ダブルディスパッチ戦略


単にオブジェクトをメソッドで
 呼び出すだけではなく、
 相手から呼び返してもらう
画面が表示用オブジェクトを作成
●



    Bookに引き渡す
●



    それを受け取ったBook側で、表示オブジェク
●


     トに出力メッセージを送る(呼び返す)
    表示用オブジェクトが画面に出力する
●




このようにBook側が賢く動く
クラス図
シーケンス図
    シーケンス図では説明無理!!
●
コード例:Book側
public void format(Out<String> out) {
  out.put(quot;タイトルquot;,title());
  out.put(quot;価格quot;,      price());
  out.put(quot;中古価格quot;, usedPrice());


outというオブジェクトが
 formatメソッドに飛んできたら、
 出力したい情報をputする。
 どこに出力されるかは知らないが
コード例:画面表示用オブジェクト
interface Out<T> {
  void put(String attr , T obj);
}
class ConsoleOut implements Out<String> {
  public void put(String attr, String value) {
     System.out.printf(
          quot;%s %s nquot; , attr, value);
コード例:画面表示用オブジェクト
    BookクラスはOutというインタフェースのput
●


     メソッド呼び出すと、何らかの形で自分の情
     報を外部に出力できる事だけを知ってる
    ConsoleOutクラスはOutインタフェースを実装
●


     し、標準出力に情報を出力する
コード例:Main
AmazonWebService aws = new AmazonWebService();
Book book = aws.readBookInfo(args[0]);
Out out = new ConsoleOut();
book.format(out);

BookをAmazonWebServiceから取得して、

そのBookに出力を依頼している
効果
    画面側からモデル側の情報を、一方的に
●


    引き出して利用するという関係が消えた
    責務が配分され、オブジェクト同士のコラボ
●


    レーションにより機能が実現されている
その他の设计案
    Bookクラス自体に表示能力を持たせる
●



          Squeak派
      –

    単純にBookクラスのtoString()を実装する
●



          Java王道派
      –

    getterという名前じゃないんだけど、同じ機
●


     能のメソッドを用意する
          ひたすらずるい
      –
実は、、正解は無い
その場の「制約」をどうバランスさせるか
    判断することが重要
    このような設計時の判断の集積はアーキテク
●


     チャになり、チームのコモンセンスになる
    エクササイズによって
●


     議論が引き出される効果がある
さらにエクササイズを进める
最终的なクラス図
过剰设计じゃない?
    エクササイズは設計手法そのものでは无い
●



    実際はルールを調整する必要がある
●



    ただし著者(ThoughtWorks社のJeff Bay氏)は
●


     このルールで実プロジェクト(10万行)を実施
     しているらしい
演習のまとめ
責務が分割されて、オブジェクト間のコラボレー
    ションにより機能が実現されるようになった。
学習効果としては、
    惰性で行っていた設計の見直しが出来た
●



    制約が設計に影響することを実感できた
●



    いろいろなテクニックを引き出した
●
最后に
エクササイズで壁を超えよう
    とにかくきつい! 無理!
●



    無理を通して道理を蹴っ飛ばせ!
●



    あらゆるテクニック、知識を総動員しろ!
●



    議論を巻き起こせ!
●
なお、効果には个人差があります
スペシャルサンクス
    Jeff Bay氏
●


     (原著者/ThoughtWorks社テクノロジプリンシバル)

    村上 未来 さん(翻訳)
●



    オブジェクトの広場メンバー
●


     (佐藤さん,田中さん,辻さん,山内さん,山野さん)

    オライリー?ジャパン様(宮川さん)
●



    本書を読んでくださった皆様
●




                                      83
告知
    ソースコードは後日「オブジェクトの広場」
●


     でダウンロード可能にします。
    「オブジェクトの広場」でThoughtWorksアン
●


     ソロジーのプレゼントをやっています。




                                 84
ご静聴ありがとうございました

http://www.ogis-ri.co.jp/otc/hiroba/




                                       85

More Related Content

オブジェクト指向エクササイズのススメ