8

ご存知のように、「インターフェイスへのプログラム」の設計原則は、具体的な型や実装ではなく、スーパータイプを広く好みます。

Javaプログラムでinstanceofを使用してスーパータイプから具象型を導出するという原則と一致していますか?

私のアプリケーションでは、Storehouse は、いくつかのプライベート変数とパブリックの getter および setter を持つ抽象スーパータイプ クラスです。

ConcreteStorehouseA は Storehouse を継承し、多くの具体的なメソッドと変数を持っています。ConcreteStorehouseB は似ていますが異なります。

私のアプリケーションは倉庫を受け取ります。ただし、Storehouse は操作するのに便利なタイプではありません。本当に有用なメソッドだけが具体的な型に含まれているため、次のように instanceof を使用します。

if (storehouse instanceof ConcreteStorehouseA) {
    ConcreteStorehouseA concreteStorehouseA = (ConcreteStorehouseA) storehouse;
    // perform operations on the concrete type's useful methods and variables

instanceof の使用は原則と互換性がありますか?

編集:

本質的に、このアプリケーションは、テーブル トップ RPG、Shadowrun のサイコロ シミュレーターです。具体的なタイプは、成功テスト、反対テスト、拡張テストなどのさまざまなテスト タイプであり、成功する操作の要因とパラメータはすべて非常に異なります。スーパータイプには基本的にダイス プールが含まれています。

4

7 に答える 7

10

経験則として、あなたが言及した「プログラムからインターフェイスへ」の原則は、次のように変換できます。インターフェイスタイプimport のみで、コンパイル時のサブクラスへの依存はありません。

したがって、あなたの質問に対する答えは間違いなくノーです。具体的な型にキャストするため、インターフェイスにプログラミングしていません。

于 2011-02-11T21:26:51.980 に答える
8

あなたはそれを自分で言った:

私のアプリケーションは倉庫を受け取ります。ただし、Storehouse は操作するのに便利なタイプではありません。本当に有用なメソッドだけが具象型に含まれているため

言い換えれば、あなたのStorehouse抽象化はあなたに何も買っていません...なぜあなたはそれを持っているのですか?

で抽象メソッドを作成しStorehouse、各具象クラスに実装して、具象型をクライアント コードで同じように処理できるようにすることはできますか? それが抽象化の目標です。

于 2011-02-11T21:23:20.307 に答える
2

あまり。メソッドが受け取る型によって動作が大きく異なる場合、ポリモーフィズムは何の役にも立ちません。2 つの別々のオーバーロードされたメソッドを検討する必要があります。1 つConcreteStorehouseAは引数としてを取り、もう 1 つはConcreteStorehouseB.

于 2011-02-11T21:25:01.823 に答える
2

それは必ずしも罪ではありません。x が A の場合はこれを行い、x が Y の場合はこれを行うという仕様を実装しているとします。コードが仕様のように見えるようにすることをお勧めします。それを人為的に小さな断片に切り分けて異なるソースに配置することは、大げさであるだけでなく、複雑で安全ではなく、理解しにくく、維持するのも困難です。

プログラミングの問題は多面的です。少なくとも今のところ、プログラミング言語は 1 次元です。関連する懸念事項を密接に整理する方法は芸術です。懸念はクラスに応じて分解されなければならないという定説に同意しないでください。その場合、懸念は多くても 1 つのクラスを参照でき、そのクラス内に存在する必要があります。

より優れたソフトウェアを作成する方法を知っている専門家によると、前世紀、ソフトウェア エンジニアリングにはこの大きなタブーがありました。つまり、コードの変更は絶対に避けるべきです。以前に作成したソース コードを変更する場合、宇宙はいつでも崩壊してピーナッツになる可能性があります。したがって、最初から完璧なアーキテクチャを設計することをお勧めします。その後、要件の変更は、既存のコード ベースに触れることなく、新しい/クリーンなクラスを追加することで実行できます。

それは、ここでの言葉遣いを非常に正確にさせてください。当時でさえ、まったくナンセンスです。

今日では、はるかに優れたツールがあり、コードの変更は安全であるだけでなく、推奨されています。予期せぬ理由で明日コードを簡単に変更できるようにする最善の方法は、今日のコードをできるだけシンプルに保つことです。カンマでも分かるようにコードを書いてください。

于 2011-02-11T22:35:26.533 に答える
1

実行している操作を洞察せずに確認するのは難しい場合がありますが、より洗練された設計は、StoreHouseにさまざまな「操作」のメソッドシグネチャを定義させることです。次に、if(instanceof)チェックの代わりに、操作を実行するだけで、concreteStorehousesがそれらの操作を実装します。

public abstract class Storehouse
//add these definitions;
public void operation1();
public void operation2();

public class ConcreteStorehouseA

public void operation1() {
   //do operation
}

public void operation2() {
   //do operation
}

public class ConcreteStorehouseB

public void operation1() {
   //do operation
}

public void operation2() {
   //do operation
}

呼び出しコードでは、次の代わりに:

if (storehouse instanceof ConcreteStorehouseA) {
    ConcreteStorehouseA concreteStorehouseA = (ConcreteStorehouseA) storehouse;
    // perform operations
} else if (storehouse instanceof ConcreteStorehouseB) {
    ConcreteStorehouseB concreteStorehouseB = (ConcreteStorehouseB) storehouse;
    // perform operations
}

次に、ポリモーフィズムを使用して、実行されている実装を気にせずに操作を実行できます。

storehouse.operation1();
storehouse.operation2();

ここで、concreteStorehouseAとConcreteStorehouseBは、これらの操作の実装を定義しています。

于 2011-02-11T21:29:06.740 に答える
1

Storehouseこの場合、抽象化は実際には適切な抽象化ではないようです。タイプ自体としては、実際には何も提供していません。

役立つかもしれないことの 1 つは、実装を「型」とはまったく考えないようにすることです。「タイプ」は、クラスが実装している抽象化です。(基本的に、「クラス」と「型」という用語は、考え方の中で切り離して考えてください。)したがって、使用している型はStorehouse. ConcreteStorehouseAでありStorehouse、そうですConcreteStorehouseB。質問は、 とは何Storehouseですか? それが、それぞれが何であるかを定義するタイプです。

この特定のケースでは、異なるStorehouse実装が (少なくとも現在の実装では) 非常に異なるため、価値のある抽象化を実際には共有していないように思えます。この場合の抽象的な「型」は、実際に型を抽象化するのではなく、継承によっていくつかの共通機能を提供するだけです。

別の言い方をすれば、Storehouseここでの実装は、リスコフ置換の動機付けポスターの典型的な例のように思えます: http://www.lostechies.com/blogs/derickbailey/archive/2009/02/11/solid-development-モチベーションの原則-pictures.aspx

于 2011-02-11T21:31:07.423 に答える
0

さまざまな人が指摘しているように、これはインターフェースへのプログラミングではありません。どうやら、インターフェイスの抽象化が要件に対して弱すぎるようです。

これに対処するにはさまざまな方法がありますが、その中には次のようなものがあります。

  • インターフェイスが制御下にある場合は、展開できます。それが価値があるかどうかを検討してください。特に次の箇条書きが当てはまる場合は、支払うには高すぎる可能性があります.
  • 1 種類のコンクリート倉庫しか使用しない場合は、それを直接使用できます。
  • さまざまな種類のウェアハウスをサポートする必要がある場合、適切な代替手段は、必要な抽象化を正確に提供する独自のインターフェイスを定義し、各種類の具象クラス (アダプター パターン) の薄いラッパーを作成することです。
于 2011-02-11T21:31:40.463 に答える