web-dev-qa-db-ja.com

必要OOP世界と国の問題のための設計

私は現在、鶏または卵の最初の状況の問題に取り組んでいます。基本的に、私はこのようなソリューションを設計しています:

  • Worldは国のコレクションです。
  • Countryには、名前、フラグ、および社長(すべて文字列)があります。
  • 国Aは国Bの友人または支持者のように、国間に関係があります。したがって、他の国の友人または指導国のいずれかである多くの国があります。
  • 国間の貿易の数に基づいて、国が友だちであるかどうかのいくつかの条件があります。国Xが国P、Q、R、Sと言ってさらに輸出する場合、Xはリーダー国であり、P、Q、R、Sはその友国であり、他の国についても同様です。

いつでも私は次のような要求を処理する必要があるかもしれません:誰が究極のリーダー国であるか(最大の支持者や友人などがいる)、誰が究極のリーダー国の支持者であるか、または特定のリーダー国の支持者である、など。ここでのトリックは、友達やリーダーの基本的なプロパティが同じであるということです(すべてのCountryには名前、フラグ、社長がいるように)

この問題ステートメントの基本的なサービス要件に対処するための優れたスケルトン構造が必要です。しかし、後継者、子孫、判決の期間、大統領の家族など、将来の拡張を処理できるデザインが必要です。

従うべきアプローチを決定する際に混乱しています。作成する必要があるか(アプローチ1)、定義する必要があるか(アプローチ2)。

アプローチ1:CountryWorldの一部です

class World
{
    class country *country_list // not taking array , so that i need not to limit the list
};

アプローチ2:Countryが最初に定義され、Worldはそれから継承します

Countryは小さなエンティティであり、Worldは大きなエンティティであるため、これは奇妙に見えます。そして、それから世界の内容は何でしょうか、再び国のリストです。

class World : Inherit class country
{
    // not sure what should be the content here 
    // can getcounty();
    // add_country_to_world();
    //
};

//not sure wether to make this abstract or normal.
//no duplicates countries are allowed.

class country
{
    string countryname;
    string flag;
    string president;
};

次に、キー(国名で作成)と値がその詳細であるマッパーを作成します。国は友達またはリーダーであり、友達はないので、最終的なリーダーが誰であるかを直接確認できます。

18
sravs

私は、WorldとCountryにどのような形式の継承も使用しません。世界は国ではなく、国は世界ではありません。

代わりに、世界は多くの国を含む「バッグ」です。 「バッグ」とは、選択したある種のコンテナクラス(リンクリスト、セット、辞書/マップなど)を意味します。最も効率的に国を見つけることができるコンテナタイプを選択してください。

127
Simon B

ここに1つか2つの考えがあります:

  1. Worldをモデル化する必要があると確信していますか?あなたの説明によると、それは何の効果もないようです。はい、それはあなたのCountriesをカプセル化しますが、それがすべてのプログラムがそうするなら、プログラムのカプセル化はうまくいくはずです。
  2. どういうわけか関係をモデル化する必要があります。正確にはどのように、あなたの要求に依存しますが、私は以下のコードのようなものだと思います。
  3. さまざまなタイプのリーダーシップを管理するいくつかの方法を検討してください。世界の国々は、大きく異なる方法でリードされています。首相や大統領がいる民主主義国もあれば、独裁国もある。リーダーシップを何かに使用する必要がある場合は、これに対処する必要があります。

Relationsクラス(簡略化された疑似コード)

class CountryRelation
{
    Country FirstCountry { get; set; }
    Country SecondCountry { get; set; }
    RelationshipType Relationship { get; set; }
}

enum RelationshipType {
    Friends,
    Enemies,
    Neutral
};
19
Noceo

私はあなたの最初の要件が最もわかりやすいと思います:

世界は国の集まりです

残りの要件は、国、リーダー、およびアライアンスについて話します。私が確信していることが1つあります。動作がなければ、Worldはクラスではありません。せいぜい、それは一般的なコレクションです。

var world = new Collection<Country>();

国とアライアンスの要件がどの程度詳細であるかを考えると、Countryオブジェクトのコレクションは必要ないかもしれません。このモデルの主なエンティティはCountry(お伝えしたとおり)とAlliance(複数の国間の関係)のようです。

var world = new Collection<Country>();

world.Add(new Country("United States of America"));
world.Add(new Country("Portugal"));
world.Add(new Country("Saudi Arabia"));

var natoAllianceTypes = new AllianceType[] { AllianceType.Military, AllianceType.Political };
var nato = new Alliance("North Atlantic Treaty Organization", natoAllianceTypes);

nato.AddMemberNation(world.Single(c => c.Name == "United States of America"));
nato.AddMemberNation(world.Single(c => c.Name == "Portugal"));

var opecAllianceTypes = new AllianceType[] { AllianceType.Economic };
var opec = new Alliance("Organization of the Petroleum Exporting Countries", opecAllianceTypes);

opec.AddMemberNation(world.Single(c => c.Name == "Saudi Arabia"));

// so on, and so forth...

ここでの鍵は、国を結びつけるAllianceクラスです。これにより、希望する関係をモデル化できます。国固有の属性はCountryクラスに属します。 2つ以上の国間の関係に固有の属性は、Allianceクラスに属します。 「リード」国を特定することは、Allianceクラス、またはこの計算を抽象化する必要がある場合は戦略オブジェクトの懸念事項のように聞こえます。たとえば、NATOは政治的および軍事的同盟です。 「政治的」指導者は必ずしも「軍事的」指導者ではないかもしれない。

world?まあ、このオブジェクトについて言うことはあまりありません。これは、存在する国の正規の情報源です(ただし、国際社会によって必ずしも「公式に認識されている」とは限りません。これは、another同盟:国連、誰かですか?)。

12
Greg Burghardt

世界は国ですか?

最も基本的なエンティティはCountryです。 Worldは、すべての国の aggregation です( nited Nations によると、193の加盟国)。明らかに、Worldには大統領も旗もありません。したがって、これはCountryではなく、継承しないものとします。

このモデルから何かが欠けていませんか?

それにもかかわらず、問題にとって重要な何かを見逃しました。国によっては、関係によってはより大きなGroupを形成するように集約できます。そして、すべての質問は基本的にこれらのグループの特性についてです。

enter image description here

WorldGroup(またはそのインスタンス)になるかどうかは哲学的な問題であり、モデルの決定はお客様にお任せします。

国の集計の詳細

GroupCountryよりも多くを提供します:加盟国があり、リーダー国がある場合があります(必ずしもそうである必要はありません)。独自の政治的代表であり、正式な資本または非公式の資本などがある場合があります。ユニオン、フェデレーション、ブロックなど、さまざまな種類のGroupが存在する可能性があります。関係。グループは、将来の拡張のための完全な柔軟性と、その部分に基づいて全体がどのように反応するかについてのより微妙なルールを保証します。

設計の核となる問題は、CountryGroupsを同じように使用したいかどうかです。

  • そうでない場合は、少し迷わずに継承よりも構成を選択できます。これが私の推奨する解決策です(上記を参照)。
  • はいの場合、複合パターン を使用して、同じCountryインターフェイスに基づいてGroupPowerを設計できます=(以下を参照)。

enter image description here

非常に大まかに言えば、すべての問題は、いくつかのメンバーシップ規則による setssubsets 、および partitions に関するものです。グループの機能を簡単に拡張して、それらすべてを処理できます。また、新しいまたは更新された関係に基づいて経済グループを修正できる関係マネージャーを設計できます。

追記:地球上のすべての州に大統領がいるわけではありません。より適切な一般的な用語は 国家元首です。

8
Christophe

専門用語に集中しすぎているようです。

WorldCountryはどちらもテリトリーです。実際、すべてがTerritoryです。テリトリーにはテリトリーが含まれているので、私があなたである場合、それをテリトリーの再帰的なコレクションに減らし、ユースケースのテリトリーを定義するために必要なプロパティの最小数を決定します。

たとえば、政府の場合、PersonRole、およびResponsibilityをすべての関連する人々の基本型として持つことができます。人は多くの役割を持つことができ、役割は多くの責任を持つことができます。継承と階層を使用すると、政府やその他のエンティティを形成する人々の複雑なネットワークを計画できます。

テリトリーの場合、テリトリーには多数の小さなテリトリーが含まれ、各テリトリーにはRelationshipsのコレクションが含まれ、TradeRelationshipおよびPoliticalRelationshipなどを使用してサブタイプを指定できます。

各個人と地域は別個のエンティティであり、それらを接続してネットワークを形成し、必要に応じてプロパティと新しいサブタイプを追加します。

それを最も基本的な構成要素に分解することは、将来的に完全に拡張可能にする最良の方法ですが、それを非常に複雑にする方法でもあるため、将来達成する必要があることによって異なります。

擬似コードの例:

var world = new Territory {
    Name = "World",
    Children = []
};

var china = new Territory {
    Name = "People's Republic of China",
    Parents = [world],
    Children = []
};

var eu = new Union {
    Name = "European Union",
    Members = [],
    Relationships = [],
    Purposes = [UnionPurpose.Trade, UnionPurpose.Political]
};

var euChinaRelationship = new TradeRelationship {
    Participants = [eu, china]
};

eu.Relationships.Add(euChinaRelationship);
china.Relationships.Add(euChinaRelationship);

var europe = new Territory {
    Name = "Europe",
    Parents = [world],
    Children = []
};

var britain = new Territory {
    Name = "Britain",
    Parents = [europe],
    Children = []
};

var conservatives = new Union {
    Name = "Conservative Party",
    Members = [],
    Purposes = [UnionPurpose.Political]
};

var ukPrimeMinisterRole = new Role {
    Name = "Prime Minister",
    Responsibilities = ["Leading the government", "Causing trouble :P"],
    BeganAt = "24 July 2019",
    EndedAt = "12 December 2019"
};

var bojo = new Person {
    Name = "Alexander Boris de Pfeffel Johnson",
    Roles = [ukPrimeMinisterRole]
};

conservatives.Members.Add(bojo);
britain.Government = conservatives;

europe.Children.Add(britain);
eu.Members.Add(britain);

以下のスキーマの場合:

abstract Entity {
    Name: string;
}

Person : Entity {
    DOB: DateTime;
    DOD: DateTime;
    Roles: Role[];
    Relationships: Relationship[];
}

Role {
    Name: string;
    Responsibilities: string[];
    BeganAt: DateTime;
    EndedAt: DateTime;
}

Relationship {
    Reciprocal: boolean;
    Participants: Entity[];
}

TradeRelationship : Relationship {
    Reciprocal = true;
    override Participants: Territory[];
}

Territory : Entity {
    Parents: Territory[];
    Children: Territory[];
    Relationships: Relationship[];
    Government: Union;
}

Union : Entity {
    Members: Entity[];
    Purposes: UnionPurpose[];
    Relationships: Relationship[];
}

enum UnionPurpose {
    Political,
    Military,
    Trade
}

これを計画するには長い時間がかかるかもしれませんが、世界はかなり複雑です。

0
Dom

私は「ワールド」クラスを国のコンテナではなく国のコンテナとして見ています。国のためにそれを継承することは正しく聞こえません。

国については、国名とそのフラグがほとんど変わらないことを考えると、それを列挙型として持つことができます。

Enum Country{
    ABC("abc", "abc_flag")


    private final String name;
    private final String flag;

    public String getName() {
        return name;
    }

    public String getFlag() {
        return flag;
    }

}

国の大統領は変更することができ、1対1のマッピングがあるため、このための簡単なEnumMapを使用できます。

EnumMap<Country, String> countryPresident

@Noceoが言及したように、関係タイプとマッピングは列挙型にすることができます。

enum RelationshipType {
    Friends,
    Enemies,
    Neutral
};
0
skott

ソフトウェアエンジニアリングStackexchangeへようこそ!

いつでも私は次のような要求を処理する必要があるかもしれません:誰が究極のリーダー国であるか(最大の支持者や友人などがいる)、誰が究極のリーダー国の支持者であるか、または特定のリーダー国の支持者である、ここでの秘訣は、友人や指導者の基本的な特性が同じであることです(すべての国に名前、旗、大統領があるように)。

国間の関係は輸出情報に基づいているように思えます。これは、各ノードが国であり、国AからBへの各リンクが、国Aが国Bに輸出する量の情報を運ぶ、有向グラフとしてモデル化できると思います。実装に関しては、いくつかの方法で実装できます。 、2つのマップを持つそれぞれの国のクラスのように、1つはエクスポート用、もう1つはインポート用で、キーは他の国で、値は金額です。

国間の関係ではなく単一の国(フラグなど)に関連するプロパティは、このクラスの単純なプロパティにすることができます。

この問題ステートメントの基本的なサービス要件に対処するための優れたスケルトン構造が必要です。しかし、後継者、子孫、判決の期間、大統領の家族など、将来の拡張を処理できるデザインが必要です。

拡張可能な構造を持つことは良いことですが、あまり多くするべきではありません。あなたが作成するこれらの例は、必要になった場合にリファクタリングを検討するのに十分な大きさであると思われるため、最初は検討しません。私の以前のアイデアに基づくと、将来性のある適切な選択の例は、単純な数値ではなくクラスでエクスポートとインポートの関係を表すことです。そのため、関係に情報を追加する必要が生じた場合、次のことができます。それは単に。

0
bracco23