LoginSignup
5
2

More than 5 years have passed since last update.

[メモ]オブジェクトデザイン 1章-設計概念

Posted at

オブジェクトは賢くあるべき

  • 自分自身の属性を持ち、役割を持っている(使われる側のオブジェクト)
  • オブジェクトを利用したり、協調結果を参照して自律的に判断する(オブジェクトを使うオブジェクト)
    ただ、こいつもどこかから参照して使えるようにはなっているべき?

あるレベルでは一部であり、あるレベルでは全体となれる

オブジェクトの振る舞いは設計された振る舞いに厳密に制限される
→行き当たりばったりのやんわりプログラミングでは到達できない

ソフトウェアの構成

  • アプリケーション: 相互作用するオブジェクトの集合
  • オブジェクト: 1つ以上のロール(役割)の実装
  • ロール: 関連する責務の集合
  • 責務: タスクを実行する義務、または情報を知っている義務
  • コラボレーション: オブジェクトもしくはロールの相互作用
  • 契約: あるコラボレーションを行う際に満足すべき条件を要約した取り決め
    (これはコラボレートを行うオブジェクトが持つのかコラボレートされるオブジェクトが持つのか
    オブジェクトが持つと役割が増えるのでこれはオブジェクトを使う側が判断するべきかな)

ロール

オブジェクトが意図された環境で行われるべき役目のこと

抽象化された役目について、責任を持つオブジェクトは交換可能であるべき。
役目を果たすためのロジックの集合体。

ex.)
例えばecサイトの支払いという責務については
コンビニ払い
クレジット払い
着払い
等のロジックがある。
支払いという役目が発生した時にロジックが選択可能であれば良い。

多分遠回しにストラテジーパターンのことを言っているのだと思う

一貫した使いやすいオブジェクトを作り上げるために

オブジェクトのロールステレオタイプという概念
オブジェクトの責務を単純化し、パターンを定義する。
→オブジェクトのロールを考える時にどういうオブジェクトを作ろうとしているか理解しやすくなる

  • 情報保持役
  • 構造化役
  • サービス提供役 : 一般に演算サービスを行う
  • 調整役
  • 制御役
  • インターフェース役

オブジェクトの契約

責務を果たすための条件をもれなく保証する。
あるオブジェクトを使用するときの決まりごとなど

単純な話、責務(業務ドメイン)を行うためにロールの集合体があり、コラボレータによってロールが利用されるのかな。

パターン

オブジェクト指向で開発してきた熟練者たちが、よく出くわす問題を抽象化しパターン化したもの

「オブジェクト志向における再利用のためのデザインパターン」が詳しいようだ。

後述のDouble Dispatchパターンが見ていて気持ちよかったので
この本も読んでみたい。

Double Dispatchパターン(visitorパターン)

一般的に2つの相互に関係を持つオブジェクトに対して、受け入れ側が行う処理は
受け入れた相手のオブジェクトに任せる(時には自身、受け入れ側を渡す)ことで
ifやswitchの条件分岐を減らし、保守性をあげる。

例(コードは割愛)

じゃんけん

あくまで、一対一の前提。

出した手同士を戦わせて、win, draw, loseを出力する。

Rock、Scissors、Paperのオブジェクトを用意する。

それそれのオブジェクトは、じゃんけんというインターフェースを実装する

じゃんけんインターフェース
interface じゃんけん{

    public function fight(じゃんけん $obj){}

    public function resultRock(): string{}

    public function resultPaper(): string{}

    public function resultScissors(): string{}

}

各result*()メソッドの実装方法は、自分と戦わせた時の結果を返すようにする。
例えば、RockのresultPaper()の返り値は、lose
RockはPaperに勝てないから

fightメソッドの実装はというと、受け取ったオブジェクトに自分との結果を
問い合わせるようにする。
これがvisitorパターンと呼ばれる由来なのか

どういうことかというと、Rockでの実装はこんな感じ

Rock

public function fight(じゃんけん $obj)
{
    return $obj->resultRock();
}

うん、オブジェクト同士が連携していていい感じ、これを本で見たときには
キレイだなぁと感動しました。

そして、じゃんけんを行う際には
オブジェクトが持つfightメソッドに相手が出した手のオブジェクトを渡す

実行
$rock = new Rock;
$paper = new Paper;

echo $rock->fight($paper); //lose
echo $paper->fight($rock); //win

デメリット

登場人物が増えた際に各オブジェクトを修正しなければならないので
登場人物が固定されているときに役立つ

頻繁に判定を行うための登場人物が増えるような問題を扱うには向いていない

感想

まだ一章だが、理解して読むために1ページを何度か戻って読まなければならない
重めの本だと学習。

それだけ自分のオブジェクト指向で書いたり設計したりするための概念的な部分が
抜けていたんだなと。

Double Dispatchパターンはじゃんけん以外の現実世界での例がないかなと探していましたが
見つからなかったので、じゃんけん例を借りることに

何かあればご教授ください、、実装課題として使いたい。

多分、2章が終わる頃にはこの部分は抜けているんだろうな。。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2