Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

【保存版】「凝集度」と「結合度」でRubyコードはここまで変わる!基本のOOP原則を実例で解説

オブジェクト指向設計において最も重要な原則のひとつが、凝集度(Cohesion)結合度(Coupling)です。この2つの概念を理解すると、コードベース内のすべてのクラスを特定のレンズを通して評価できるようになり、クラス設計の堅牢さや改善すべき箇所が明確に見えてきます。

凝集度と結合度とは何か?

凝集度とは、クラス内にあるメソッド同士の関係性を表す概念です。各メソッドが同じインスタンス変数や引数を使い、共通の目的に向かって協力し合っているか?それとも、メソッドごとに役割がバラバラで、互いに無関係に感じられるでしょうか?

結合度とは、あるクラスが他のクラスにどれほど依存しているか、システムの他の部分とどれほど密接に「結びついているか」、そしてそのクラスを単体で再利用できるかどうかを示します。

ベストな結果を得るためには、高い凝集度(high cohesion)低い結合度(low coupling)を目指すことが大切です。

凝集度の具体例

ピザに例えるなら、凝集度が低い状態はトッピングがちぐはぐに散らばったピザのようなもので、凝集度が高い状態はすべての材料が適切な場所に収まったピザのようなものです。

感覚的にはイメージできても、実際に測定するのは難しいものです。クラスの凝集度を数値で教えてくれるツールは存在しません。そこで分かりやすく理解できるよう、典型的なコード例を見てみましょう。

class Library
  def lend_book
  end

  def return_book
  end

  def make_coffee
  end
end

この例では make_coffee が際立って浮いていますね。たとえ図書館にカフェテリアが併設されていたとしても、Library クラスがコーヒーを淹れるのは不自然です。

カフェテリア側は、所蔵書籍の情報や貸出手順などを知る必要はありません。逆に図書館側も、コーヒーの残量や淹れ方を知る必要はないのです。これこそが「低い凝集度」の典型例といえます。

もちろん、実際のコードではここまで明白ではないことも多いでしょう。その場合は、メソッド名だけで判断せず、注意深く観察する必要があります。

  • これらのメソッドは実際に何をしているのか?
  • どんなデータを扱っているのか?
  • どのオブジェクトと連携しているのか?

こうした問いを自問することで、クラスの凝集度のおおよその水準を掴むことができます。

では、低い凝集度はどうやって改善すればいいのでしょうか?

答えはシンプルです。そのクラスに属さないメソッドを、別のクラス(多くの場合は新規クラス)へ抽出します。上記の例であれば、make_coffeeCafeteria クラスなどに移動するのが適切です。

結合度の具体例

次に結合度を見てみましょう。以下が問題のあるコード例です

class ShoppingCart
  attr_accessor :items

  def initialize
    @items = []
  end
end

class Order
  def process_order(cart)
    cart.items.map(&:price).inject(:+)
  end
end

この例では、Order クラスが ShoppingCart クラスに強く結合しています。理由は、items 変数の内部構造を知りすぎており、さらにそれを使って計算まで行っているからです。

もし ShoppingCartitems の実装を変更したら、Order 側も修正せざるを得ません。これは好ましい状態とは言えませんね。

次のように修正できます

class ShoppingCart
  attr_accessor :items

  def initialize
    @items = []
  end

  def calculate_total
    items.map(&:price).inject(:+)
  end
end

class Order
  def process_order(cart)
    cart.calculate_total
  end
end

計算の詳細を本来あるべき場所(ShoppingCart)へ移動することで、結合度を下げることができました。これにより、ShoppingCart の内部実装を自由に変更しても、Order 側への影響を最小限に抑えられます。

この考え方を日常的なモノに例えるなら、電池が本体に固定されて取り外せない携帯電話が高い結合度、電池を交換できる携帯電話が低い結合度に相当します。

ただし、ある程度の結合は必要である点に注意してください。電池がなければ携帯電話は動きませんし、顧客への請求額を知らなければ Order クラスは機能しないのです。重要なのは「結合をゼロにすること」ではなく、「不要な依存を減らすこと」です。

まとめ

今回は、OOPにおける2つの重要な原則である「凝集度」と「結合度」について学びました。この2つの概念は、クラス内のメソッドがどれだけうまく連携できているか、そして自分のクラスがシステムの他の部分からどれだけ独立しているかを把握するための強力な指針となります。

ぜひ今すぐ、自分のプロジェクトに適用してみてください。エディタを開いていくつかのクラスを眺めてみましょう。今日学んだことを使えば、どこをどう改善できるでしょうか?

最後までお読みいただきありがとうございました!ぜひ記事をシェアして、まだの方はニュースレターの購読もお願いします🙂

  1. iPadとiPhoneでQRコードをスキャンする方法|アプリ不要で簡単に読み取る手順

    2018年に登場したiOS 12には、iPadやiPhoneのユーザー体験を大きく向上させる便利な機能が多数追加されました。そのひとつが「QRコードのスキャン」機能です。この機能を使えば、チケットやクーポン、商品の成分表示などの情報を素早く取得でき、買い物の前に商品について数秒で調べることも可能になります。さらに、スマートフォンのカメラだけで直感的にQRコードを読み取れるため、面倒な操作も一切必要ありません。この記事では、iPadとiPhoneでQRコードをスキャンする具体的な方法を詳しく解説します。QRコードとは?QRコード(Quick Responseコード)とは、白と黒の四角形が格子状に

  2. 確認コードを使ってGmailのパスワードをリセットする方法【初心者向け完全ガイド】

    Gmailのパスワードをリセットしたい理由は人それぞれです。セキュリティ攻撃の疑いから、プライバシーへの意識の高まりまで、さまざまなケースが考えられます。特別な理由がなくても、アカウントの安全を守るために数ヶ月ごとにパスワードを変更するのは良い習慣です。また、パスワードを忘れてしまった場合にも再設定が必要になります。なお、パスワードの「変更」と「再設定(復元)」では手順が少し異なる点に注意しましょう。この記事では、Gmailのパスワードをリセットする具体的な手順をステップごとに詳しく解説します。 Gmailアカウントを安全に保つためのポイント セキュリティ専門家によると、パスワードは3ヶ月ご