3

私の C++ アプリケーションの大部分は、クラスを使用してデータ モデルを記述します。たとえば、ClassType (プレーンな C++ でリフレクションを実際にエミュレートします) などです。

アプリケーションに新しいモジュールを追加したいのですが、これらの ClassType を使用する必要がありますが、新しいモジュールから ClassType への依存関係を導入したくありません。

これまでのところ、次の代替手段があります。

  • 独立させずに ClassType への依存関係を導入すると、アプリケーションに「スパゲッティ」依存関係がさらに作成されるリスクがあります (これは私の最も好ましくないソリューションです)。
  • IType などの新しいクラスを導入し、モジュールが IType のみに依存するようにします。ClassType は IType から継承する必要があります。
  • 識別方法として文字列を使用し、新しいモジュールのユーザーに、必要に応じて ClassType を文字列に、またはその逆に変換するように強制します。
  • GUID (または単純な整数) を ID として使用し、GUID と ClassType の間の変換も必要

アプリケーション内のモジュールを切り離すときは、どこまでやるべきですか?

  • インターフェイスを導入して、他のすべてのモジュールがインターフェイスに依存するようにするだけですか? (上記の IType のように)
  • 文字列や GUID などの他の ID を使用して、さらに分離することはできますか?

デカップリングしすぎると、コードが不安定になり、デバッグが難しくなるのではないかと心配しています。Qt でそのような例を見たことがあります。シグナルとスロットは文字列を使用してリンクされており、タイプミスをすると機能は動作しませんが、それでもコンパイルされます。

モジュールをどこまで切り離す必要がありますか?

4

3 に答える 3

2

デザインがリフレクションに基づいている場合、99% の確率で、デザインに大きな問題があります。

一般的に言えば、

if (x is myclass)
elseif (x is anotherclass)
else

ポリモーフィズムを無視しているため、設計が不適切です。これを行っている場合、アイテムxは Liskov Substitution Principle に違反しています。

また、C++ には既に RTTI があることを考えると、車輪を再発明する理由がわかりません。それtypeofdynamic_cast目的です。

于 2010-09-23T17:12:55.137 に答える
1

私はあなたの反省について考えるのをやめて、依存関係のアイデアだけを見ます。

分離するのが合理的なものを分離します。カップリングとは、あるものが変われば別のものも変わるということです。そのため、NewCode は ClassType を使用しています。その一部が変更された場合、NewCode を変更する必要があります。完全に切り離すことはできません。次のうち、分離したいものはどれですか?

  1. セマンティクス、ClassType の機能。
  2. インターフェース、あなたがそれをどのように呼ぶか。
  3. 実装、実装方法。

私の目には、最初の 2 つは妥当な結合です。しかし、実装の変更によって NewCode の変更が必要になることはありません。したがって、インターフェースへのコード。私たちはインターフェイスを固定したままにしようとします。インターフェイスを変更するのではなく拡張する傾向があり、可能な限り後方互換性を維持します。時々、名前と値のペアを使用してインターフェースを拡張可能にしようとしますが、あなたが言及したタイプミスのようなエラーに遭遇することがあります。これは、柔軟性と「型安全性」の間のトレードオフです。

于 2010-09-23T17:50:53.873 に答える
0

それは哲学的な質問です。モジュールのタイプとトレードオフによって異なります。私の意見では、文字列から型へのマッピングに勝る利点がなく、少なくとも文字列が読み取り可能であるGUIDから型へのマッピングを除いて、私はさまざまな時点でそれらすべてを個人的に行ったと思います。

予想される外部使用法とコード編成を考慮して、特定のモジュールに必要なデカップリングのレベルを確認し、そこから進む必要があると思います。あなたは私が知る限りすべての概念的な方法を打ちました、そしてそれらはそれぞれ特定の状況で役に立ちます。

とにかく、それは私の意見です。

于 2010-09-23T18:20:59.987 に答える