Yanonoblog!

こつこつと

ソフトウェア設計 - 低凝集 (アンチパターン)

はじめに

本記事では「良いコード 悪いコードで学ぶ設計入門」で学んだ内容と別途気になって調べた内容や知識も含めアウトプットしています。

書籍に記載されている内容を順序立ててまとめるというよりは、整理しておきたい周辺の知識と深ぼった内容を雑多に書いています。

低凝集 (アンチパターン)

ソフトウェアの設計において関連するデータやロジックどうしが分散し、バラバラになっている状態を指します。

低凝集の状態では、関連する要素がバラバラになっており、一つの機能や目的を果たすために複数の箇所で重複した実装が行われることが多くなります。

主な原因

データとそれを操作するロジックが分離して実装されている場合です。

たとえば、税込み計算のロジックが複数の箇所で独立して実装されている場合、そのロジックの存在を他のメンバーが気づかずに同様の計算を別の場所で行ってしまう可能性が高くなります。

データと計算ロジックが密に結びついていないため、処理の一貫性や保守性が低下し、バグや重複したコードの発生などの問題が生じることがあります。

弊害

重複コード

関連するコードどうしが離れていると、関連するものどうしの把握が困難になります。

既に実装されている機能やロジックが他の開発メンバーに認知されず、同様の機能が別々の場所で重複して実装される可能性が高まります。

修正漏れ

重複したコードが多く存在する場合、仕様変更や修正が必要な場合には、すべての重複コードを特定して変更する必要がありますが、すべての重複コードを把握しづらい状況から修正漏れが発生し、バグの原因となる可能性があります。

可読性の低下

関連するコードや処理が分散している場合、重複コードを含めて関連する要素を特定するために時間がかかります。

特に大規模なプロジェクトでは、複数のモジュールやコンポーネントが組み合わさって動作するため、コードの修正や機能の追加を行う際に、既存のコードの理解や変更箇所の特定がしづらいとさらに時間なかかるでしょう。

低凝集を解消する

低凝集を解消するためには、関連するデータと機能を結びつけることが重要です。

モジュールやクラスの設計を見直す

関連するデータと機能を同じモジュールやクラスにまとめることで、関連性を明確にし、凝集度を高めることができます。

データと計算ロジックを統一的なインターフェースで結びつける

データと計算ロジックを一つのクラスやモジュールで統一的に扱うことで、重複を避け、一貫性のある処理を実現します。

ドメイン駆動設計の原則を適用する

Domain-Driven Designの概念や要件に基づいたモデル化を行い、関連するデータと機能をドメインのコンテキストに結びつけることで、凝集度を高めます。

Railsにおける簡単な例

アンチパターン例 - クラス内に複数の責務が存在する場合

# 低凝集なコード
class User
  def create
    # ユーザーの作成処理
  end
  
  def update
    # ユーザーの更新処理
  end
  
  def delete
    # ユーザーの削除処理
  end
  
  def calculate_score
    # スコア計算の処理
  end
end
改善例 - クラスを責務ごとに分割する
# 凝集性の高いコード
class UserCreator
  def create
    # ユーザーの作成処理
  end
end

class UserUpdater
  def update
    # ユーザーの更新処理
  end
end

class UserDeleter
  def delete
    # ユーザーの削除処理
  end
end

class ScoreCalculator
  def calculate(user)
    # スコア計算の処理
  end
end

アンチパターン例 - メソッド内に複数の役割が混在している場合

# 低凝集なコード
class UsersController < ApplicationController
  def create
    # ユーザーの作成処理
    # ログの出力
    # メールの送信
    # ユーザーのステータス更新
  end
end
改善例 - メソッドを役割ごとに分割する
class UsersController < ApplicationController
  def create
    create_user
    log_output
    send_email
    update_user_status
  end
  
  private
  
  def create_user
    # ユーザーの作成処理
  end
  
  def log_output
    # ログの出力
  end
  
  def send_email
    # メールの送信
  end
  
  def update_user_status
    # ユーザーのステータス更新
  end
end

参考

続く…

コメント

本記事の内容は以上になります!

書籍の続きのアウトプットも随時更新したいと思います。


プログラミングスクールのご紹介 (卒業生より)

お世話になったプログラミングスクールであるRUNTEQです♪

https://runteq.jp/r/ohtFwbjW

こちらのリンクを経由すると1万円引きになります。

RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

https://twitter.com/outputky