Rubyで設計を学ぶ|オープンクローズドの原則を解説

今回は設計を学ぶために、Rubyでオープンクローズドの原則を解説していきます。
なお、以下の書籍を参考にしております。
オープンクローズドの原則とは?
オブジェクト指向を用いた設計原則で用いられます。
簡単にいうと、クラスやモジュールなどは
拡張に対して、オープンであり、
修正に対してはクローズにすべき
という原則です。
拡張にオープンである事のメリット
インターフェースや抽象クラスなどを利用して、拡張にオープンにする事で、
既存機能への影響が発生しにくく、メンテナンスも楽になります。
修正に対してはクローズである事のメリット
修正作業は、既に稼働しているコードを修正しますので、 既に稼働しているコードに影響が発生します。
そうなると、既存コードの内容を追い、ビジネスロジックの抜け漏れがないかを確認していかなければなりませんので、修正に対してクローズであるべき という原則が理解できます。
※もちろんバグ修正などは、問題ないでしょう。
関連記事
サンプルコードの処理内容
飲食店で
1:テイクアウト
2:配達
3:店舗注文
が発生した場合に別々の処理を行う事を想定したコード
なおサンプルコードでは、エラーキャッチは考えないのと 別途説明が必要なので、クラス継承とStruct(構造体クラス) は利用しません。
詳細な動作よりは、各クラスとメソッドの内容に注目してください
リファクタリング前のコード
リファクタリング前のコードは以下になります。
def order(order_types) order_types.each do |order_type| case order_type when "take_out" # テイクアウト専門処理 when "delivery" # 配達専門処理 else #それ以外の処理 end end end order_types = ["take_out", "delivery", "store_order"] order(order_types)
上記で既にcase文が複数発生しています。
例えば、予約注文が発生した場合に、whenに新しい条件を追加する事になります。
簡単なロジックでも、注文内容によって、どんどんcase文の選択肢が増えていきます。
これでは、クラスも肥大化していきますし、複雑な処理が発生すると、既存のコードに影響が発生するリスクが増大します。
そのため、このクラスをオープンクローズドの原則に当てはめて改修します。
リファクタリング後のコード
リファクタリング後のコードは以下です。
class Order def execution_order(order_types) order_types.each do |order_type| order_type.execution_order(self) end end end class TakeOut def execution_order(order) #テイクアウト用の処理 puts order end end class Delivery def execution_order(order) #配達用の処理 puts order end end class StoreOrder def execution_order(order) #店舗用の処理 puts order end end order_types = [TakeOut.new, Delivery.new] Order.new.execution_order(order_types)
こちらで、
1:各処理を呼び出すOrderクラス
2:具体的な処理はTakeOutクラスなど各クラスで行う
3:各処理を呼び出すために、ダックタイピング を利用する
という事を行っています。
こうすることにより、
新たな要件が発生すると、新規クラスを作成したり、既存のクラスを改修していくなどをすればよく、既存のコードを修正する必要はありません。
実際の具体的な動作は、サンプルコードを動作させて確認してみてください。
以上になります。
関連記事
paizaのスキルチェックの難易度|各ランクの特徴・ランクアップのコツ
初心者・独学者向け|Rubyのハッシュ入門とよく使うメソッド
初心者・独学者向け|Rubyの配列処理の入門とよく使うメソッド
初心者・独学者向け|Rubyのinitializeメソッドとは