#はじめに#
オブジェクト指向設計の目的の一つとして再利用性が挙げられますが、実際のところなかなか上手くいかないですよね。
上手くいかない原因は色々あるかと思いますが、本記事では名前空間設計をテーマに、再利用性を高めるための方法について考えていきたいと思います。
#私はWindowsに囲われた悲しきSIerなので、用語は.Net Frameworkに準拠します。ご了承ください。
#本記事の内容は私個人の経験則です。有用な文献等ありましたら、コメントでご指摘頂けると助かります。
#名前空間とは#
名前空間とはクラスなどのプログラム部品を整理、分類するものです。
NameSpace、パッケージ、スキーマなど色々な呼び方があります。
フォルダでソースコードファイルを物理的に分類することとは違い、空間を分けることで、本来はブログラム内に共存できない同じ名前のクラスが共存できるようになります。
#名前空間設計のガイドラインってあるの?#
色々ググってみたのですが、コレといって設計のガイドラインは見当たりませんでした。
名前の付け方についてはMicrosoftが下記のガイドラインを掲げています。
名前空間の名前|Microsoft Docs
実態としては、会社ごとのコーディング規約で定義されるか、または設計者 or 開発者のセンスに任されているというところかと思います。
#再利用を困難にする名前空間設計#
名前空間設計でよく見かけるのが、クラスの種類ごとに分ける形です。
例えば、Interfaceクラス、UIクラス、Domainクラスのような塊で名前空間を付ける形。
あるいは、MVCモデルでViewクラス、Controlerクラス、Modelクラスの塊で名前空間を付ける形。
これらの形は再利用性が悪いので、避けたほうがいいと考えています。
下記のケースで考えてみましょう。
ソフト内に2つの機能A、Bがあり、それぞれのMVC要素ごとに名前空間を付けている、とします。
ここから機能Aを再利用するため、ライブラリとして分離したくなったとします。
必要なのはViewAクラス、ControllerAクラス、ModelAクラスですが、それぞれ名前空間内で機能Bとくっついているため、分離できなくなっています。
もちろん内部設計を丁寧に追って機能Aと機能Bに依存関係が無いことを確認すれば分離可能ですが、機能が多ければ確認も大変でコストのかかる作業になってしまいます。
再利用はなによりもコスト削減が目的なので、名前空間単位で概観して分離可能と分かるようになっているべきです。
#再利用のための名前空間設計#
ではどのような名前空間設計が良いのか?
(すでに多くの人が辿り着いているでしょうが)機能の塊で名前空間を付ける形が良いと考えています。
先ほどのケースを機能ごとの名前空間に変えてみました。
機能Aと機能Bに依存関係が無く、分離可能だと一目で分かりますね。
クラスにAやBといった修飾子を付ける必要もないので、読みやすくもなっています。
#再利用の敵#
さて、名前空間を機能ごとに分けたとしても、再利用には別の敵が立ちはだかります。
###グローバル変数###
悪名高きグローバル変数です。ちなみに、グローバル変数と同じ位置づけのSingletonクラスも同様です。
再利用したクラスがグローバル変数を参照していた場合、再利用先のソフトでわざわざグローバル変数を用意してあげなければならない、なんてことになってしまいます。
また、グローバル変数が嫌われる最大の理由は、どこで誰が状態を変更したか分かりづらいことにあります。
先ほどの例で機能Aと機能Bが同じグローバル変数を参照していたら、どうなるでしょう?
もしかしたら、機能Bがグローバル変数に何かを設定しないと機能Aが正しく動かないかもしれません。
そんなリスクを回避するためにも、グローバル変数は敵として排除しておきましょう。
###神クラス###
無計画に機能が追加され、なんでも出来るように膨張してしまったクラスを神クラスと呼びます。
多機能である代わりに、多くのデータを設定しないと動かないという特徴があります。
再利用したクラスが神クラスを参照していた場合、再利用クラス自身には必要のないデータを、神クラスのためにわざわざ設定してあげる、なんてことになります。
これは無駄ですね。役に立つはずの再利用クラスが、逆に再利用先に迷惑をかけてしまいます。
神クラスは排除し、名前空間では必要最小限のデータのみ持つようにしましょう。
#パッケージ図を描こう#
※名前空間図よりパッケージ図の方が一般的なので、ここだけパッケージと表記します。
パッケージ図を描くことで、システムの全体像が見通しやすくなり、依存関係が一目で分かるようになります。
勢いで設計していると見落としがちなパッケージ間の相互依存や、責務の偏りなどにも気づくことができます。
また、再利用のみならず、長期的な保守性、拡張性の向上にも役立ちます。
#まとめ#
・名前空間は機能ごとに分割することで再利用しやすくなる
・グローバル変数、神クラスは再利用の敵、排除すべし
「クラス設計は勘とセンスやで!」という方も、ちょっと立ち止まって、名前空間設計を意識してみては如何でしょうか?
お読み頂き、ありがとうございました!