1

最初に言っておきますが、私は OO パターン、プラクティス、クリーン コードなどの経験があまりありません。実際、これらすべてのテクニックを学んでいます。

最も疎結合の方法は、新しいオブジェクトの構築またはメソッドの実行にプリミティブ型を使用することですが、それは実用的ではないと思いますが、これは正しいですか? エラーが発生しやすくなるからです。単純に存在しない Id を表す整数を引き渡すことができます。オブジェクトを使用する場合、有効なデータがあることを実際に知っています。そうしないと、オブジェクトが作成されないか (例外)、チェックする必要がある無効な状態になります。

この記事では、これに具象オブジェクトを使用するのは悪であると述べています。代わりに、そのインターフェイスを引き渡す必要があります (ご存知のように)。具象型 (インターフェイスではない) を変更すると、依存型が「故障」します。それはすべての場合にそうですか?これは、閉じた単一プロジェクト環境にも当てはまりますか? インターフェイスが一度作成されると、変更できず、再度変更/リファクタリングできない場合にのみ理解できます。

4

3 に答える 3

2

この質問は多くの問題を提起すると思います。私は物事をできるだけ短くするように努めます:

単に存在しないIDを表す整数を言うことができます。

私の見解では、プログラムは問題の領域を表す(計算)モデルです(物理学者や天文学者が現象を表す方程式を書くことで類推することができます)。オブジェクトを使用してモデル化する場合、実行しているのは、特定のルールを使用してそのドメインの表現を作成することです。したがって、質問に戻ると、概念的には整数でIDを表すことができますが、問題のドメインには、適切に表されていない概念があります(たとえば、有効なIDではない整数があるため) )。また、概念的な問題に加えて、問題は、整数に新しい動作を追加(したがって委任)できないことです。可能であれば(たとえば、Smalltalkではすべてがオブジェクトであり、任意のクラスを拡張できます)、それも間違っています。モデリングの観点から。一般的な経験則として、特定の責任を負わないオブジェクトに動作を記述しなければならない場合、モデルには抽象化が欠けていると考えます。この場合、Utilクラスメソッドを持つクラスisValidId

オブジェクトを使用する場合、そのオブジェクトに有効なデータがあることを実際に知っています。そうでない場合、オブジェクトは作成されていないか(例外)、チェックする必要のある無効な状態になります。

100%同意します。私はあなたが役に立つと思うかもしれないこれについていくつかの記事を書きました(免責事項:私はQuanbitResearchで働いています)

この記事では、これに具体的なオブジェクトを使用するのは悪いことだと言っていますが、代わりにそれらのインターフェイスを渡す必要があります(ご存知のとおり)。(インターフェースではなく)具象型を変更すると、依存型が「故障」します。すべての場合にそうですか?

オブジェクト、タイプ、インターフェースに関する話はかなり長いです。少し要約すると、理想的には、具体的なクラスではなく、インターフェイスに対してプログラムする必要があります。これは、(理論的には)特定のオブジェクト(パラメーターなど)が事前定義されたセマンティクスを持つメッセージのセットを実装することだけに注意する必要があるためです。ただし、この道を進むと、実際には、1つのクラスが複数のインターフェイスを実装し、すべてのインターフェイスをクラスと同期させるための簿記が禁止されていることがわかります。私は通常、動的に型指定された言語を使用するため、これはほとんどの場合問題になりませんが、静的に型指定された言語で作業する必要がある場合は、システムがプロジェクト外のコードフォームとインターフェイスする必要があるときにインターフェイスを使用します。モジュール間のAPIで。言い換えれば、私はシステムの「境界」の結合を下げようとします。

これは、閉じた単一プロジェクト環境にも当てはまりますか?私は、インターフェースが(一度書かれると)触れられず、二度と変更/リファクタリングされない場合にのみ理解します。

私はここで反対しなければなりません。計算モデルであるプログラムは、問題領域の特定の時点で私たちが知っていることを反映しています。このように、私たちがそれに取り組むほど、私たちはそれについてより多くを知るようになります。プログラミングには学習が含まれ、学習するにつれて物事をよりよく理解します。したがって、モデルが変更されます。また、モデルが変更されると、モデルを表すために使用する要素も変更されます(クラスやインターフェイスなど)。時間が経つにつれて、モデルがより堅牢になり、概念の変更が遅くなり、ある時点で安定したモデルになることがわかります。しかし、変更はレイファクタリングであり、あなたが期待すべきものです:)。

HTH

于 2012-11-23T12:06:43.430 に答える
2

必要に応じてすべてを使用する必要があります。プリミティブは、意味がある場合にのみ使用してください。コンクリートタイプも同様です。確かに、抽象化に「結合」する方が良いのですが、多くの場合、抽象化はなく、必要ありません。使用しているすべてのオブジェクトからインターフェースを抽出できますが、そうする本当の理由がなければ意味がありません(ポリモーフィズム)。

あなたは考えなければなりません。具象型の使用を開始できますが、実際には具象型ではなく抽象化が本当に必要であることがわかります(たとえば、ストレージが変更される可能性があることがわかっている場合、ストレージの抽象化は非常に一般的なことです)。Mysql Databaseオブジェクトに依存する代わりに、オブジェクトはデータベース抽象化(抽象クラ​​スまたはインターフェース)に依存することができます。これにより、任意の実装(Mysql、MMSql、さらにはNoSql)を切り替えることができます。ただし、mysqlのみを使用する小さなアプリをコーディングしている場合は、具象型を直接使用してください。

インターフェイスを抽出する理由がもう1つあります。それは、テストです。もちろん、具象型が依存関係として使用され、それが十分に複雑な動作をする場合にのみ、インターフェースを抽出します。依存関係が単純なDTO(データ転送オブジェクト)である場合は、それを抽象化する必要はありません。

これらのほとんどは経験に基づいていますが、経験則では、具体的なタイプから始めて、必要に応じてそれを抽象化します。オブジェクトが、必要な機能を含むインターフェースをすでに実装している場合は、そのインターフェースを直接使用します。

于 2012-11-23T11:49:42.767 に答える
2

答えは(よくあることですが)「場合による」と思います。決定は、次の影響を受けます。

  1. どのような種類のオブジェクトを扱っていますか? ドメイン オブジェクト (ビジネス ドメインの概念を表す) またはサービス (たとえば、検索または保存操作を提供する)。

  2. アプリケーションの規模や複雑さは?

  3. 作業しているすべてのオブジェクトを「所有」していますか? あなたが使用しているオブジェクトが、あなたの管理外の誰かによって変更される可能性はありますか?

ドメイン モデルを正当化するのに十分なほど複雑なプロジェクトでは、次のセットアップを使用するのが好きです。

  1. ID を取得してドメイン オブジェクトを返す「ファインダー」サービス オブジェクトと、ドメイン オブジェクトを取得する「保存」サービス オブジェクトを含むデータアクセス層。

  2. メソッドで他のドメイン オブジェクトのみを受け取るドメイン オブジェクトを含むドメイン モデル。

  3. ID を受け取り、データ アクセス層を使用してドメイン オブジェクトを取得し、ドメイン モデルでドメイン操作をトリガーし、データ アクセス層を使用して変更を保存するサービス層。

  4. ID を提供するサービス層を使用する 1 つ以上の UI 層。

単体テストでこれらのコンポーネントを簡単にモックするオプションが必要なため、サービス オブジェクトをインターフェイスの背後にあるデータ アクセス レイヤーとサービス レイヤーに配置しました。私は通常、自分のドメイン オブジェクトのインターフェイスをわざわざ作成することはありません。

最後に、クラス A がクラス B への具体的な参照を持っている場合、クラス A が使用するインターフェイスとは関係のないクラス B の一部を変更すると、クラス A がどのように壊れるかわかりません。

于 2012-11-23T13:36:38.333 に答える