オブジェクト指向プログラミングでは、各クラス/オブジェクト/インスタンスは明確に定義された目的を持つべきであると一般的に言われています。たとえば、ウィンドウツールキットにはWindow
クラス、MinecraftのようなゲームにはChunkLoader
クラス、Matrix<>
線形代数ライブラリのクラス(テンプレート)。これらの各ケースで、クラスには特定のジョブがあります。これらの例では、ジョブはそれぞれ、基盤となるウィンドウAPIを処理し、有用な関数を公開し、チャンクをロードおよびアンロードし、有用な操作でマトリックスを表します。
このガイドライン(各クラスの単一の目的)は多くの場合良いアドバイスですが、プログラムの接着剤の部分ではフラットに見えるようです。つまり、必要に応じて、チャンクローダー、行列、ウィンドウクラスを呼び出す必要があります。これは、それらの間でデータを往復させたり、それらの間の適切なポリモーフィックインターフェイスを使用して設定したり、前述の部分(ChunkLoader
など)を組み合わせて全体を構成する他のホストにすることができます。たとえば、Minecraftのようなゲームでは、メインループを処理し、必要に応じてより明確な目的で他のクラスを呼び出す必要があります。
私がプログラムに取り組んでいる間、私の最初の(そしてこれまでのところ唯一の)アイデアは、プログラムのより広い領域を抽象化し、それらの内部のより抽象的でないクラスを扱うクラスを作成することです。ただし、これは名前などに関係なく、マネージャクラスの形式をとる傾向があります。たとえば、ビデオゲームには、世界の一般的な部分ごとにデータメンバー(つまり、世界自体をレンダリングするメンバー、他のプレーヤー用、およびGUI用のメンバー)があるRenderingManager
クラスがある場合があります。 )。次に、その内部で、GUIのさまざまな部分(インベントリ、ヘルス、一時停止画面など)の独自のメンバーを持つGuiManager
クラス。
ただし、この再帰的なマネージャー構造にはいくつかの問題があります。
プログラムの大規模な組織化、および/またはより基本的なOOPパーツを接着するためのより良いテクニックはありますか?ある場合、それは何ですか?そうでない場合、どのようにして前述の問題?
マネージャークラスは間違った抽象化から生まれるので、それらに基づくソリューションはうまく適合せず、特にOOの概念で)あらゆる種類の問題を引き起こします。
今週私が遭遇した一例を挙げさせてください。 Androidアプリケーションで「サブスクリプション」処理を記述していました。今では「通常」、SubscriptionManager
が表示され、Subscription
が表示されます。これには、有料かどうかに関係なく、おそらく製品IDが含まれます。それは、サブスクリプションが何であるかを一般的に抽象化したものです(一部は主張するでしょう)。
しかし、私が書いたのは、単一のメソッドContent retrieveContent()
を含む(おおまかに)単一のSubscription
クラスだけでした。
「サブスクリプション」とは基本的にanyアプリケーションに一般化する代わりに、myアプリケーションでのサブスクリプションである独自のSubscription
を作成しました。私だけのために、すべてのアプリケーションのサブスクリプション管理を解決する必要はありませんでした。これは、ビジネスコンセプトがmySubscription
の一部である可能性があることも意味します。そして私のドメインでは、サブスクリプションの唯一の目的はいくつかのコンテンツにアクセスすることです。
これは実際にはすべてのオブジェクトに当てはまります。 (アプリケーション内の)すべてのオブジェクトには、ある程度のビジネスロジックが含まれている必要があります。他のすべてのオブジェクト(String
、Matrix
、Window
など)は、アプリケーションとはまったく関係なく、できればライブラリから取得する必要があります。
最後に、一緒に「接着」する必要のあるものはありません。むしろ、物事は互いに自然に含まれるか、ビジネスロジックのラインに沿って互いに参照します(Subscription
はContent
を取得しますが、代わりにContentManager.retriveByProductId()
またはいくつかのような)。
注意:ほとんどのプロジェクト(過去20年間に見たもの)は「マネージャー」を実行するだけであり、ほとんどが手続き型の分解で満足しているので、OOとインラインで何かをしようとしている潮流に逆らって泳いでいるでしょう。