7

クラスを緩く結合しておくことは、理解、変更、およびデバッグが容易なコードを作成する上で重要な側面です。しかし、初心者として、私が苦労している最も単純な例を超えたときはいつでも。

私は、多かれ少なかれ、文字列、整数、および単純なデータ型を独自のクラスにカプセル化する方法を理解しています。ただし、リッチテキスト形式などの情報を扱い始めると、コンポーネントにすでに存在するさまざまなメソッドを使用しない限り、状況は非常に複雑になります。この例を続けるために、UIにRTFメモコンポーネントを含むものを書いていると仮定します。Delphiでは、コンポーネントには、フォーマットされたテキストの保存などを行うための組み込みメソッドがあります。さらに、RTFテキスト自体を操作する唯一の(または少なくとも最良の)方法は、コンポーネントに再度組み込まれているメソッドを使用することであるように思われる場合があります。

これらすべてを実行するコンポーネントがすでにある場合、別のクラスでテキストの保存、読み込み、フォーマットのすべての作業をどのように(またはなぜ)実行しますか?

私自身は通常、(a)必要以上に複雑に見えることを行うか、すでに存在するメソッドを再発明するか、(b)互いに緊密に結合された不十分なクラスを作成することになります。彼らがインフォマーシャルで言うように、「もっと良い方法がなければならない!」

私はその「より良い方法」がどのように機能するかについて概念的に迷っています。何かご意見は?

4

4 に答える 4

5

いくつかの基本的な概念を見逃していると思います。

OOPの背後にある考え方は、離散的で再利用可能なロジックのユニットから始まります。自給自足のモジュールの作成に重点を置いています。

RTF Memo コンポーネントの場合、特定のデータ セット (メモ) を処理することで上記の基準を満たし、プログラムやプログラム内の他のオブジェクトが自分の仕事を気にしないようにします。その目的は、インターフェイスを表示し、データを受け入れ、その特定のデータを操作し、そのデータをプログラムの別の部分に渡すことです。

疎結合の背後にある考え方は、単にそのメモ コントロールを、同じインターフェイス仕様を満たす別のコントロールに置き換えることができるということです。つまり、それをインスタンス化し、ユーザーがそれを操作できるようにし、必要に応じてデータを引き出すことができるということです。

疎結合であることは、関心の分離(SoC) の考え方と密接に関連しています。これは、重複する機能を減らして管理を容易にするために、プログラムを個別の機能に分割するプロセスです。しかし、それらは同じものではありません。偶然にも、これはプログラミングの手続き型スタイルから OOP への移行を後押しした主な要因の 1 つでもありました。OOP は、関連する個別の機能の観点からプログラミングを強制するためです。

あなたは本当にSoCについて尋ねているようです。

SoC を実現するには多くの方法があります。場合によっては、UI、処理ロジック、および永続化レイヤーを分離しておく必要があります (たとえば、MVC デザイン パターンを考えてみてください)。複雑さを軽減するために、関連する機能をまとめておくだけの場合もあります。RTF コントロールは、データを操作するために必要なすべての関数を含むことで既に行っているため、それ以上の依存関係はありません。

于 2009-03-27T18:30:05.680 に答える
5

クラスを分離する方法として、インターフェイスと依存性注入という 2 つの概念を提案します。インターフェースは、どの実装にも依存しないコントラクトまたは期待される一連の動作を定義する方法を提供します。クラスがクラスではなくインターフェースに依存している場合、インターフェースに依存しているクラスを書き直さなくても、インターフェースを実装する他のクラスを自由に置き換えることができます。

依存性注入でインターフェイスを使用する場合、つまり、クラスに特定の実装を独自に作成させるのではなく、実際に動作する実装をクラスに与えると、アプリケーションでさらに分離を実現できます。現在、クラスはインターフェースについてのみ知っており、それを作成する方法さえ知りません。それを使用するだけです。依存性注入は、多くの場合、Builder や Factory などの作成パターンで使用されます。このパターンでは、追加のクラスでアプリケーションを拡張するときに、そのクラスのみを変更する必要があるように、単一のクラスでオブジェクトの構築をローカライズします。

また、カップリング (およびその双子の結束) は相対的な尺度であることを忘れないでください。すべての結合を排除することはできません。そうしないと、オブジェクトが相互作用できなくなります。ある程度の依存は必要です。使いやすさと実装のしやすさのバランスを取る必要があります。

あなたの特定の例に関しては、実際のコードなしではわかりません。ソリューションを過度に設計し、DRY の原則に違反していると思われます (繰り返さないでください)。完全な再実装ではなく、クラスをフレームワーク コンポーネントから切り離すために、インターフェイスや軽量ラッパーを使用する方法を検討する必要があるかもしれません。

于 2009-03-27T18:24:35.100 に答える
0

質問については完全に明確ではありませんが、ここでは戦略パターンがうまくいくように思えます。

親の RTF オブジェクトに基づいてオブジェクトを構築しますが、独自のメソッドを持つ定義済みオブジェクトとして格納などの処理メソッドを設定します。

これにより、すべての親メソッドを厳密に継承することなく合成の力が有効になり、巨大なカスタム オブジェクトを構築する必要がなくなり、必要なメソッドを置き換えるだけで済みます。

于 2009-03-27T18:11:35.757 に答える
0

あなたが選んだ例はかなり複雑です。

rtf memo コンポーネントが非常に疎結合であると言うのは正しいです。大まかに、実際には拡張可能ではなく、プレゼンテーション/ビュー、コントローラー、およびモデルを統合するため、そのまま使用することしかできません。

適切に設計された拡張可能なリッチ テキスト システムの例を見たい場合は、OS X テキスト システム(コードを読みたい場合は Gnustep) のドキュメントを参照してください。多くの設計上の決定を行う必要があり、あるモジュールから別のモジュールに隠す必要があるため、複雑です。そこでは、優れた構造で直接作業できます。

rtf memo コンポーネントの使用範囲は限られているため、適切に設計されたクラスを使用して回避する必要がある場合があります。

  • コンポーネント データの読み込みと保存は、プログラム内の他のデータを同じファイル/データベースに保存する必要がない場合にのみ意味があります。
  • また、大量のデータをうまく処理できません。
  • そして、rtf の小さなサブセットしか理解できません。
于 2009-03-27T22:57:03.747 に答える