名詞と動詞 シンプルなコードを書くアイデア

# TL;DR
- クラス名は名詞でつけような
- 配列変数は複数形にしてくれな
- メソッド名は動詞でつけような
- メソッド名でメソッドの実装を説明するのはやめとこうな
- プロパティを使ってメソッドを変数同然にしてみてもいいんじゃない？

# はじめに
ここに書かれていることは僕がプログラミングを楽しむなかで思いついた**ちょっとしたアイデア**であって、いい手段かもしれないが正解ではないかもしれないし、必要不可欠なものではないかもしれない。

だから、ここに書かれているアンチパターンをしていたとしても、それをすべて否定するわけではないことを覚えておいてほしい。

プログラミングに対して理解を深めるにつれ、コードのスタイルはどんどん移り変わってゆく。
必要だと、参考にしてみようかと感じたタイミングでこの記事を読んでくれると嬉しい。

また、あたかも熟練者のような書き方をしているが、筆者は超平凡な学生なのでその辺はオ〇イリー本的なジョークだと思って流してもらいたい。

以下、例としてコードを上げる際はC#を利用する。

## 影響を受けたもの
いわゆる参考文献。
### リーダブルコード
何かしらのプログラミング言語を理解しはじめたらぜひ読んでほしい。
シンプルなコードを書くための実践的なテクニックが記されている。

### プログラミングでよく使う英単語のまとめ【随時更新】
[プログラミングでよく使う英単語のまとめ【随時更新】](https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923)
万物に名前を付けるにあたって、必要最低限の英単語の語彙を身につけることができるエントリ。
codicもいいサービスだけど、こういうエントリを読んでまずは英単語に理解を深めるのも大事だと思う。

# 名詞と動詞を意識しよう
プログラミング**言語**とある通り、プログラミング言語でも単語の品詞を意識してあげるとグッと読みやすいコードになる。

例えば、クラス名や変数名を名詞で、メソッド名を動詞で宣言してみることにしよう。

```csharp
public float getArea(float height, float width){
    return height*width;
}
```

`area`は面積、`height`は高さで`width`は幅を表す英単語であることを知っていれば、このメソッドは面積を求めるものであると予測することができるだろう。
意味を持った単語で仮引数が名付けられているため、後で書き換える必要が出てきたとき、どの引数が何を表しているかが明確である。

このようなコードで構成されていれば後から変更を加えるときでもつらくない。
未来の自分や、他のメンバーのために、やさしさにあふれたコードのアイデアを見ていこう。

# 名詞
## 名詞とは
ものの名称を表す語のこと。

## 配列を保持する変数名は複数形にしてあげよう
名詞はとても便利なことに**自身が単数であるか、複数であるかをとても簡単に表すことができる**。

```csharp
var fruits = new Fruit[3];
var fruit = new Fruit();
```

可算名詞ならば配列は複数形にしてあげよう。
ループ処理が必要か不要か、一見するだけで判断ができる。

## クラス名を名詞で定義する
クラスはプログラムにおいて**モノを表す要素**だ。

```csharp
class Book{
    string title;
    Page pages;
    private int openingPage = 0;

    public Book(string title, Page[] pages){
        this.title = title;
        this.pages = pages;
    }

    Page getPage(){
        return pages[openingPage];
    }

    int getPageCount(){
        return pages.length;
    }

    void next(){
        if(getPageCount > openingPage){
            openingPage++;
        }
    }

    void previous(){
        if(getPageCount > 0){
            openingPage--;
        }
   }
}
```

本を`Book`としてクラスで表現するとこのようになるだろう。
Pageというものが別で定義されていて、本は今開かれているページとタイトルを持つ。
他にも著者や出版社という要素が必要ならば、それに応じて増やせば簡単に対応できるだろう。

また、本はページをめくることができるよね。
次のページヘとめくる`next`メソッドと前のページへ戻る`previous`メソッドを作ってみた。

**メソッドは動詞で名付けた**。これはとても大事なことだ。

# 動詞
## 動詞とは
ものの動きを表す語のこと。

## メソッドは動詞で名付けよう
動詞はものの動きを表す語だ。
メソッドはクラスの動きを定義することができる。メソッドの名付けを行うのは動詞が適任だ。

先程の`Book`クラスでもページをめくるメソッドを動詞で名付けている。

```csharp
class Book{

    //...

    void next(){
        if(getPageCount > openingPage){
            openingPage++;
        }
    }

    void previous(){
        if(getPageCount > 0){
            openingPage--;
        }
   }
}
```

動詞で名づいているとどのような動きをするのかイメージがしやすい名前になる。

### 19/07/11 追記
<font color="red">`next`、`previous`は動詞じゃないらしい。すいません。</font>
本項なら`goPreviousPage`とかが適切でしょうが、ソフトのウィザードなんかで`next`/`previous`という表記がよく使われてるから使ってしまいました。
命名を悩んで、その名前にした理由があるのなら使ってしまっても問題ないと思います。

記事としては正しくないですね。申し訳ない。

### メソッド名のアンチパターン
**メソッドの処理内容を説明するメソッド名は避けたほうが良いだろう**。
例えばこのようなメソッドだ。

```csharp
void countUpOpeningPageNum(){
    openingPageNum++;
}
```

`countUpOpeningPageNum`という名前。
フィールドの`openingPageNum`を数え上げるというのはわかるのだが、**クラスの外側からしたらその情報は不要**なのだ。
**そのメソッドを実行したらインスタンスはどうなるのか**、そういった情報をメソッド名に含むべきであり、内部で何をしているのかは意識させる必要がない。

それが巷で話題の**カプセル化**という考え方。
これを意識することで**難しい処理も表面上はシンプル**に動いているように見えるのだ。

もし、内部でどんな処理をしているのか、クラスを使うときに知る必要があるというならば、クラスの設計を見直すのが好ましいだろう。

# そのメソッド、プロパティがいいんじゃない？
先程の`Book`クラスをもう一度見てみよう。

```csharp
class Book{
    string title;
    Page pages;
    private int openingPage = 0;

    public Book(string title, Page[] pages){
        this.title = title;
        this.pages = pages;
    }

    Page getPage(){
        return pages[openingPage];
    }

    int getPageCount(){
        return pages.length;
    }

    void next(){
        if(getPageCount > openingPage){
            openingPage++;
        }
    }

    void previous(){
        if(getPageCount > 0){
            openingPage--;
        }
   }
}
```

`getPage`に`getPageCount`、JavaやPHPのような言語ならこれらのメソッドは必要なのだが、僕らの書いている言語は**C#**、**プロパティ**という機能を使ってみよう。

# プロパティ
プロパティは以下のように記述すると定義することができる。

```csharp
class ExampleClass{
    // クラス内部で扱われる変数
    private int num = 10;
    private string message = "Hello";

    // R/Wできるプロパティ
    public int Num{
        // 代入される時
        set{ this.num = value;}

        // 値を読まれる時
        get{ return num;}
    }

    // Read onlyなプロパティ
    public string Message{
        get{ return message; }
    }
}
```

これらのプロパティを扱うときはこう。

```csharp
var instance = new ExampleClass();

// numの読み書き
var a = instance.Num;
instance.Num = 10;

// messageの読み書き
var msg = instance.Message;
```

...というような感じにできる。
これだと魅力を伝えることが難しいので`Booku`クラスで考えてみよう。

## プロパティのうれしいポイント
`Book`クラスをプロパティを活用して書き換えてみる。

```csharp
class Book{
    string title;
    Page pages;
    private int openingPage = 0;

    public Book(string title, Page[] pages){
        this.title = title;
        this.pages = pages;
    }

    Page page{
        get{ return pages[openingPage];}
    }

    int pageCount{
        get{ return pages.length;}
    }

    void next(){
        if(getPageCount > openingPage){
            openingPage++;
        }
    }

    void previous(){
        if(getPageCount > 0){
            openingPage--;
        }
   }
}
```

先程まで`getPage`や`getPageCount`のようなメソッドで定義したものをプロパティとして`page`、`pageCount`と定義した。
プロパティの内部ではメソッドを動かしたりして、値を加工することができる。
しかし、呼び出す側の見た目は変数と変わらないのが特徴だ。

```csharp
var pages = new Page[10];

// pagesをいい感じになんかしたとして...

var book = new Book("不思議の国のアリス", pages);

// プロパティにする前
var readingPage = book.getPage();
var pageCount = book.getPageCount();

// プロパティにしたあと
var readingPage = book.page;
var pageCount = book.pageCount;
```

変数と変わらない見た目であれば、内部の処理を全く意識することなく扱うようになるし、メソッドを呼び出すよりも見た目が自然なコードになると思わないかい？

---

少しの工夫で僕らのコードはもっと流暢になれる。
さぁ、作業的に書いてきたコードを、ひとつの小説を書くような気持ちで書いてみよう。

---

繋がりたい猛者はこちらから → [Twitter](https://twitter.com/okmt_okmt_)