【システム設計】オブジェクト指向とは

##システム設計の種類
####手続き型
上から下に処理を書いていく方法です。
　メリット：
　　　・書き方が簡単です。
　　　・簡単な処理なら一番早く書けます。

　デメリット
　　　・変更が必要になった場合に、いろんな箇所を書き換える必要が出てきます。
　　　 なので、結局再設計が必要になります。


####オブジェクト指向
プログラミングの対象を「モノ」としてとらえて設計していく手法です。
例えば、車に乗ることを考える場合、車に乗る「人」と、「車」をそれぞれ「モノ」として定義して、「モノ」の一つ一つがどのような動きをするかをプログラミングしていく手法です。
![obj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/3878960a-fc5d-7830-5509-2f693296fd53.png)

　メリット：
　　・一度ルール付けすると、簡単に変更できるので、仕様が変更になった時に再設計することが簡単です。
　　　　⇒なので、最近ではオブジェクト指向を利用してプログラミングすることが主流になっています。

　デメリット：
　　・オブジェクト設計する手間と時間がかかる。



##オブジェクト指向の用語と概念

####クラス
モノ（オブジェクト）を作るための設計図です。
オブジェクトがどんなことをするのか？どんなことを覚えておくのか定義します。

例えば、
　人なら、どんな名前か？何歳か？、どんな動作ができるのか？
　車なら、どんな色か？どんな操作ができるのか？
こういったことを定義するのです。

この設計図（クラス）があれば、何個でもモノ（オブジェクト）を作成できます。

####オブジェクト
設計図（クラス）から生成した、モノの実態です。これが動きます。


####インスタンス化
プログラムで設計図（クラス）からモノ（オブジェクト）を生成させることです。

　![クラスとオブジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/d1e472de-16cd-045c-9375-014197f2f266.png)




####プロパティ
オブジェクトの状態を表します。
つまり
　人なら、「名前」「年齢」「髪の色」「現在の体力値」「身長」「体重」
　車なら、「車体の色」「製造年月日」「現在までの走行距離」「車種」
などの状態を表すものです。

####メソッド
オブジェクトに対する操作を記載します。
つまり
　人なら「立つ」「歩く」「走る」「食べる」「寝る」
　車なら「前に走る」「止まる」「後ろに走る」「燃料の残高を表示する」
などの操作(処理)を定義します。

####カプセル化
オブジェクトの外から、プロパティを直接アクセスできないようにして、
メソッドを使わないとアクセスできないようにすることです。
つまり、プロパティを外から隠すのです。
こうすることで、外から不整合な操作をできなくさせるのです。

例えば、「車」オブジェクトで、ある「距離」の分「走る」操作をするとします。

この操作は
①「車」の「ガソリン残量」から「燃費」をもとに「走行可能距離」を出して、「距離」の分走れるか確認し
②「ガソリン残量」を引いて、「現在までの走行距離」に「距離」の分加算する
とします。

そうすると、この「ガソリン残量」や「現在までの走行距離」「燃費」のプロパティを外から勝手に変えられてしまったら
処理がおかしくなりますよね？
それに、この車を使う人は、いちいち「ガソリン残量」や「現在までの走行距離」「燃費」なんていちいち指定して乗りたいわけではありません。なのでこういった情報は外側から隠して見えなくするのです。
内側は複雑な物だとしても、外からは簡単で使いやすい機能を提供させます。

####継承
特定のオブジェクトの持つ機能を引き継いで使うことです。
例えば、車だと
「セダン」「コンパクトカー」「ワゴン」「軽自動車」と種類がありますけど
車は　「前に走る」「止まる」「後ろに走る」「燃料の残高を表示する」
といった機能はどの車も共通ですよね？
なので、「車」クラスにこういった処理を記載します。

例えば、「軽自動車」だと
ダイハツの「ムーブ」とか「ミラ」などは、「車体」の一部は同じものを利用していたりしますよね。
なので、「軽自動車」クラスにそのような特徴を記載します。

![継承.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/fcfcd067-a380-8eb0-6b6c-c0a78702ab59.png)

####ポリモーフィズム
日本語で「多様性」「多態性」といいます。
同じ呼び出し方法をした場合、呼び出し先のオブジェクトの性質で結果が違うということです。

例えば、「動物」で表すと「犬」「猫」「ニワトリ」は鳴きますよね。
でも
　犬が鳴く　　　　→　ワンワン
　猫が鳴く　　　　→　ニャー
　ニワトリが鳴く　→　コケコッコー

と結果が変わりますよね。

そんな感じで、呼び出し元は、単に「鳴け」と同じ命令を出せばよくて、
結果はそれぞれのオブジェクトの性質で変わるようにすることです。

これは、「継承」と「カプセル化」の技術を利用することで実現します。
メリットとしては、コードがきれいになり、プログラムの変更に柔軟になります。

##オブジェクト指向を目指すうえでの９つのルール
下記を意識するとオブジェクト指向を意識して設計できるようです！
挑戦してみましょう。

####1. 1つのメソッドにつきインデントは1段階まで
　処理を複雑にしすぎないようにする効果があります。
　複雑な処理は他のメソッドを呼ぶか、他のクラスのメソッドを呼びます。

####2. else句を使用しないこと
　これも処理を複雑にしない効果があります。
　ガード節（早い段階でパラメータをもとにチェックして例外を投げたりreturnをする）を利用するポリモーフィズムを
　利用することで  elseを使わないようにします。

###3. 全てのプリミティブ型と文字列型をラップする
　これは数字や文字列などを一つのクラスとして、カプセル化して使用するということです。
　例えば、メールアドレスなら、String型を使わずに、String型のプロパティを持つmailAdress型とかを作って、
　それを使うようにします。
　こうすることで、メールアドレス文字列とメールに対する操作（例えばメール形式チェック）を一つにすることができる
　ので変更箇所を局所化できます。

####4. 1行につきドットは1つまでにする
　つまり、１つのクラスがいろんな役割を持つようにすることはやめて、
　1つのクラスが単純な機能をもつクラスとしてそれを組み合わせるようにします。
　そしてカプセル化を徹底化することで、クラスが他のクラスのもつクラスなどに
　複雑に入り込んで操作するようなことがないようにします。

####5. 名前を省略しない
　名前を省略しすぎると、このクラスが何を持っているのか、何をするのか、かわからなくなります。
　省略しないようにします。



###6. 全てのエンティティを小さくする
50行を超えるクラス、10ファイルを超えるパケッージを作らないようにします。
つまり、処理は積極的に、細かくクラスに分けてそれを組み合わせるようにします。


####7. 1つのクラスに付きインスタンス変数は2つまでにする
一つのクラスの持つ状態を２つまでにすることで、クラスを凝縮化します。クラスが小さくなります。

####8. ファーストクラスコレクションを使用する
ListやMapなどをファーストクラスコレクションといいます。
コレクションを持つクラスは他のプロパティを記載しないようなクラスにします。

####9. Getter, Setter, プロパティを使用しない
プロパティを直接・設定・取り出しできるGetter, Setterメソッドを使わないようにします。
自分のクラスの振る舞いを他のクラスから操作できてしまうことを極力なくします。


##オブジェクト指向設計が上手くなるためには
####1. 他の人が書いたソースを読もう
他の人が書いたソースはとても参考になると思います。
社内のソースコードやGitHubにUPされているソースコードなどいろいろと研究できるものはあります。
興味のあるソースコードを是非チェックしてみてください。

####2.Gang of Fourのデザインパターンを覚えよう
デザインパターンとは、設計パターンのことです。過去のエンジニアが解決してきた方法が、デザインパターンとしてまとめられています。
特にその中でもGang of Fourのデザインパターンで紹介されている23個のパターンが、オブジェクト設計ではお手本となります。
参考書を読んで勉強してみましょう。

■オブジェクト指向における再利用のためのデザインパターン
https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF-%E3%82%AC%E3%83%B3%E3%83%9E/dp/4797311126

■増補改訂版Java言語で学ぶデザインパターン入門
https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030/ref=tmm_other_meta_binding_swatch_0?_encoding=UTF8&qid=&sr=

####3.各種ソフトウェア設計パターンを勉強しよう
いろんな設計パターンがあります。調べて勉強してみましょう。
・MVC
・MVVM
・DDD（ドメイン駆動設計）