2

オブジェクト作成の責任について、一般的な規則、一般的な落とし穴はありますか? オブジェクト作成の責任者をどのように決定すればよいですか? 明らかな場合もあれば、そうでない場合もあります。冗長なコードを避け、必要最小限に制限しようとしています。作成メソッドをどこに書くかを決めなければならないとき、私は自分自身に何を尋ねるべきですか?

class State
{
    ...
    public [City] getCapitalCity()
    {
        return new City(this.capitalCityID);
    }
}

class City
{
    ...
    public static [City] getCapitalOf(State s)
    {
        return new City(s.capitalCityID)
    }
}

前もって感謝します

4

2 に答える 2

1

最初のメソッドの欠点は、呼び出しごとに新しいCityオブジェクトを作成することです。そのようなものは私にとってより自然なものになるでしょう:

class State
{
    protected [City] capitalCity;
    ...
    public [City] getCapitalCity()
    {
        if (this.capitalCity == null) {
            this.capitalCity = City::getCapitalOf(this);
        }
        return this.capitalCity;
    }
}

class City
{
    ...
    public static [City] getCapitalOf(State s)
    {
        return new City(s.capitalCityID)
    }
}

私は両方の方法をそのままにして、一方を他方に委任したことに注意してください。この変更後もまだ解決されていないもう1つの点は、Cityオブジェクトを交換できないことです。つまり、単体テストのモックと交換できません。依存関係は固定されています。

デザインパターンについて言えば、緩く結合されたデザインの場合、オブジェクトをインスタンス化するクラスはファクトリのみである必要があります。

ここでそれを適用すると、次のようになります。

class CityFactory
{
    ...
    public static [City] createCapitalFromState(State s)
    {
        return new City(s.capitalCityID);
    }
}

class State
{
    protected [City] capitalCity;
    ...
    public [City] getCapitalCity()
    {
        if (this.capitalCity == null) {
            this.capitalCity = CityFactory::getCapitalOf(this);
        }
        return this.capitalCity;
    }
}

class City
{
    ....
}

簡単にするために、ファクトリメソッドを静的に保ちました。実際には、のインスタンスにアクセスできますCityFactory。そして、これは簡単に交換して、さまざまなオブジェクトを生成できます。

作成方法をどこに書くかを決める必要があるとき、私は自分自身に何を尋ねるべきですか?

2つのこと:

  • 新しいハードワイヤード依存関係を導入しますか?
  • オブジェクト作成を独自のクラスに抽出できますか?

2つのドメインオブジェクトは、明らかに常に一緒に使用されるため、デカップリング演習の最良の例ではないCityと考えることができますか?State

しかし、あなたがそれについて考えるならば、それはそれほど大げさではありません:多分ある時点であなたは行動の特定の違いを区別するためにあなたの都市をサブクラス化または装飾するでしょう。シティファクトリを使用すると、都市の作成を変更したい場合に、一度に変更するだけで済みます。そして、これはOODの重要な目標です。何かを変更する必要がある場合、それをあちこちで変更する必要はなく、ある時点でのみ変更する必要があります。

于 2013-03-22T17:19:16.273 に答える
1

おそらく、クラスがどのように使用されるかに完全に依存していると言えます。この場合、State.getCapitalCity()開発者のワークフローは、既に持っている状態オブジェクトの首都が何かを問い合わせる可能性が高いため、 を選択します。

私のクラス設計は、おそらく次のようになります。そうすれば、必要に応じて 2 つのエンティティ間を行き来できます。

class State
{
   ... 
   public City CapitalCity()
   {
      return new City(this.capitalCityId);
   }
}

class City
{
   ...
   public State State()
   {
      return new State(this.stateId);
   }

   public bool IsCapitalCity()
   {
      return this.isCapitalCity;
   }
}
于 2013-03-22T17:05:29.570 に答える