Tbpgr Blog

元エンジニア 人事 tbpgr(てぃーびー) のブログ

実装パターン | クラス

概要

クラスについて
(この書籍のベースはJavaの話)

詳細

クラス

クラスはデータとロジックの機能・役割を表す。
可能な限り意味をもたせたクラス作成を行うこと。

シンプルなスーパークラス

スーパークラスは核となる概念になるため、可能な限り「単語」で命名する。
命名のコツはメタファーの利用、同僚との相談、同僚への説明。

修飾的なサブクラス

サブクラスはより具体的な命名を行う。主に付加的な名称+規定クラス名の形式にする。
例外として特別な概念を表す場合はサブクラス自体の命名を簡潔な単語とする。

抽象インターフェース

コストがかかるため、必要となって初めて対応するか事前によく計画した箇所に関して適用すること。

インターフェース

インターフェースの用途は、利用者に目的の意図を明確に伝えるため。
また、実装と分離するために変更に強くなる。
命名方法は2種。
1つ目は通常のクラスのように命名する。この場合は、実装側にImplなどのサフィックスを付けることとなる。
2つ目はプリフィックスのIを付ける。これであれば簡潔な命名のまま実装クラス名との住み分けも可能である。

抽象クラス

インターフェースとの違いは実装を共有し、また一部の実装を強制することを伝えることができること。
また共通部あくまでデフォルトの実装であるためオーバーライド可能。

別バージョンのインターフェース

インターフェースの変更が困難なら別のインターフェースで拡張する。

バリューオブジェクト

状態が変化しないオブジェクト。基本的にコンストラクタでの初期化時に決まった値から変化しない。
副作用がないためテストが容易で、スレッドセーフである。
パフォーマンスが問題視されることもあるが、システムの中で真にパフォーマンスが問題となる箇所は
ごく一部であり、パフォーマンスよりも保守性を優先すべきである。
パフォーマンスは問題が出てから必要な箇所のみ対応する。

特化

プログラムの類似点、相似点を分かりやすくすることでプログラムは保守性があがる。

サブクラス

一部以外は処理が共通となる概念に適用。
非常に便利だが、3つの懸念事項がある。
1つ目は単一継承である点。
2つ目はスーパークラスを理解しないと継承クラスを利用できないため1クラスで実装するよりも
難易度が高くなる点。
3つ目はスーパークラスの変更のリスクが高くなる点。
よい親子クラスの作り方は、親のメソッド粒度を細かくすること。
粒度が荒いと子がオーバーライドせざるを得ない機会が増える。

実装クラス

多態的に実装することで、シンプルで拡張可能なロジックとなる。

内部クラス

処理の一部をパッケージ化したいが、新規クラスを作るほどでもない場合に利用。

インスタンス固有の振る舞い

インスタンスをの振る舞いを途中で変更すると、追跡困難になるため初期に設定すること。

条件分岐

条件分岐は増えるほどプログラムの信頼性が減少する。
サブクラス化、委譲によって対応する。

委譲

委譲により条件分岐を排除する。

プラガブルセレクタ

クラス分割するほどでもない規模だが、処理をDRYに保ちたい場合に
リフレクションで処理を切り替える方法。
欠点は難易度が上がることと、その参照が実際に利用されているかどうか動かしてみるまで
わからないこと。

匿名内部クラス

インスタンス固有の振る舞いを定義する方法。
通常、runメソッドだけからなるRunnnableインターフェースの実装時などに利用する。

ライブラリクラス

どのクラスにも属さないような汎用的な処理はstatic メソッドにして別クラスに抽出する。
しかし、ライブラリクラスはオブジェクト指向の利点を活かせないため出来るだけ控えること。