オブジェクト指向分析によるモジュール分割のイメージ

#伝えたいこと
モデリングとプログラミングが関係ないと思っている人向けです。
オブジェクト指向分析モデリングの結果を実装すると、コードが読みやすくなります。
実際には、「オブジェクト指向分析」がモジュール分割の非常に有効な手段である、ということです。
今回は、「顧客がクリーニング店に洗濯物を出す」という内容を、分析モデリングし、その後コードに変換しています。

#分析のクラス図
話を分かりやすくするために、クラス図はかなり小さなネタにしています。
クリーニング店と顧客の関係で、特に、顧客が衣服を行きつけのクリーニング店にクリーニングしてもらうという関係性だけを表しています。
![クリーニング店のクラス図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197297/c48a9c36-124c-d583-bfa6-d553fdc738f2.jpeg)
見て分かるように、非常に素直に伝えたい人間関係やモノの関係を、ポンチ絵的に表した（クラス）図です。
これならば、プログラミングと関係なく、人と人が共有して話し合っても、話しやすい図になっているのではないでしょうか。

#分析のシーケンス図
とても単純ですが、顧客がクリーニング店に行って、クリーニングしてもらう流れを描きました。
単純化するために、クリーニングは同期で書いてあります（つまり、クリーニングが終わるまでそこで待っている）ので、そこは突っ込まないでください(^^)。
![クリーニング店のシーケンス図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197297/3b4fae2c-d426-7dea-4752-54f95c0f4e75.jpeg)

#そのモデルを、そのままコード
Program.csは、
クリーニング店と顧客のインスタンスを生成して、
顧客に、クリーニングの回数券を買わせ、
顧客に、服を汚させて、
次に、
顧客に、クリーニング店に行かせています。 // シーケンス図は、ここだけ描いてある。

```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cleaners
{
    class Program
    {
        static void Main(string[] args)
        {
            // クリーニング店
            Cleaners cleaners = new Cleaners();
            // 行きつけのクリーニング店のある顧客
            Customer custmer = new Customer(cleaners);

            // 回数券を買う
            custmer.BuyCouponTicket();

            // 服を汚す
            custmer.StockDirtyLaundry();

            // クリーニング店に行く
            custmer.GoCleaners();
        }
    }
}
```

Custmer.csは、「顧客」クラスです。
クラス図を、まんま、コードに落としています。
サンプルプログラムなので、コンストラクタで、洋服を持たせてしまいましたが、ご愛敬としてください。
最後の関数「クリーニング店に行く」がシーケンス図で示したものです。
シーケンス図と比べると対応していると思います。

```csharp:Custmer.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cleaners
{
    // 顧客
    class Customer
    {
        // 行きつけのクリーニング店のある顧客
        public Customer(Cleaners regularCleaners)
        {
            RegularCleaners = regularCleaners;
            CleanLaundry.Add(new Clothes("T-Shirt"));
            CleanLaundry.Add(new Clothes("Jacket"));
        }

        // 汚れた洗濯物
        public List<Clothes> DirtyLaundry { get; } = new List<Clothes>();

        // 回数券
        private Queue<Coupon> CouponTicket { get; } = new Queue<Coupon>();

        // 行きつけのクリーニング店
        private Cleaners RegularCleaners = null;

        // きれいな洗濯物
        public List<Clothes> CleanLaundry { get; } = new List<Clothes>();

        // 汚れものを貯める
        public void StockDirtyLaundry()
        {
            // きれいな洗濯物をひとつ取り出して、
            Clothes clothes = CleanLaundry[0];
            CleanLaundry.RemoveAt(0);

            // その洗濯物を、汚れた洗濯物にする
            clothes.Dirty = true;
            DirtyLaundry.Add(clothes);
        }

        // 回数券を買う
        public void BuyCouponTicket()
        {
            // お金は払ってないけれど、省略しているだけ
            CouponTicket.Enqueue(new Coupon());
        }

        // クリーニング店に行く
        public void GoCleaners()
        {
            // 行きつけのクリーニング店.洗濯する(汚れた洗濯物,回数券);
            List<Clothes> clothes = RegularCleaners.Wash(DirtyLaundry, CouponTicket.Dequeue());
            // 仕上り品としてしまう
            CleanLaundry.AddRange(clothes); 
        }

    }
}
```

Cleaners.csは、「クリーニング店」クラスです。
洗濯する関数だけがありますので、これがシーケンス図内に描かれている部分です。

```csharp:Cleaners.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cleaners
{
    // クリーニング店
    class Cleaners
    {
        // 洗濯する
        public List<Clothes> Wash(List<Clothes> clothes,Coupon coupon)
        {
            // 回数券クーポンを破棄し
            // (略)

            // 洗濯する
            foreach(Clothes oneClothes in clothes)
            {
                oneClothes.Dirty = false;
            }

            // 返却する
            return clothes;
        }
    }
}
```

#分析モデルとコードを見て
クラス図、シーケンス図、コードを見て、
分析モデルで特定したクラスが、そのままモジュール分割に利用されているのが分かりますよね。
つまり、逆に言えば、モジュールがポンチ絵的な構造をしている、とも言えます。
ポンチ絵的な構造だったら、人間にとって、より分かりやすいですよね。

より素直なコードに見えると思うのです。

これが、オブジェクト指向分析が、モジュール分割に有効な手段の一つだということです。
もしよかったら、参考にしてください。