クラス設計

参考文献

  • (1) Software Design 2025年5月号 もう一度学びなおすクラス設計の鉄則 増田亨 (著)
  • (2) 単体テストの考え方 / 使い方 Vladimir Khorikov (著)、 須田智之 (翻訳)
  • (3) 現場で役立つシステム設計の原則 増田亨(著)
  • (4) Clean Architecture Rovert C Martin Robert C.Martin (著), 角 征典 (翻訳), 高木 正弘 (翻訳)
  • (5) ドメイン駆動設計入門 成瀬 允宣(著)
  • (6) アジャイルソフトウェア開発の奥義 ロバート・C・マーチン(著)、 瀬谷 啓介 (翻訳)

クラスとは

データとロジックを1つのプログラミング単位にまとめる仕組み。

良いクラス設計

良いクラス設計はモジュール1性が高く次の特徴を持つ。

  • クラスの役割が明確
  • クラスの依存関係が明確
  • クラスの変更が容易

クラスはデータとロジックを1つのプログラミング単位にまとめるしくみです。データをインスタンス変数として持ち、そのインスタンス変数を使った判断/加工/計算のロジックをメソッドに書くのが、クラスの本来の使い方です。

出典:(3) p077

データとロジックを一体にして業務ロジックを整理する

クラスにデータをそのデータを使う判断/加工/計算のロジックを一緒に書いておけば、コードの重複をなくせます。そのクラスを使う側のクラスに同じロジックを書く必要がなくなるからです。

クラス設計で大切なことは、使う側のクラスのコードがシンプルになるように設計することです。

出典:(3) p089

クラスの役割が明確

クラスの役割を明確する代表的な方法として以下がある。

  • 関心の分離
  • カプセル化( public / private などのアクセス修飾子)
  • 単一責任の原則

クラスの依存関係が明確

依存とは

クラス A がクラス B を利用(呼び出し)している状態。

classDiagram
direction LR
    classA --> classB

依存の特徴

  • 依存される側は依存する側を知らない
  • 依存される側は依存する側の変更に影響されない
  • 依存される側の変更は依存する側に影響する
  • 依存される側を先に設計・実装する

依存するクラスは柔軟性が高く、依存されるクラスは安定性が高い。

graph LR
    A(A flexible) --> B(B stability)

問題のある依存

  • 多すぎる依存(関心の分離ができていない)
  • 不安定な依存関係
  • 循環した依存

設計の順序

以下の順番で設計する。

  1. 依存されるクラスを設計
  2. 依存するクラスは依存されるクラスがある状態で設計

依存のコントロール

依存される側を変更した場合、依存する側に影響が及ぶ。 影響を最小化するには依存関係をコントロールする必要があり、その代表例が依存関係逆転の原則( DIP )である。

DIPを実現する方法のひとつにDI(Dependency Injection)がある。

依存関係逆転の原則( DIP: Dependency Inversion Principle )

上位レベルの方針の実装コードは、下位レベルの詳細の実装コードに依存すべきではなく、逆に詳細側が方針に依存すべきであるという原則。

出典 (4) p79

具象実装を変更してもインターフェースの変更が必要になるkとはあまりない。つまりインターフェース実装よりも変化しにくいということだ。 次ぐれたソフトウェア設計者やアーキテクトは、インターフェースの変動性をできるかだけ抑えようとする。新しい機能を実装するときにも、できる限りインターフェースの変更なしで済ませられるようにする。これはソフトウェア設計の基本中の基本だ。

classDiagram
direction LR
    class BInterface
    <<interface>> BInterface
    classA --> BInterface
    BInterface <|-- classB

クラスの変更が容易

クラスの変更を容易にする方法論として、SOLID原則が広く知られている。
中でも、オープン・クローズドの原則( OCP )と依存関係逆転の原則( DIP )が特に重要である。

OCP:オープン・クローズドの原則

ソフトウェアの構成要素は拡張に対しては開いていて、修正に対しては取っじていなければならない。

出典:(6)

つまり、新しい機能を追加できるが、その追加によって既存のコード(クラス)を変更しなくても済む構造を指す。

  1. モジュールとは何らかの基準で分類・命名されたソフトウェアの単位。