このパターンはプログラミング言語に関係していません。
更新:実際の練習からの例を追加しました。
注目を集める画像:
状況を想像してみてください。すでに大きなプロジェクトが形成されており、急速な再設計の段階を過ぎています。 プロジェクトにはレイヤーがあり、すべてが技術的に有能に実装され(はい、これが起こります)、アーキテクチャにより現在の機能のサブセットを実装できます。 開発は、計画通りに行き過ぎず、過剰に行われません。
しかし、ある時点で、デザイナー/投資家/クリエイティブディレクターまたはアーティストの明るい目標の1つにアイデアまたは要件が生じます(必要に応じて下線を引きます)。 この考え方は、現在のアーキテクチャには適合しません。 それは必ずしも新しい機能としてのアイデアではないかもしれません。たとえば、ミドルウェアのサプライヤの1つのカスタム機能\モードのサポートであり、技術などの利点をもたらします。
この状況でデザイナー/建築家は何をしますか? 最適なコードは、記述されていないコードであるため、最も正しい解決策は、利用可能なすべての方法で新しい機能を拒否することです。 このようなコードは簡単に保守でき、最小限の数のバグが含まれています。 影響力のある方法は、権威による圧力からさまざまなトリックの使用まで、例えば、 自分がQuakeに勝つことを可能にするなど、さまざまです。
2番目の解決策は、状況が許せば、アーキテクチャを確認し、必要に応じて再設計するための正常な順序です。
評価と再設計の時間がなく、「昨日」に解決策が必要な場合、「技術的負債」を負う必要があります。 最悪のケースは、機能を複数のレイヤーにスローする必要があることです。
プロブロス機能:
そのような決定の否定的な結果は知られています。 上位層は下位層の詳細に依存するようになり、機能の転送などにのみ必要な中間サービスが表示されます。
プロブロによるアーキテクチャのポイ捨ての問題と、アーキテクチャ全体への悪影響を解決するために、このパターンも役立ちます。 このパターンの本質は、すべての負債を単一のサービスまたは一連のサービスにカプセル化することです。 このようなサービスは、システムのすべての技術的負債の正面になります。
転送のカプセル化:
このパターンはアーキテクチャの一部ではなく、一時的なソリューションをカプセル化するためにのみ必要であり、現在のアーキテクチャを破壊することなく評価と再設計のための時間を購入できることを理解することが重要です。
実世界の例
プロジェクトMMOゲーム。 コードベースは約3,000個のC#ファイルです。 クライアントはC#で記述されており、OGRE(C ++)がレンダリングに使用されました。
最下層の「レンダー」は、レンダーの実装であり、さまざまなエフェクト(アニメーションシーン、パーティクル)およびアニメーションをサポートするシーンオブジェクト(骨格、モーフ)の実装です。 何らかの形式での表示に関連するすべてのものがこのレイヤーに実装されました。
レンダリングファサードレイヤーは、レンダリングへのインターフェイス(ファサード)であり、C#で使用するためのすべてのネイティブコードラッパーが含まれていました。
シーングラフレイヤーは、オブジェクトとその相互作用をシミュレートする場所でした。
「ロジック」レイヤーは、オブジェクトをシミュレートし、シミュレーションオブジェクトにロジックをマップしました。
このフラグメントでは、これらのレイヤーにあった他のシステムは省略されています。たとえば、UIはありません(C ++のC#ラッパーも表します)。
グラフシーンレイヤーのオブジェクトは、位置と方向を含む最も単純なオブジェクトでした。 階層をサポートし、識別子を介して抽象的なアニメーションを管理しました(大まかに言うと、idで開始および停止します)。
創造性が再び高まった後、設計者はランタイムのロジックに応じてマテリアルの色を変更する必要がありました。 動機は次のとおりでした:「説明する時間がないので、材料の色を変えさせてください!」、しかし、ゲーム開発ではこれは一般的な習慣です(スマイリーフェイス)。
そのような機能を追加するには、マテリアルなどの特定のものを追加してオブジェクトのインターフェイスを変形し、すべてのレイヤーで転送する必要がありました。 さらに、すべてのオブジェクトが基本的にマテリアル、たとえば光源とカメラ、または合成アニメーションオブジェクト、たとえば小惑星帯などを持っているわけではありません。
考える時間、特に実験する時間が足りなかったため、この機能を独立したサービスとして一時的に配置することが決定されました。 この場合、オブジェクトのインターフェースも影響を受けませんでした。拡張メソッドの特定の実装は、グローバルコンテキストでのみです。
さらに、サービスのすべての段階およびすべてのチェーンで、サービスがシステムを破壊したり、障害の原因になったりしないように、あらゆる種類の妄想チェックが行われました。
時間が経つにつれて、非常にトリッキーなウィジェットやその他の問題のあるソリューションのためのさまざまな方法がこのサービスに登場し、姿を消しました。
そして、視覚化のすべての側面をサポートする本格的なアニメーショングラフの実装後、マテリアルの機能はサービスから削除されました。 そして、デザイナーはアニメーションの一部として材料の変更を示しました。
クライアントアーキテクチャの断片
最下層の「レンダー」は、レンダーの実装であり、さまざまなエフェクト(アニメーションシーン、パーティクル)およびアニメーションをサポートするシーンオブジェクト(骨格、モーフ)の実装です。 何らかの形式での表示に関連するすべてのものがこのレイヤーに実装されました。
レンダリングファサードレイヤーは、レンダリングへのインターフェイス(ファサード)であり、C#で使用するためのすべてのネイティブコードラッパーが含まれていました。
シーングラフレイヤーは、オブジェクトとその相互作用をシミュレートする場所でした。
「ロジック」レイヤーは、オブジェクトをシミュレートし、シミュレーションオブジェクトにロジックをマップしました。
このフラグメントでは、これらのレイヤーにあった他のシステムは省略されています。たとえば、UIはありません(C ++のC#ラッパーも表します)。
グラフシーンレイヤーのオブジェクトは、位置と方向を含む最も単純なオブジェクトでした。 階層をサポートし、識別子を介して抽象的なアニメーションを管理しました(大まかに言うと、idで開始および停止します)。
創造性が再び高まった後、設計者はランタイムのロジックに応じてマテリアルの色を変更する必要がありました。 動機は次のとおりでした:「説明する時間がないので、材料の色を変えさせてください!」、しかし、ゲーム開発ではこれは一般的な習慣です(スマイリーフェイス)。
そのような機能を追加するには、マテリアルなどの特定のものを追加してオブジェクトのインターフェイスを変形し、すべてのレイヤーで転送する必要がありました。 さらに、すべてのオブジェクトが基本的にマテリアル、たとえば光源とカメラ、または合成アニメーションオブジェクト、たとえば小惑星帯などを持っているわけではありません。
Probros機能(赤で表示)
考える時間、特に実験する時間が足りなかったため、この機能を独立したサービスとして一時的に配置することが決定されました。 この場合、オブジェクトのインターフェースも影響を受けませんでした。拡張メソッドの特定の実装は、グローバルコンテキストでのみです。
VIPサービスの実装
さらに、サービスのすべての段階およびすべてのチェーンで、サービスがシステムを破壊したり、障害の原因になったりしないように、あらゆる種類の妄想チェックが行われました。
時間が経つにつれて、非常にトリッキーなウィジェットやその他の問題のあるソリューションのためのさまざまな方法がこのサービスに登場し、姿を消しました。
そして、視覚化のすべての側面をサポートする本格的なアニメーショングラフの実装後、マテリアルの機能はサービスから削除されました。 そして、デザイナーはアニメーションの一部として材料の変更を示しました。
長所:
- 機能はすぐに利用可能です。
- 正しい決断をするための勝利の時間
- 技術的な負債はシステム全体に広がりません
- すべてのシステム負債への迅速なアクセス(アーキテクチャの問題を評価するため)
- 特定の問題の解決が遅れているため、あらゆる種類の問題の解決が可能です。
- 機能が不要になった場合の直接的な利益
短所:
- パターンはどこにも適用されません
ご理解いただきありがとうございます!