0

言語構文は無視してください。ここでは OOPS についてのみ説明します。


ここに 2 つのコード スニペットを示します。それぞれがコンポジションのサンプルです (私が間違っていなければ)。

問題文: システム内のエンティティの統計を保持するオブジェクトがあります。それらの統計を次のようにします。

  1. 名前
  2. 苗字
  3. 給料

*これらのフィールドは何でもかまいません。私はこれらを例に取りました。どの分野が必要かどうかという観点から考えないでください。3 つすべてが必要であると仮定します。

これらのフィールドに対応するクラスを作成しました:

public class Stats{
field Name;
field LatsName;
field Salary;
}

今、私はある人についての情報を時系列で知りたいという状況に遭遇しました。ワークフロー システムのある時点で、3 つのステージすべてについて個人に関する情報を提示する必要があることを見てみましょう。

  1. 彼が子供だったとき。
  2. 彼が若かったとき。
  3. 彼が退職したとき。

ここで注意すべき点は、namelastNameは変わらず、給与のみが変わる可能性があるということです。このため、既存のオブジェクト「stats」を使用できるクラスを作成できるのではないかと考えました。

2 つの解決策を紹介します。どちらが優れているか、またその理由を教えてください

コード例 1

public class CompositeStats{
  //Adding three more properties and hinding the one already existing.
  private objStats= new Stats();
  public field FirstName{
    get{return objStats.Name;}
    set{objStats.Name=value;}
  }
  public field LastName{
    get{return objStats.LastName;}
    set{objStats.LastName=value;}
  }

  public field SalaryChild{get;set;}
  public field SalaryYoung{get;set;}
  public field SalaryRetired{get;set;}
}

上記のサンプル コードでは、給与の元のフィールドを公開しませんでしたが、期間ごとに 3 つの新しいフィールドを作成しました。

コード例 2

public class CompositeStats{
  private objStatsChild= new Stats();
  private objStatsYoung= new Stats();
  private objStatsRetired= new Stats();

  public field FirstName{
    get{return objStatsChild.Name;}
    set{objStatsChild.Name=value;}
  }

  public field LastName{
    get{return objStatsChild.LastName;}
    set{objStatsChild.LastName=value;}
  }

  public field SalaryChild{
    get{return objStatsChild.Salary;}
    set{objStatsChild.Salary=value;}
  }

  public field SalaryYoung{
    get{return objStatsYoung.LastName;}
    set{objStatsYoung.LastName=value;}
  }

  public field SalaryRetired{
    get{return objStatsRetired.LastName;}
    set{objStatsRetired.LastName=value;}
  }

}
4

6 に答える 6

2

私はこのようなものがいたるところに良いと思います。オブジェクトモデルを変更せずに、新しいライフステージを作成できます。

また、人がまだステージに達していない場合、その人の情報は保存されません。「CurrentStage」というプロパティは、リスト内の最新のステージを選択できます。

public class Stage{
  object BeginStage;  // Probably a DateTime or similar class.
  object EndStage;    // Probably a DateTime or similar class.
  object Salary;
}

public class Stats{
  object Name;
  object LastName;
  IEnumerable<Stage> Stages;
}

このバリエーションを使用することもできます。

public enum Stage {
  Child,
  Young,
  Retired,
}

public class StageSalary {
  Stage Stage;
  object Salary;
}

public class Stats{
  object Name;
  object LastName;
  List<StageInfo> Stages;
}
于 2009-07-23T15:02:59.860 に答える
1

最初のものがより良い選択であることは明らかだと思います。

理由:1。パフォーマンス:

 private objStatsChild= new Stats();
private objStatsYoung= new Stats(); 
private objStatsRetired= new Stats();

実際に1つのインスタンスからのみ値が必要なのに、なぜ3つのインスタンスを作成するのでしょうか。

  1. 悪いデザイン。「統計」のインスタンスを3つ作成し、名前を返すときにそのうちの1つを選択します(ランダムに、少なくとも1つを選択するロジックはありません)。

3.統計で「Salary」を非表示にするだけの場合は、「Salary」が親クラスから削除された、継承のケースになります。

于 2009-07-23T14:57:12.273 に答える
1

「ファサード」と呼ばれるデザインパターンを確認してください。これにより、複数のインターフェイスから継承する単一のクラス構造を作成でき、データはそれらを分類した構造のみを表すことができます。つまり、「子」のフィールドを非表示/無視します。 「引退」などにのみ使用されます。

于 2009-07-23T15:03:23.400 に答える
1

もう1つの使用法を考えてみましょう。

var dictStages = new Dictionary<Stage,double>();

ここで、ステージは列挙型です:子供、大人、引退

クラスにプロパティを追加します

CurrentStage-これはdictStageCurrentSalaryからの最新のステージを反映します-これは
CurrentStageの給与を反映します。

ただし、特定のステージの給与を返すことができるいくつかのメソッドを公開したい場合があります。

于 2009-07-23T14:56:37.577 に答える
0

「古典的な」「IsA」、「HasA」の考え方は、常に正しい方向に導くのに役立ちます。

「人物」「HasA」「データ集」、その人のライフステージからあなたの情報を。今日、あなたは「3つの」段階と言っていますが、もちろん、そのような限られた問題の見方に合わせて設計することは決してありません...そうですか?

だからあなたは持っています

class Person {
  [vector or list or your favorite collection type] Data;
  Name;
  LastName;
};

Person への「HasA」参照、およびスナップショットに必要なデータの指定子について尋ねるスナップショット:

class PersonInfoSnapshot {
  [reference to] Person;
  /* "reference to Person.Data" could mean anything that allows retrieval of the data that you need */
  [reference to] Person.Data;
};

特定のタイプ、可視性などの詳細は演習として残されています。

于 2009-07-23T17:06:46.650 に答える
0

コードを次のようにリファクタリングします。

class Person {
   field Name;
   field LastName;
}

enum PersonAge {
   Child, Young, Retired
}

class Stage {
   public PersonAge Age { get; set; }
   field Salary;
}

class PersonStats {
   public Person Person { get; set; }
   public IList<Stage> Stages { get; set; }
}

それは理にかなっていますか?

于 2009-07-23T15:04:49.577 に答える