web-dev-qa-db-ja.com

「時期尚早の抽象化」とは何ですか?

私はそのフレーズが乱れているのを聞いたことがありますが、私には議論が完全に正気ではないように聞こえます(ここでわざわざ言っているとすみません、それは私の意図ではありません)。

一般的なケースがわかる前に抽象化を作成したくない場合は、(1)属していないものを抽象化に入れるか、(2)重要なものを省略している可能性があります。

(1)私にはこれはプログラマーが実用的ではないように思えます、彼らは最終的なプログラムには存在しないものがあると仮定しているので、抽象化のレベルが低くなるように作業しています問題は時期尚早な抽象化ではなく、時期尚早な結着です。

(2)重要なものを省略することは1つのことであり、後で重要になることが仕様から省略されている可能性は完全にあります。これに対する解決策は、自分自身を明確にし、リソースを無駄にすることではありません。間違っていると思います、それはクライアントからより多くの情報を取得することです。

これは抽象化から具体化に至るまで常に作業する必要があります。これが最も実用的な方法であり、その逆ではないためです。

そうしないと、クライアントを誤解し、変更が必要なものを作成するリスクがありますが、クライアントが独自の言語で定義した抽象化のみを構築する場合は、このリスクにぶつかることはありません(少なくとも、いくつかの具体的な暗闇の中でのショット)、はい、クライアントが詳細について考えを変える可能性がありますが、彼らが最初に彼らが望むものを伝えるために使用した抽象化は依然として有効である傾向があります。

次に例を示します。クライアントがアイテムバギングロボットを作成することを望んでいるとします。

public abstract class BaggingRobot() {
    private Collection<Item> items;

    public abstract void bag(Item item);
}

私たちは、クライアントが使用した抽象化から何かを構築していますが、わからないことについては詳しく説明していません。これは非常に柔軟性があり、「時期尚早な抽象化」と呼ばれるのを見てきましたが、実際にはバギングがどのように実装されたかを想定するのは時期尚早です。一度に複数のアイテムをバッグすることをクライアントと話し合った後、 。クラスを更新するために必要なのはシグネチャを変更することだけですが、ボトムアップを始めた人にとっては、大規模なシステムのオーバーホールが必要になる可能性があります。

時期尚早な抽象化などはなく、時期尚早な結集だけです。このステートメントの何が問題になっていますか?私の推論のどこに欠陥がありますか?ありがとう。

10
James

少なくとも私の意見では、時期尚早な抽象化はかなり一般的であり、OOPの歴史の初期には特にそうでした。

少なくとも私が見たところから生じた主要な問題は、人々がオブジェクト指向階層の典型的な例を読むことでした。彼らは可能性があるが発生する将来の変更に対処する準備をすべて整えることについて多くのことを話されました(彼らがそうすることを信じる特に良い理由はなかったとしても)。しばらくの間多くの記事に共通する別のテーマは、「哺乳類はすべて同じである」または「鳥はすべて同じである」という単純なルールに反するカモノハシのようなものでした。

その結果、実際には従業員のレコードなどを処理するだけで十分なコードが作成されましたが、クモまたは甲殻類を雇ったことがある場合に備えて、注意深く書かれました。

19
Jerry Coffin

抽象化は目的を達成するための手段であることを覚えておくことは重要です。抽象化を使用してプログラム全体の動作を統一し、新しいクラスの追加が予想されるが、その瞬間に抽象化が必要な場合にのみ、新しいクラスの追加を簡単にします。

必要になるかもしれません(将来新しいクラスを追加する必要があると考える本当の根拠がないため)だけでは、抽象化を追加しません。ここでの適切な比喩は配管であるかもしれません。うまくいけば、水が上/下、東/西、北/南に流れることを可能にする6方向パイプが、最も柔軟なタイプのパイプになることに同意するでしょう。理論的には、パイプが必要な任意の場所で6方向パイプを使用し、不要な方向を遮断できますよね。

シンクの下のリークの問題を修正しようとして、パイプのすべてのセクションが6方向のパイプの断片であることがわかった場合、そのように設計した人にイライラして髪を引き出したいと思います。問題がどこにあるかわからないだけでなく、適切な方法でゼロから開始することはほぼ間違いなく簡単です。

もちろんコーディングではない配管ですが、比喩はまだ立っています。抽象化は、それらの6方向パイプピースを使用するようなものです。あなたがいつかあなたが正直に信じるかもしれないときそれらを使ってください近い将来に 6つの方向すべてからパイプを接続する必要がある。それ以外の場合、抽象化は単純な複雑化であり、何も必要としないパターンを使用することや、すべてを実行しようとする神クラスを使用することと大差ありません使用されておらず、今後も使用される可能性が低い場合は、最終的に何もないクラスを追加します。

確かに、プログラムを書く技術は概念的に非常に抽象的なものです。抽象化であるために抽象化は存在しないが、実際には何らかの方法で実用的であるため、単に言及する価値があります。抽象化を使用する必要があると感じた場合もそうですが、後で配管をチェックするように依頼しないでください。 ;)

6
Neil

何年も前にオブジェクト指向の分析と設計について知ったとき、私たちは顧客が必要とするシステムのわかりやすい英語の説明から始めました。

それを見ると、どんな名詞(または名詞句)も可能なクラスと見なされます。動詞(または動詞句)は、クラスの潜在的なメソッドになります。つまり、「袋詰めロボット」はクラスBaggingRobotになる可能性があります。 「バッグを開く」はメソッドOpenBagになるかもしれません。

数回繰り返すと、これはクラス図になります。

この時点では、抽象クラスはありません。顧客は、袋詰めロボットの抽象的な概念を望んでいません。彼らは物をバッグに入れるロボットを望んでいます。すべてのクラスは具象であり、一連のメソッドがあります。

抽象クラスは、次のことが明らかになったときにのみ導入されます。

  • 階層を形成できる類似のクラスがいくつかあります。
  • それらは実際には共通点を共有しているため、基本クラスは有用な目的を果たします。

私にとって、「時期尚早な抽象化」とは、BaggingRobotmustBaseRobotから継承することを想定しており、さらに悪いことに、BaseRobotすべてのロボットに共通するものを知る前に。

3
Simon B

まだ存在していない問題を解決する必要があるように聞こえますが、クライアントが要求していることが間違っていると考えている場合を除いて、発生することを想定する十分な理由はありません。それが事実である場合、私は、抽象またはその他の推測ソリューションの実装よりも多くのコミュニケーションをお勧めします。クラス定義を「抽象化」するだけで無害に見えるかもしれませんが、後で拡張できることを知って安心しているかもしれませんが、必要がない場合や、設計を複雑にしすぎる方法で拡張する場合もあります。間違ったものを抽象化することによって、線。

あなたの例に沿って、それがロボット自体アイテムがバッグされているまたはバギングの方法は行を変更しますか?

時期尚早な抽象化は、実際には抽象化を実行する十分な理由がないことを意味します。抽象化は多くの言語で無料ではないため、正当化せずにオーバーヘッドが発生する可能性があります。

編集コメントのOPのいくつかのポイントに回答するために、ポイント(1)および(2)に対処しながら、長いコメントチェーンを必要としない方法で明確にして応答するようにこれを更新します。具体的に。

(1)私にはこれはプログラマーが十分に実用的ではないように思えます彼らは最終的なプログラムには存在しないものがあると仮定しています、それで彼らは低いレベルで作業しています抽象化、問題は時期尚早な抽象化ではありません、それは時期尚早な結着です。

(エンファシス鉱山)。最終的なプログラムに存在しないものがあると仮定すると、私はあなたの例で正確に見ています。顧客は、荷物を運ぶロボットを求めました。言語がやや曖昧な場合、これは非常に具体的な要求です。顧客はアイテムを袋に入れるロボットを望んでいるので、オブジェクトのペアを作成します

public class Item {
/* Relevant item attributes as specified by customer */
}
public class BaggingRobot {
  private Collection<Item> items;

  public void bag(Item item);
}

モデルはシンプルで正確であり、ソリューションに複雑さを追加することなく、また顧客が求めている以上のものを望んでいると仮定することなく、顧客が設定した要件に従います。これが提示されたときに、ロボットが交換可能なバギング機構を持つ必要性を明確にした場合、その後のみ、インターフェースの作成を正当化するのに十分な情報がありますまたは、抽象化によってシステムに追加された特定の値をポイントできるようになったため、他の抽象化方法。

逆に、純粋な実用主義からの抽象化から始める場合は、別のインターフェースを作成してそれを具体化して実装するか、抽象クラスを作成するか、好きな抽象化の方法を使用します。その後、顧客がこれに満足し、それ以上の拡張が不要であることが判明した場合、時間とリソースを無駄に費やしているか、システムにオーバーヘッドと複雑さをもたらしたかのいずれかです。

(2)に関して、私は重要なものを省略することがその表面にあるのは時期尚早な抽象化の特徴ではないことに同意します。抽象化の有無にかかわらず、重要なものは省略できます。抽象化のチェーンのはるか下にある場合を除いて、それをいずれかの方法で整理することは難しくも簡単でもありません。

代わりに、私はそれを抽象化がドメインモデルを難読化するリスクを実行することを意味すると解釈します。ドメインモデルのさらなる成長とドメインの理解に劇的な影響を与える可能性のある関係を作成しているため、不適切な抽象化はシステムの推論を非常に困難にする可能性があります。 抽象化されたものに関する重要な情報ではなく、システム全体に関する重要な情報を省略してしまうリスクがあります、モデルを間違ったうさぎの穴に落とします。

1
JimJam