Javaコードを乾燥させる最良の方法は何ですか?パラメータ用に異なるオブジェクトを使用してプライベートメソッドを作成しますか?

イリ

私はRTSゲームを作成していますが、その機能の1つは、さまざまな種類の建物を構築することです。多くの繰り返しを見つけて、ヘルパーメソッドでそれを抽出することを考えていましたが、問題は、すべての建物が異なるオブジェクトであり、メインの建物クラスの一部のプロパティを継承していることです。

構築方法は次のようになります。

  public static void buildDockyard(Base base) {
    if (Validator.checkForBuilding(base, "Dockyard")) {
       throw new IllegalStateException("Dockyard is already build");
     }
    Dockyard dockyard = new Dockyard("Dockyard");
    int requiredPower = dockyard.requiredResource("power");
    int requiredStardust = dockyard.requiredResource("stardust");
    int requiredPopulation = dockyard.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    dockyard.setCompleteTime(dockyard.requiredResource("time"));
    base.getBuildings().add(dockyard);
  }

  public static void buildHotel(Base base) {
    if (Validator.checkForBuilding(base, "Space Hotel")) {
      throw new IllegalStateException("Space Hotel is already build");
    }

    SpaceHotel spaceHotel = new SpaceHotel("Space Hotel");
    int requiredPower = spaceHotel.requiredResource("power");
    int requiredStardust = spaceHotel.requiredResource("stardust");
    int requiredPopulation = spaceHotel.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    spaceHotel.setCompleteTime(spaceHotel.requiredResource("time"));
    base.getBuildings().add(spaceHotel);

    base.setCapacity(base.getCapacity() + spaceHotel.getCapacity());
  }

私はこのようにリファクタリングすることを考えていました:ヘルパーメソッド

private static void construct(Building building, Base base) {
    int requiredPower = building.requiredResource("power");
    int requiredStardust = building.requiredResource("stardust");
    int requiredPopulation = building.requiredResource("population");

    Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
    updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
    building.setCompleteTime(building.requiredResource("time"));
  }

狙った結果

public static void buildDockyard(Base base) {
        if (Validator.checkForBuilding(base, "Dockyard")) {
           throw new IllegalStateException("Dockyard is already build");
         }
        Dockyard dockyard = new Dockyard("Dockyard");
        construct(dockyar, base);
        base.getBuildings().add(dockyard);
      }

問題は、各建物に固有のプロパティとリソース要件があり、メインのBuildingクラスがそれらを認識していないため、ヘルパーメソッドのパラメーターとして使用できないことです。

これはすべて、Baseクラスの静的ヘルパークラスで発生しています。

このコードをどのようにリファクタリングしますか?前もって感謝します !

ソリン

ゲームを作成するときにJavaでDRYを実行する最良の方法は、ゲームを明確に理解し、用語を理解することです。あなたはどの読めば現代のマニュアルボードゲームを、あなたはすぐに彼らは次のように、1つの概念のために正確に一つの単語を使用することがわかりますTurnRoundBuildingPlayerResourceこれにより、大まかな構造を形成できます。AにBuildingは一定コストがかかりますResourceプレーヤーが十分でない場合は、Resource「ベスパインガスがもっと必要です」などと伝えます。画像が鮮明であるほど、Javaが乾燥し、コードに必要なクラスを簡単に作成できます。

パラメーター

あなたがこのようなものになってしまう場合:

public static void someFunction(Base base, Object param1, Object param2)
public static void someOtherFunc(Base base, Object paramA, Object paramB)
...

次に、これは、おそらく両方の関数がBaseクラスの一部である必要があるという強力なヒントです

列挙型

値のセットが限られている場合、Java列挙型はそれらを表すのに最適です。たとえば、リソースシステム:

public enum Resource {
    POWER, STARDUST, POPULATION
}

これで、「スターダスト」、「スターダスト」と呼んだのか、「スターダスト」のようなリソースがまだあるのかを覚えておく必要はありません。代わりに使用できますint requiredPower = building.requiredResource(Resource.POWER);

ポリモーフィズム

我々は2つのクラスを持っている、としましょうBuildingStarHotelで、StarHotel特定の種類であることBuilding抽象クラスを持つBuildingことで、次のような特定の方法でいくつかの一般的なメカニズムを処理できます。

public abstract class Building {
    private ... cost;
    private ... requirements;
    private ... 

    // Std-Getter and Setter methods
    public ... getCost() { return this.cost; }

}

すべての建物には、コスト、要件、その他の重要な変数があります。しかし、これらの汎用変数を取得して基本クラスに設定するという標準的な作業はすべて処理しました。基本クラスから、他のより具体的な建物を拡張できます。extendsキーワードのおかげで、繰り返しのゲッターとセッターでクラスをStarHotel埋めることなくオブジェクトのコストを取得できますStarHotel

public class StarHotel extends Building {
    // Getter, Setter inherited from Building class
}

インターフェイス

Javaインターフェースを使用すると、メソッドを定義するインターフェースを定義できます。素人の言葉で言えば:インターフェースが実装を提供しない限り、インターフェースを実装するすべてのクラスがメソッドを実装する必要があるため、これは便利ですdefault

public interface ResourceProvider {
    void provideResourceFor(Base base); // A Resource Provider provides Resource for a base.
}

このインターフェースを使用して、一部のクラスが実装ResourceProviderする場合、一部のBaseオブジェクトに提供するリソースの方法と内容を指定する必要があることを定義しました私たちのインターフェースは、どのリソース、どのベース、そして何provideResourceForを意味するかさえ気にしませんが、何かが実装されResourceProviderている限り、それは機能を提供しなければなりません

すべてをまとめる

列挙型、インターフェイス、およびポリモーフィズムを組み合わせて、StarHotel拡張Buildingおよび実装するクラスを作成し、ResourceProvider8つのFoodユニットと2つのHappinessユニットをBaseに提供できるようになりました

public class StarHotel extends Building implements ResourceProvider
    public void provideResourceFor(Base base) {
        base.addResource(Resource.FOOD, 8);
        base.addResource(Resource.HAPPINESS, 2);
    }
}

それは理解するのに大変かもしれませんが、うまくいけば、それはあなたにさらに見るべき良い方向性を与えるでしょう。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ