ラーメンモデリング

# したかったこと
ラーメンをモデリングし、コードに落とし込む

---
# きっかけ
* 先日、
<TABLE ALIGN=CENTER><TR><TD WIDTH=400px>
 <A HREF="https://www.slideshare.net/iwaoRd/20150917-52952731" TARGET="_blank"><STRONG>すしモデリング 20150917</STRONG></A>
 <A HREF="http://b.hatena.ne.jp/entry/https://www.slideshare.net/iwaoRd/20150917-52952731" TARGET="_blank">
 <IMG BORDER="0" SRC="http://b.hatena.ne.jp/entry/image/https://www.slideshare.net/iwaoRd/20150917-52952731" BORDER="0" ALT="" /></a>
 <BR>
 すしモデリング 20150917... 
 </TD>
 <TD WIDTH=150px>
 <IMG STYLE="float:left;margin-right:.5em;" SRC="http://capture.heartrails.com/120x120/cool?https://www.slideshare.net/iwaoRd/20150917-52952731" ALT="" WIDTH="120" HEIGHT="120" />
 </TD></TR>
</TABLE>
というものを知った
* 豚骨ラーメン、醤油ラーメンというカテゴリーがあまり好きじゃなく、ラーメンをきちんと説明したい
* モデルとコードの関係性を理解するためにもコードまで落とし込みたい

---
# 使ったもの
* [draw.io](https://www.draw.io/)：初めて使った。というかUMLもほぼ初めて
* C#：初めて使った
* [paiza.io](https://paiza.io/)

という状態なので、色々と不備があると思います。もしもアドバイス頂けると嬉しいです

---
# 作ったモデル
![ラーメン.png](https://qiita-image-store.s3.amazonaws.com/0/337041/072a5eb2-3d46-899b-538e-18607d06ac44.png)

---
# 言いたかったこと
* 「ラーメン食べに行こう！」と言いながら、つけ麺食べたり、汁なし食べたりする人もいるので、この文脈ではつけ麺などはラーメン（というカテゴリー）のひとつとしました
* スープは出汁とタレと香味油から成っています。いわゆる「豚骨ラーメン」にも薄口醤油が使われていますので「醤油ラーメン」とも言えます。逆にいわゆる「醤油ラーメン」の多くは鶏ガラを使っていると思いますが、部分的に豚骨を使っているものもあるはずで「豚骨ラーメン」とも言えます
* 汎化部分があまり自信ないです

---
# 書いたコード
```C#
using System;
using System.Collections.Generic;

public class Ramen {
    static void Main() {
        Noodles noodles = new Noodles("中太麺");
        Fond fond = new Fond("豚骨");
        fond.AddFond("鶏ガラ");
        Sauce sauce = new Sauce("醤油");
        Oil oil = new Oil("鶏油");
        Soup soup = new Soup(fond, sauce, oil);
        Topping topping = new Topping("チャーシュー");
        topping.AddTopping("ほうれん草");
        topping.AddTopping("のり");
        WithSoupRamen iekei = new WithSoupRamen("家系", noodles, soup, topping);
        Console.WriteLine(iekei.Explain());
    }
}

// 各クラスが自分自身の説明をするための共通のインターフェース
interface IExplainer
{
    string Explain();
}

// 汁あり
class WithSoupRamen : IExplainer {
    private string Name;
    private Noodles Noodles;
    private Soup Soup;
    private Topping Topping;
    
    public WithSoupRamen(string name, Noodles noodles, Soup soup, Topping topping) {
        Name = name;
        Noodles = noodles;
        Soup = soup;
        Topping = topping;
    }
    
    public string Explain() {
        return Name + "の\n" + Noodles.Explain() + "\n" + Soup.Explain() + "\n" + Topping.Explain();
    }
}

// 麺
class Noodles : IExplainer {
    private string WidthType;
    
    public Noodles(string widthType) {
        WidthType = widthType;
    }
    
    public string Explain() {
        return "麺の太さは" + WidthType + "です。";
    }
}

// スープ
class Soup : IExplainer {
    private Fond Fond;
    private Sauce Sauce;
    private Oil Oil;
    
    public Soup(Fond fond, Sauce sauce, Oil oil) {
        Fond = fond;
        Sauce = sauce;
        Oil = oil;
    }
    
    public string Explain() {
        return Fond.Explain() + "\n" + Sauce.Explain() + "\n" + Oil.Explain();
    }
}

// 出汁
class Fond : IExplainer {
    private List<string> Ingredients = new List<string>();
    
    public Fond(string ingredient) {
        AddFond(ingredient);
    }
    
    public void AddFond(string ingredient) {
        Ingredients.Add(ingredient);
    }
    
    public string Explain() {
        return "出汁は" + String.Join(", ", Ingredients) + "です。";
    }
}

// タレ
class Sauce : IExplainer {
    private List<string> Seasonings = new List<string>();
    
    public Sauce(string seadoning) {
        AddSauce(seadoning);
    }
    
    public void AddSauce(string seadoning) {
        Seasonings.Add(seadoning);
    }
    
    public string Explain() {
        return "タレは" + String.Join(", ", Seasonings) + "です。";
    }
}

// 香味油
class Oil : IExplainer {
    private List<string> Oiltypes = new List<string>();
    
    public Oil(string oiltype) {
        AddOil(oiltype);
    }
    
    public void AddOil(string oiltype) {
        Oiltypes.Add(oiltype);
    }

    public string Explain() {
        return "香味油は" + String.Join(", ", Oiltypes) + "です。";
    }
}

// 具
class Topping : IExplainer {
    private List<string> Toppings = new List<string>();
    
    public Topping(string topping) {
        AddTopping(topping);
    }
    
    public void AddTopping(string topping) {
        Toppings.Add(topping);
    }
    
    public string Explain() {
        return "具は" + String.Join(", ", Toppings) + "です。";
    }
}
```

---
# 補足説明
* Compositionをメンバー変数として表現しました。例えば、汁ありクラスが、麺クラス、スープクラス、具クラスの型のメンバー変数を保持しています
* 汎化はどう表現するのが正しいのかよくわかりませんでした。出汁クラスを継承した鶏ガラクラスを使ってもあまり効果なさそうだったので、出汁クラスのメンバー変数に鶏ガラという情報を書き込みました。そもそも汎化関係で表現したのが間違いだったかもしれません

---
# 後日追加すること

---
# 愛知県の好きなラーメン屋
* [麺創なな家](https://tabelog.com/aichi/A2305/A230501/23030995/)
* [らぁ麺 飛鶏](https://tabelog.com/aichi/A2303/A230301/23051026/)
* [麺座 かたぶつ](https://tabelog.com/aichi/A2303/A230302/23044368/)
* [つけ麺 丸和 春田本店](https://tabelog.com/aichi/A2301/A230113/23007487/)
* [麺屋三郎](https://tabelog.com/aichi/A2302/A230201/23053548/)
* [中華蕎麦 生る](https://tabelog.com/aichi/A2301/A230106/23061894/)
* [らーめん奏](https://tabelog.com/aichi/A2301/A230106/23056955/)
* [からみそラーメン ふくろう 本店](https://tabelog.com/aichi/A2301/A230110/23050032/)
* [らぁめんこはく](https://tabelog.com/aichi/A2301/A230110/23056803/)
* [大岩亭](https://tabelog.com/aichi/A2305/A230503/23041084/)
* [麺喰](https://tabelog.com/aichi/A2303/A230302/23040959/)
* [ラーメンめろう](https://tabelog.com/aichi/A2303/A230302/23044548/)

挙げるとキリがないのでこの辺で・・・