【UMLでプリキュア】変身のセリフのクラス図

#前回からの流れ
プログラミング言語ドリブンのプリキュアシリーズに便乗しようと、
第一作【UMLでプリキュア】を作成。

これまでの、プログラミング言語のプリキュアシリーズ同様に、
変身のセリフを言わせるため、詳細な検討を始めると、
「プリキュアの変身」に対する理解の甘さを実感。【UMLでプリキュア】変身のモデル見直しを投稿。

しかし、やはり理解が不十分とのことで、
全プリキュアの変身のセリフをオブジェクト図を使って分析し直すこととした。

オブジェクト図で見直すと良いとのコメントいただき、感謝。
それでは、お楽しみください。

#特徴的な変身のオブジェクト図
全プリキュアのオブジェクト図は、別途[こちら](https://qiita.com/azuki8/items/1dc6d84af3af8d54eac1)を参照。
ここでは、特徴的なものをピックアップして紹介します。
##「ふたりはプリキュア Splash Star」
現在とは異なり、「開始の合図」と「名乗り」以外に、「心意気」や「相手へのメッセージ」がある。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/f4cd0f18-a6cf-af95-498b-b740ffd3025a.png)
##「Yes! プリキュア5 GoGo!」
以降のシリーズで基本となる「開始の合図」「個人の名乗り」「チームの名乗り」型が確立する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/8e5604b7-af18-dc58-6ace-d594433cd7b4.png)
##「ドキドキ！プリキュア」
「開始の合図」を分担する形式が始まる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/43955e1f-0191-f722-fcb5-ae36e0590fce.png)
##「HUGっと！プリキュア」
今までにない、「個人の名乗り」の前に、個人に集中させる音（歌舞伎では「ツケ」というらしい）が導入される。「チームの名乗り」がないことは、革命的。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/8a9d295a-5c6d-6477-96a9-5ddc10a26c52.png)
##別資料
2018年7月現在の全プリキュアの「変身のセリフ」のオブジェクト図は、[こちら](https://qiita.com/azuki8/items/1dc6d84af3af8d54eac1)。

#オブジェクト図から導いたクラス図
・変身シーンのセリフは、セリフの集まり
・セリフには、役割（＝ロール名、関連端名）がある
・セリフを言うプリキュアが決まっている
ことから、以下のクラス図とした。

セリフをまとめて1つの関連端「詳細セリフ {ordered} 」にもできるが、
「プリキュアの変身のセリフ」たる特徴を、複数の関連端名で表現した。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/c6bc2349-a69a-07ca-6491-4cc43f6e6d78.png)

このほかに候補に挙がったクラス図は、[こちら](https://qiita.com/azuki8/items/a935120c3365a4f374ae)。

#C#コードにしてみる
やはり、コードにしてみる。
コピペして、ビルドすれば、動きます。

##プリキュア.cs

```csharp:プリキュア.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace UMLでプリキュア
{
    // 属性は、全般的に省略

    class プリキュア
    {
        private string _プリキュア名;
        public string プリキュア名
        {
            get { return _プリキュア名; }
        }

        public プリキュア(string プリキュア名)
        {
            _プリキュア名 = プリキュア名;
        }

        public void 叫ぶ(string 言葉)
        {
            Console.WriteLine("「" + 言葉 + "」");
        }
    }
}
```

##セリフ.cs

```csharp:セリフ.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace UMLでプリキュア
{
    class セリフ
    {
        #region 発言者
        private List<プリキュア> _発言者 = new List<プリキュア>();
        public List<プリキュア> 発言者
        {
            get { return _発言者; } // リスト自体を書き換えられないようにgetのみ
        }
        #endregion

        #region 言葉
        private string _言葉;
        public string 言葉
        {
            get { return _言葉; }
        }
        #endregion

        public セリフ(string 言葉, List<プリキュア> 発言者)
        {
            this._言葉 = 言葉;
            foreach(プリキュア pricure in 発言者)
            {
                this._発言者.Add(pricure); // リストはセリフ自体の特性なので、外から与えないこととした。
            }
        }
    }
}
```

##変身シーンのセリフ.cs

```csharp:変身シーンのセリフ.cs
using System;
using System.Collections.Generic;

namespace UMLでプリキュア
{
    class 変身シーンのセリフ
    {
        // List自体を、外から差し替えられないようにprivateにしている
        private List<セリフ> 開始の合図 = new List<セリフ>();
        private List<セリフ> ツケ = new List<セリフ>();
        private List<セリフ> 心意気 = new List<セリフ>();
        private List<セリフ> 個人の名乗り = new List<セリフ>();
        private List<セリフ> 相手へのメッセージ = new List<セリフ>();
        private List<セリフ> 目的メッセージ = new List<セリフ>();
        private List<セリフ> チームの名乗り = new List<セリフ>();

        public 変身シーンのセリフ(
            List<セリフ> 開始の合図,
            List<セリフ> ツケ,
            List<セリフ> 心意気,
            List<セリフ> 個人の名乗り,
            List<セリフ> 目的メッセージ,
            List<セリフ> チームの名乗り,
            List<セリフ> 相手へのメッセージ)
        {
            // Listは「変身シーンのセリフ」の特性であると考えられるため、
            // 引数のリストをそのまま代入せずに、中身だけを代入する
            if( 開始の合図 != null)
            {
                foreach (セリフ serif in 開始の合図)
                {
                    this.開始の合図.Add(serif);
                }
            }
            if (ツケ != null)
            {
                foreach (セリフ serif in ツケ)
                {
                    this.ツケ.Add(serif);
                }
            }
            if (心意気 != null)
            {
                foreach (セリフ serif in 心意気)
                {
                    this.心意気.Add(serif);
                }
            }
            if (個人の名乗り != null)
            {
                foreach (セリフ serif in 個人の名乗り)
                {
                    this.個人の名乗り.Add(serif);
                }
            }
            if (目的メッセージ != null)
            {
                foreach (セリフ serif in 目的メッセージ)
                {
                    this.目的メッセージ.Add(serif);
                }
            }
            if (チームの名乗り != null)
            {
                foreach (セリフ serif in チームの名乗り)
                {
                    this.チームの名乗り.Add(serif);
                }
            }
            if (相手へのメッセージ != null)
            {
                foreach (セリフ serif in 相手へのメッセージ)
                {
                    this.相手へのメッセージ.Add(serif);
                }
            }
        }

        public void 開始()
        {
            if (開始の合図 != null && 開始の合図.Count > 0)
            {
                foreach (セリフ serif in 開始の合図)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (ツケ != null && ツケ.Count > 0)
            {
                foreach (セリフ serif in ツケ)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (心意気 != null && 心意気.Count > 0)
            {
                foreach (セリフ serif in 心意気)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (個人の名乗り != null && 個人の名乗り.Count > 0)
            {
                foreach (セリフ serif in 個人の名乗り)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (目的メッセージ != null && 目的メッセージ.Count > 0)
            {
                foreach (セリフ serif in 目的メッセージ)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (チームの名乗り != null && チームの名乗り.Count > 0)
            {
                foreach (セリフ serif in チームの名乗り)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
            if (相手へのメッセージ != null && 相手へのメッセージ.Count > 0)
            {
                foreach (セリフ serif in 相手へのメッセージ)
                {
                    プリキュアがセリフを叫ぶ(serif);
                }
                Console.WriteLine();
            }
        }

        private void プリキュアがセリフを叫ぶ(セリフ serif)
        {
            foreach (プリキュア pricure in serif.発言者)
            {
                Console.Write(pricure.プリキュア名 + ":");
                pricure.叫ぶ(serif.言葉);
            }
        }
    }
}
```

##Program.cs

```csharp:Program.cs
using System;
using System.Collections.Generic;

namespace UMLでプリキュア
{
    class Program
    {
        static void Main(string[] args)
        {
            プリキュア キュアホワイト = new プリキュア("キュアホワイト");
            プリキュア キュアブラック = new プリキュア("キュアブラック");
            セリフ 開始の合図 = new セリフ("デュアル・オーロラ・ウェーブ！", new List<プリキュア>(){ キュアホワイト,キュアブラック});
            セリフ 個人の名乗り1 = new セリフ("光の使者！キュアブラック！", new List<プリキュア>() { キュアブラック });
            セリフ 個人の名乗り2 = new セリフ("光の使者！キュアホワイト！", new List<プリキュア>() { キュアホワイト });
            セリフ チームの名乗り = new セリフ("ふたりはプリキュア！", new List<プリキュア>() { キュアホワイト, キュアブラック });
            セリフ 相手へのメッセージ1 = new セリフ("闇の力のしもべたちよ！", new List<プリキュア>() { キュアホワイト });
            セリフ 相手へのメッセージ2 = new セリフ("とっととお家に帰りなさい！", new List<プリキュア>() { キュアブラック });
            変身シーンのセリフ ふたりはプリキュアの変身 = new 変身シーンのセリフ(new List<セリフ>() { 開始の合図 }, null, null, new List<セリフ>() { 個人の名乗り1, 個人の名乗り2 }, null, new List<セリフ>() { チームの名乗り }, new List<セリフ>() { 相手へのメッセージ1, 相手へのメッセージ2 });
            ふたりはプリキュアの変身.開始();
#if DEBUG
            Console.WriteLine("続行するには何かキーを押してください．．．");
            Console.ReadKey();
#endif
        }
    }
}
```

##実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/197297/3b2d5a10-c8d1-cfae-65d3-78449b0c78a2.png)

#感想
今回は、変身の部分だけをモデル化しました。
元々は、もう少し広範囲を狙っているので、他の範囲までモデルを広げてみる予定です。

UMLモデリングも、こうやって、コードに落ちてゆくところまで見ると、
何か、楽しくないですか？
「UMLモデリングは、なんかなぁ」と思う方は、
クラス分割法として捉えてもらっても良いと思います。