パッケージ設計6つの原則~ポイントは関連性/依存性/抽象度

package-principles

プログラムも規模が大きくなると管理が大変です。クラスや関数をある程度のまとまりとして分けたほうが、管理しやすくなります。このまとまりがパッケージです。

共通的なクラスをまとめてパッケージにする、程度はなんとなく分かります。

実際にはどのような指針に従うべきなのでしょうか。

目次

パッケージ設計の考え方

パッケージ設計とはつまり、どのクラスをまとめ、どのクラスを分離するか、を考えることです。

ポイントは3つあります。

パッケージ設計のポイント
  • 関連性 関連性の強いクラスをまとめる
  • 依存性 依存方向が同じクラスをまとめる
  • 抽象度 抽象度が同程度のクラスをまとめる

うまくまとめられたパッケージは、あとで再利用がしやすくなります。

再利用・リリース等価の原則

再利用・リリース等価の原則

REP:Reuse-Release Equivalency Principle

再利用の単位とリリースの単位は等価になる

パッケージは段階的にバージョンアップします。Ver1.0、1.1、2.0…のように。理由は、パッケージ内クラスの不具合修正、新たな機能の追加、などあるでしょう。

パッケージとしてリリースするときは、そのパッケージのクラス全てが利用可能でないといけません。中途半端な状態でリリースしてはいけない、ということです。

あるパッケージに、クラスAとクラスBがあるとします。

パッケージVer1.0に不具合があり、関連するクラスAとクラスBを修正した、としましょう。

このとき、クラスAを修正してVer1.1リリース、クラスBを修正してVer1.2リリース、というのはNG。

AとBを両方修正した完璧なバージョンでリリースすべきです。

パッケージをバージョン管理システムで管理しているなら、問題は起こりにくいでしょう。

共通再利用の原則

共通再利用の原則

CRP:Common Reuse Principle

パッケージに含まれるクラスは、すべて一緒に再利用される。

パッケージを使うとき、たいていは1つのクラスだけ使うわけではありません。複数のクラスが関連します。例えばメソッドの引数、戻り値、に別のクラスを使ったりします。

こういったクラス群は、一緒に使われる傾向にあります。互いに強い関連性を持つクラスは同じパッケージに含めるのがよいでしょう。

クラスの一部だけパッケージの外に出したりすると、パッケージの整合性が取りにくくなります。

閉鎖性共通の原則

閉鎖性共通の原則

CCP:Common Closure Principle

パッケージに含まれるクラスは、みな同じ種類の変更に対して閉じているべき。

ソフトウェアの修正は必ず起こります。パッケージ内のクラスも同様です。

でも修正がパッケージで完結すれば、他には影響を与えません。いっしょに修正しそうなクラスなら、同じパッケージに入れたほうがいいでしょう。

逆に言えば、異なる理由で修正されるクラスは、同じパッケージに入れるべきではないということです。これはパッケージ設計における単一責任原則です。

よくあるのが、共通的なクラスをなんでも詰め合わせたCommonパッケージです。すべてのクラスがCommonパッケージを参照してしまい、影響範囲がはたしてどこまで及ぶか分からなくなります。

パッケージを考えるとき、実際には「再利用」より「保守性」を重視します。保守時の修正やテストの影響度から、パッケージの変更理由は一つであるべきなのです。

非循環依存関係の原則

非循環依存関係の原則

ADP:Acyclic Dependencies Principle

パッケージ依存グラフに循環を持ち込んではならない。

循環依存とは、パッケージAを使うにはパッケージBが必要、パッケージBを使うにはパッケージAが必要、と依存関係がぐるぐる回ってしまうことです。

クラス単体なら分かりやすいのです。しかしパッケージになると、めぐりめぐって循環している場合があり、気づきにくいのです。

こうなると、パッケージAとBは独立して使えず、実質ひとつの大きなパッケージになってしまいます。

パッケージ設計をするときには、必ず片方向の依存関係となるようにしましょう。

安定依存の原則

安定依存の原則

SDP:Stable Dependencies Principle

安定する方向に依存せよ。

パッケージAとパッケージBに、依存関係があり、

  • パッケージA:安定(変更されにくい)
  • パッケージB:不安定(変更されやすい)

という場合、不安定なBパッケージが、安定しているAパッケージに依存されてはいけません。

「安定している」とは、変更しづらいという意味。変更しづらいというのは「他のクラスやパッケージから依存されている」(=責任を負っている)パッケージです。

パッケージの依存関係は、より安定しているパッケージへと向かうべきです。

安定度・抽象度等価の原則

安定度・抽象度等価の原則

SAP:Stable Abstractions Principle

パッケージの抽象度と安定度は同程度でなければならない。

基本的に、

  • 安定度の高いパッケージは、抽象度が高い
  • 不安定なパッケージは、具体的である

という関係があります。安定したパッケージに出来るだけ変更を発生させないためには、それは抽象的である必要があります。

依存関係は安定する方向へ向かうべき。そして、安定するということは抽象化されているということを意味します。

いろいろなところから参照されているパッケージが、抽象度合いが低い場合、いろいろな変更が多くなってしまい、安定度の低いシステムとなってしまう。安定したパッケージは抽象度を高く、不安定なパッケージは具体的にします。

パッケージの方針として、

  • 安定したパッケージは抽象クラス中心で構成する。柔軟さや設計の自由さを残す。
  • 不安定なパッケージは具象クラス中心で構成する。具体的なコードを変更可能とする。

安定依存原則とこの原則は、パッケージにおける依存関係逆転原則といえます。

まとめ

パッケージ設計を考えだすということは、プログラムもある程度大規模になっているところでしょう。

パッケージ構成を考えるにあたり、世の中にあるライブラリやフレームワークをみてみるのもよいでしょう。各々コンセプトは違いますが、永年の英知が詰まったパッケージ構成となっていて参考になります。

パッケージ分割を誤ると、保守性に重大な支障が発生します。慎重に考えましょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次