Rubyスタイルガイドを読む: クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど

こんにちは、hachi8833です。Rubyスタイルガイドを読むシリーズ、今回の「クラスとモジュール編」の2回目に予定していた部分がかなりこってりしているので、3回に分けることにしました。よろしくお願いします。 今回取り上げるスタイルの多くは、設計で「不要なクラスを作らない」「不要な継承を作らない」ことに注目していますね。 Rubyスタイルガイドを読む: 総もくじ 前回: Rubyスタイルガイドを読む: クラスとモジュール(1)構造 次回: Rubyスタイルガイドを読む: クラスとモジュール(3)クラスメソッド、スコープ、エイリアスなど クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど 参照: bbatsov/ruby-style-guide 5-06【統一】クラス設計の階層はLiskovの置換原則に従う When designing class hierarchies make sure that they conform to the Liskov Substitution Principle. Liskovの置換原則に言及しています。 型のオブジェクト に関して真となる属性を とする。このとき が の派生型であれば、 型のオブジェクト について が真となる。 すなわち、リスコフとウィングが定式化した派生型の定義は置換可能性 (substitutability ) に基づいている。 が の派生型であれば、プログラム内で 型のオブジェクトが使われている箇所は全て 型のオブジェクトで置換可能であり、それによってプログラムの妥当性が損なわれることは無い。 Wikipedia: リスコフの置換原則より どう落とし込むか考えてしまいましたが、morimorihogeさんが「派生クラスはスーパークラスが持つインターフェース(メソッド)を受信可能でなければならない」とまとめてくれました。 参考: [オブジェクト指向設計原則]リスコフの置換原則(LSP)Add Star 参考: オブジェクト思考 – リスコフの置換原則 5-07【統一】クラスはできるだけSOLIDに設計すること Try to make your classes as SOLID as possible. この「SOLID」はオブジェクト指向における設計原則(design principle)を指します。5つの原則の頭文字をうまいこと設定しています。 以下は「SOLID Design Principles」を元にごく簡単にまとめたものです。この枠には到底収まりきれないので、いずれ別記事にしたいと思います。 S(単一責任原則) クラスは単一の機能についてのみ責任を持つようにすべし O(オープン・クローズ原則) クラスは自身への拡張に対しては寛容(open)にし、変更に対しては非寛容(close)にすべし L(リスコフの置換原則) 派生クラスはスーパークラスが持つインターフェース(メソッド)を受信できるようにすべし I(インターフェイス分離原則) ひとつの汎用インターフェイスで何もかもまかなうより、クライアント側に寄せたインターフェイスを多数作るべし D:(依存関係逆転原則) 上位のモジュールは下位のモジュールに依存してはならない 以下のリンク先でもしきりに注意されていますが、「あくまで原則は原則」なので振りかざすのは逆効果になりがちです。従わない者のお尻をペンペンするための原則ではなく、現実の設計やコーディングの見通しをよくして開発・改修を楽にするための原則、と考えることにします。 参考 Wikipedia_en: SOLID (object-oriented design) [オブジェクト指向設計原則]オブジェクト指向設計原則 オブジェクト指向の法則集 — SOLID以外にも多数の原則が紹介されています 5-08【統一】ドメインオブジェクトを表現するクラスには常に適切なto_sメソッドを実装すること Always supply a proper to_s method for classes that represent domain objects. ドメインオブジェクトはビジネスオブジェクトとも呼ばれ、Wikipedia: ビジネスオブジェクトによると「プログラムが表現しようとしている領域(ドメイン)での実体を抽象化したものである」と説明されています。 class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end def to_s # to_sを実装してあげよう “#{first_name} #{last_name}” end end b22c6d3の更新を反映しました。 参考 ドメインオブジェクトとは? データ中心指向とオブジェクト指向 5-09【統一】重要度の低いアクセサやミューテータはattr_*で定義する Use the attr family of functions to define trivial accessors or mutators. # 不可 class Person def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end def first_name @first_name end def last_name @last_name end end # 良好 class Person attr_reader :first_name, :last_name def initialize(first_name, last_name) @first_name = … Continue reading Rubyスタイルガイドを読む: クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど