組織駆動設計～組織の形～

以下の記事をベースに話を進めていきます。

https://qiita.com/sikimuOji/items/3cfb8c81f82e7f86f613

# 担当の分け方を考える
**システム概要**
**仕様１**．商品伝票の個数をみて販売金額を決定
**仕様２**．商品伝票を入れ物をみて配送料を決定
**仕様３**．伝票の束の総額を計算
**仕様４**．対象外の商品が入ってくることはない

## 商品別担当者
商品ごとに把握しやい
商品を追加しやすい

~~~java:注文商品伝票.java
class 注文商品伝票 {
    public final String 商品名;
    public final int 個数;
    public final String 入れ物;
    //~省略~
}
~~~
~~~java:
abstract class 計算職{
    abstract boolean 担当商品か確認(String 商品名){
}
~~~
~~~java:管理人.java
class 管理人 {
    private りんご計算担当 太郎 = new りんご計算担当();
    private みかん計算担当 花子 = new みかん計算担当();
    private めろん計算担当 ボブ = new めろん計算担当();
    public int 総額を計算する(List<注文商品伝票> 伝票の束){
        int 総額 = 0;
        for(注文商品伝票 伝票 : 伝票の束){
            if(太郎.担当商品か確認(伝票.商品名)){
                総額 += 太郎.合計額の計算();
            }
            else if(花子.担当商品か確認(伝票.商品名)){
                総額 += 花子.合計額の計算();
            }
            else if(ボブ.担当商品か確認(伝票.商品名)){
                総額 += ボブ.合計額の計算();
            }
        }
        return 総額;
    }
}
~~~
~~~java:りんご計算担当.java
class りんご計算担当 extends 計算職{
    public boolean 担当商品か確認(String 商品名){
        return 商品名.equals("りんご");
    }

    public int 合計額の計算(注文商品伝票 伝票){
        int 販売金額 = 伝票.個数 * 100;
        int 配送料 = 100;
        //木箱は100円増し
        if(伝票.equals("木箱")){
            配送料 += 100;
        }
        return 販売金額 + 配送料;
    }
}
~~~
~~~java:みかん計算担当.java
class みかん計算担当 extends 計算職{
    public boolean 担当商品か確認(String 商品名){
        return 商品名.equals("みかん");
    }

    public int 合計額の計算(注文商品伝票 伝票){
        int 販売金額 = 伝票.個数 * 50;
        int 配送料 = 100;
        //木箱は100円増し
        if(伝票.equals("木箱")){
            配送料 += 100;
        }
        return 販売金額 + 配送料;
    }
}
~~~
~~~java:めろん計算担当.java
class めろん計算担当 extends 計算職{
    public boolean 担当商品か確認(String 商品名){
        return 商品名.equals("めろん");
    }
    public int 合計額の計算(注文商品伝票 伝票){
        int 販売金額 = 伝票.個数 * 500;
        int 配送料 = 1000;//固定で1000円
        return 販売金額 + 配送料;
    }
}
~~~

## 計算別担当者
作業ごとに把握しやすい
共通処理を組み込みやすい(りんごとみかんの配送料を共通化)

~~~java:注文商品伝票.java
class 注文商品伝票 {
    public final String 商品名;
    public final int 個数;
    public final String 入れ物;
    //~省略~
}
~~~
~~~java:管理人.java
class 管理人 {
    private 販売金額計算担当 太郎 = new 販売金額計算担当();
    private 配送料計算担当 花子 = new 配送料計算担当();

    public int 総額を計算する(List<注文商品伝票> 伝票の束){

        int 販売金額総額 = 太郎.総額を計算する(伝票の束);
        int 配送料総額 = 花子.総額を計算する(伝票の束);

        return 販売金額総額 + 配送料総額;
    }
}
~~~
~~~java:販売金額計算担当.java
class 販売金額計算担当{
    public int 総額を計算する(List<注文商品伝票> 伝票の束){
        int 総額 = 0;
        for(注文商品伝票 伝票 : 伝票の束){
            if(伝票.商品名.equals("りんご")){
                総額 += 伝票.個数 * 100;
            }
            else if(伝票.商品名.equals("みかん")){
                総額 += 伝票.個数 * 50;
            }
            else if(伝票.商品名.equals("めろん")){
                総額 += 伝票.個数 * 500;
            }
        }
        return 総額;
    }
}
~~~
~~~java:配送料計算担当.java
class 配送料計算担当{
    public int 総額を計算する(List<注文商品伝票> 伝票の束){
        int 総額 = 0;
        for(注文商品伝票 伝票 : 伝票の束){
            if(伝票.商品名.equals("りんご") || 伝票.商品名.equals("みかん")){
                int 配送料 = 100;
                //木箱は100円増し
                if(伝票.equals("木箱")){
                    配送料 += 100;
                }
                総額 += 配送料;
            }
            else if(伝票.商品名.equals("めろん")){
                総額 += 1000;
            }
        }
        return 総額;
    }
}
~~~
どちらの考えも間違っているわけではない。
継承を使ったほうがいいわけではなく、作りたいものにそった構成としたほうがいい。