『Software Design 5月号』の第2特集「クラス設計の鉄則」を寄稿しました。 gihyo.jp
第2特集の概要と、今回はとりあげなかった、SOLID、GoFデザインパターン、凝集度と結合度について、私がどう捉えているかを説明します。
概要
第2特集のクラス設計の鉄則は3章で構成されています。概要は次の通りです。
第1章:クラス設計再入門
モジュール性・関心の分離・依存関係を意識する
第2章:迷わないクラス設計の指針
アプリケーション開発の実践例から考える現代的な設計方針
第3章:設計の落とし穴対策
コードから問題を検知する着眼点と改善方法
第1章:クラス設計再入門
この章は、クラス設計の基礎として、ソフトウェア設計の三つの視点を紹介しています。
ソフトウェアシステム構築の基本課題として「複雑さ」と「変更容易性」に焦点を合わせ、二つの課題に取り組むための考え方として、「モジュール性」「関心の分離」「依存関係」というソフトウェア設計の三つの視点をクラス設計と関連づけながら説明しています。
モジュール性が低い例として大きな泥団子を取り上げ、モジュール分割のアプローチとして、手続き、関数、クラスの三つを比較しながら、クラス設計の考え方の特徴を説明しました。
関心の分離を意識したクラス設計として、入出力と計算判断の分離の重要性を強調しました。またアプリケーション独自のデータ型としてクラスを設計する効果、クラスの可視性をうまく設計して詳細を見えなくすることの効果をとりあげました。
依存関係については、コードの重複という暗黙の依存関係の問題とその改善策としてのクラス設計を説明しました。そして、クラスを使って暗黙の依存関係を明示的にすることで、より適切な依存関係に改善する道筋をとりあげました。
第2章:迷わないクラス設計の指針
この章では、第1章で説明したモジュール性、関心の分離、依存関係の三つの視点でのクラス設計の具体例として、アプリケーションを構成するクラスを次のカテゴリーに分類して、それぞれの設計指針を説明しています。
- 計算判断クラス
- アプリケーションサービスクラス
- プレゼンテーションクラス
- データソースクラス
また、現代的なクラス設計の指針として、以下を取り上げました。
- 可変より不変を選ぶ
- エンティティより値を選ぶ
- 継承よりコンポジションを選ぶ
第3章:設計の落とし穴対策
この章では、設計がうまくいっていないことを、ソースコードから検知し、それを改善する方法について説明しました。
ケントベック氏の『Tidy First?』とマーチンファウラー氏の『リファクタリング(第1版)』のエッセンスのような内容です。
取り上げた主な内容は、以下の通りです。
- 乱雑になったコードを整頓する
- 長いメソッドを改善する
- 大きなクラスを改善する
- データだけのクラス、ロジックだけのクラスを改善する
記事で取り上げなかった設計の考え方
クラス設計の考え方としては、以下の内容を参考にしている方も多いと思います。
今回の「クラス設計の鉄則」の執筆にあたり、これらの内容に触れることも検討しましたが、最終的には、まったく触れませんでした。
その理由について、簡単に補足しておきます。
まず、この三つについてさまざまな情報が出回っているので、この記事で改めて取り上げる価値はあまりないように感じたからです。
また、さまざまな情報が出回っているわりには、クラス設計に悩んでいる人が多いという状況を考えると、SOLID、GoFデザインパターン、凝集度と結合度の説明は、クラス設計の初学者から中級者にとっては、あまり役に立っていないのではないか、と考えました。
ですので、この第2特集では、より基本的で一般的な設計視点である「モジュール性」「関心の分離」「依存関係」から始めて、実践的なクラス設計の考え方として、アプリケーションを構成するクラスの分類とそれぞれの設計の要点を説明し、具体的な設計のやり方として、ソースコードに現れる不適切な設計を検知し改善するための技法を説明しました。
私は、SOLID、GoFデザインバターン、凝集度と結合度の三つは、この特集で説明したような内容を一通り習得できたレベルのエンジニアがさらにレベルアップするために利用できる内容と位置付けています。
初学者向けには、あまり適切ではないと私が感じている点を簡単にまとめておきます。
SOLID
設計の視点、粒度、適用できる状況などが、5つの原則でばらばらな点が初学者向けではないと感じています。
例えば、S: Single Responsibility Principle(単一責任の原則)は、一般的でどのクラス設計でも共通して使える考え方です。
それに対して、L: Liskov Substitution Principle(リスコフの置換原則)とD: Dependency Inversion Principle(依存性逆転の原則)の二つの原則は、かなり特殊な状況に限定された設計原則です。アプリケーション開発で、この原則を意識すべき状況は限定されます。
また、O: Open/Closed Principle(オープン/クローズドの原則)とI: Interface Segregation Principle(インターフェース分離の原則)の二つの原則は、抽象度が高く、具体的にどういう状況で、どういう設計をすることが適切かを判断する指針としては、初学者には理解が難しすぎるように思います。
また、5つの原則は、排他的網羅を意識した分類体系のようなものではない点も、上級者には参考になっても、初学者向けの指針としては適切ではないように思います。
GoFデザインパターン
これは、かなり上級者向けの内容だと思っています。扱っている設計課題とその解決策は、初学者が実際の業務で参考にするような内容ではないと思います。
また、GoFデザインパターンが提示された1990年代であれば、これらのパターンをアプリケーション開発者が習得して利用する機会もそれなりにありました。しかし、最近では、プログラミング言語、フレームワーク、ライブラリなどに、さまざまなデザインパターンが取り込まれています。その結果、アプリケーション開発者がデザインパターンを直接意識する機会は少なくなったと思います。
フレームワークやライブラリを理解し適切に使うために、GoFデザインパターンの知識が役に立つことはありますが、初学者がクラス設計を学ぶための知識としては、優先度の高い知識ではないように思います。
凝集度と結合度
凝集度と結合度は、ソフトウェア設計の考え方として、いまでも学ぶ価値は大きいと思います。
しかし、1970年代の議論をそのまま持ってきたような説明では、現代的なクラス設計の指針としては、役に立たないように思います。 またクラス設計という文脈では、1970年代の議論は、クラスというモジュール化の手段が一般的になる前の議論のため、そのままでは初学者向けのクラス設計の指針として扱うのは、かなり無理があるように思います。



















