組織駆動設計～伝票～

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

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

# 伝票を使ったやり取り
**システム概要**
**仕様１**．電話で注文を受けて入力した在庫を確認する。
**仕様２**．注文商品伝票リストを作成、件数を報告する(重複なし)

## たくさんの商品がある
今回の台帳には、カロリーや大きさ、容器の材質などのいろいろなパターンがある。
そのため、やり取りが非常に長くなる

#### 在庫台帳
| 商品名 | カロリー | 容量 |  容器材質 |  ケースあたり | 在庫数 | 
| ---- | ---- | ---- | ---- | ---- | ---- |
| コーラ | なし | 20 | ペットボトル | 12 | 50 |
| コーラ | あり | 5 | 缶 | 10 | 100 |
| コーラ | なし | 5 | 缶 | 24 | 10 |
| サイダー | あり | 5 | 缶 | 10 | 24 |
| サイダー | なし | 20 | ペットボトル | 12 | 500 |
| サイダー | あり | 5 | ペットボトル | 24 | 300 |

~~~java:在庫管理者.java
class 在庫管理者{
    public static int 在庫を確認(String 商品名, String カロリー, 
        int 容量, String 容器材質,int ケースあたり){

        return 外部の人.在庫伝票の確認(商品名,カロリー,容量,容器材質,ケースあたり);
    }
}
~~~
~~~java:受付.java
class 受付 {
    private String 商品名;
    private String カロリー;
    private int 容量;
    private String 容器材質;
    private int ケースあたり;
    private int 本数;
    public int 電話の結果を聞く(){
        商品名 = 外部の人.商品名確認();
        カロリー = 外部の人.カロリー確認();
        容量 = 外部の人.容量確認();
        容器材質確認 = 外部の人.容器材質確認();
        ケースあたり = 外部の人.ケースあたり確認();

	    本数 = 外部の人.発注数確認();

    }
    public int 在庫を聞く(){
        return 在庫管理者.在庫を確認(商品名,カロリー,容量,容器材質,ケースあたり);
    }
}
~~~
## 注文商品伝票を作って確認を楽にする
伝票を渡すことで在庫管理者とのやり取りを簡略化
外部の人には自分たちのルールを独自伝票を持ち込むことはできない
#### 在庫台帳 ※省略

~~~java:注文商品伝票.java
class 注文商品伝票 {
    public String 商品名;
    public String カロリー;
    public int 容量;
    public String 容器材質;
    public int ケースあたり;
}
~~~
~~~java:在庫管理者.java
class 在庫管理者{
    public static int 在庫を確認(注文商品伝票){
        
        return 外部の人.在庫伝票の確認(
            注文商品伝票.商品名,
            注文商品伝票.カロリー,
            注文商品伝票.容量,
            注文商品伝票.容器材質,
            注文商品伝票.ケースあたり);
    }
}
~~~
~~~java:受付.java
class 受付 {
    private 注文商品伝票 伝票;
    private int 本数;

    public int 電話の結果を聞く(){
        伝票 = new 注文商品伝票();
        伝票.商品名 = 外部の人.商品名確認();
        伝票.カロリー = 外部の人.カロリー確認();
        伝票.容量 = 外部の人.容量確認();
        伝票.容器材質確認 = 外部の人.容器材質確認();
        伝票.ケースあたり = 外部の人.ケースあたり確認();

	    本数 = 外部の人.発注数確認();

    }
    public int 在庫を聞く(){
        return 在庫管理者.在庫を確認(伝票);
    }
}
~~~

## 注文商品伝票の改ざんを抑止
一度書いた伝票を改ざんされるのはよくないので抑止。
#### 在庫台帳 ※省略

~~~java:注文商品伝票.java
class 注文商品伝票 {
    public final String 商品名;
    public final String カロリー;
    public final int 容量;
    public final String 容器材質;
    public final int ケースあたり;

    public 注文商品伝票(String 商品名, String カロリー, 
        int 容量, String 容器材質,int ケースあたり){

        this.商品名 = 商品名;
        this.カロリー = カロリー;
        this.容量 = 容量;
        this.容器材質確認 = 容器材質確認;
        this.ケースあたり = ケースあたり;
    }
}
~~~
~~~java:在庫管理者.java
class 在庫管理者{
//~省略~
}
~~~
~~~java:受付.java
class 受付 {
    private 注文商品伝票 伝票;
    private int 本数;

    public int 電話の結果を聞く(){
        String 商品名 = 外部の人.商品名確認();
        String カロリー = 外部の人.カロリー確認();
        int 容量 = 外部の人.容量確認();
        String 容器材質確認 = 外部の人.容器材質確認();
        int ケースあたり = 外部の人.ケースあたり確認();

        伝票 = new 注文商品伝票(商品名,カロリー,容量,容器材質,ケースあたり);
	    本数 = 外部の人.発注数確認();

    }
    public int 在庫を聞く(){
        return 在庫管理者.在庫を確認(伝票);
    }
}
~~~

## 注文商品リストの管理
伝票はしゃべらないが、人の目に視覚で情報を伝える。
伝票が横並びにおいてあれば、伝票同士は同じであることを人に視覚で伝える。
#### 在庫台帳 ※省略

~~~java:注文商品伝票.java
class 注文商品伝票 {
    public final String 商品名;
    public final String カロリー;
    public final int 容量;
    public final String 容器材質;
    public final int ケースあたり;

    public 注文商品伝票(String 商品名, String カロリー, 
        int 容量, String 容器材質,int ケースあたり){

        this.商品名 = 商品名;
        this.カロリー = カロリー;
        this.容量 = 容量;
        this.容器材質確認 = 容器材質確認;
        this.ケースあたり = ケースあたり;
    }

    @Override 
    public boolean equals(Object obj) {
        if (obj1 instanceof Color == false) {
            return false;
        }   
        注文商品伝票 伝票 = (注文商品伝票)obj;     
        if(this.商品名.equals(伝票.商品名) == false) return false;
        if(this.カロリー.equals(伝票.カロリー) == false) return false;
        if(this.容量 != 伝票.容量) return false;
        if(this.容器材質.equals(伝票.容器材質) == false) return false;
        if(this.ケースあたり != 伝票.ケースあたり) return false;

        return true;
    }
}
~~~
~~~java:注文集計担当.java
static class 注文集計担当 {
    
    private ArrayList<注文商品伝票> 注文伝票リスト = new ArrayList<注文商品伝票>();

    public static void 報告をうける(注文商品伝票 伝票){
        if(注文伝票リスト.contains(伝票) == false){
            注文伝票リスト.add(伝票);
        }        
    }
    public static int 報告をする(){
        return 注文伝票リスト.size();
    }
}

~~~

人間のやり取りでもコンピューターのやり取りでも、規模が大きくなれば伝票の存在が重要になってきます。