0

サーバー側の応答の構成が不十分なため、コードを効率的に記述する方法を見つけるのに苦労しています。
私が伝えようとしている例はかなり複雑なので、実際の例を使って助けようとします。

たとえば、私がスポーツ リワード プログラムを担当していて、「トップ アスリート ページ」を作成しようとしているとします。このページには、3 つのスポーツのカテゴリから上位の男性と女性のアスリートが表示されます。野球、バスケットボール、そしてサッカー。これに対するひねりは、男性の勝者が 1 人で女性の勝者がいない、またはその逆、またはまったく勝者がいない可能性があることです。その上、女性は野球選手またはバスケットボール選手にしかなれませんが、男性は3つのいずれか、またはバスケットボール選手とフットボール選手の両方になることができます. 野球と他のものとの組み合わせはありません。最後に、男性と女性の両方のプレーヤーが存在する場合は、女性を最初に表示する必要があります。3 つのカテゴリはすべて異なる属性を持ちます。たとえば、野球の「ホームラン数 = 32」と比較して、サッカーの属性は「tds = 43」になります。

したがって、サーバーの応答で混乱が生じます。

<player>
  <baseballList>
   <baseball
    name="Adam"
    sex="male"
    HomeRuns="32"
    reward="True"/>
 </baseballList>
 <basketballList>
 <basketball
  name="John"
    sex="male"
    Points="322"
    reward="False"/>
  <basketball
   name="Sandra"
    sex="female"
    Points="332"
    reward="True"/>
  </basketballList>
  <footballList>
   <football
    name= doug
    Touchdowns= 33
    sex=male
    reward="false"/>
   </footballList>
</player>

(プレーヤー名がサッカーとバスケットボールの両方に一致し、男性の場合は、2 を組み合わせる場合です) ご覧のとおり、応答は興味のないプレーヤーを送り返しています (理由は聞かないでください)。これを除外する必要があります。また、プレーヤーが複数のスポーツを持っている場合、データを結合しません。したがって、私のアプローチでは、xml を指定された「Players」ハンドラーに送信する xml ハンドラー ファクトリがあります。次のようになります。

public class PlayerHandler implements XmlHandler {

private static PlayerHandler handler = new PlayerHandler();

private PlayerHandler() {

}

public static PlayerHandler getInstance() {
    return handler;
}

public void load(String localName, String qName, Attributes attributes) {
    if (localName != null && attributes != null) {
        if       (localName.equalsIgnoreCase("football")||localName.equalsIgnoreCase("baseball")||localName.equalsIgnoreCase("basketball")) {
Player player = new Player();

if (localName.equalsIgnoreCase("football"))
 player.category = "football"
 player.TouchDowns=attributes.getValue("TouchDowns");

else if (localName.equalsIgnoreCase("baseball"))
  player.HomeRuns=arrtibutes.getValue("HomeRun");
  player.category = "baseball"

else{
  player.category = "basketball";
  player.Points=attributes.getValue("Points");}

  player.sex=attributes.getValue("sex");
  player.name=attributes.getValue("name");   
}
playerSorter.addPlayer(player);}}

オブジェクト用に 1 つのクラス ファイルを作成しました。

public class Player implements Serializable{
  public String category;
  public String rewards;
  public String TouchDowns;
  public String Points;
  public String HomeRuns;
  public String sex;
  public String Name;   
}

指定された基準が満たされた場合にのみリストを作成する addPlayer() メソッドを使用して、「playerSorter」というクラスですべての並べ替えを行っています。次に、checkForAthleteWithInTwoSports() メソッドを呼び出す getPlayers() メソッドがあります (バスケットボールとサッカーの両方に出場している選手がいるかどうかを調べます) よりも、ソートされたリストを返し、女性が最初に表示されます (該当する場合)。メイン ページから getPlayers() メソッドが呼び出され、アダプタ クラスに設定されます。より良いxml応答は、このようなタスクをはるかに簡単にしますが、そうではなく、これを行うためのより効率的な方法を見つけたいと思っています. 誰かがこれに取り組むための良いデザインパターンを見つけるのを手伝ってくれたり、アドバイスをくれたりしたら、本当に感謝しています.

4

1 に答える 1

1

問題を解決するための特定の設計パターンがここにあるかどうかはわかりません。私の見解では、ドメイン モデルを表すために主に文字列を使用しているため、モデルにはいくつかの抽象化が欠けています。この種のことは、オブジェクトで物事を表現することを目的とする OOP に反するため、オブジェクトに動作を委譲できます。例として、次のコードを考えてみましょう。

if (localName.equalsIgnoreCase("football"))
 player.category = "football"
 player.TouchDowns=attributes.getValue("TouchDowns");

else if (localName.equalsIgnoreCase("baseball"))
  player.HomeRuns=arrtibutes.getValue("HomeRun");
  player.category = "baseball"

else{
  player.category = "basketball";
  player.Points=attributes.getValue("Points");}

FootballPerformanceこれは、各スポーツ パフォーマンスを表す 3 つのクラス ( 、BaseballPerformanceおよび)を作成することで簡単に改善できますBasketballPerformance。各クラスは、それぞれに適用される属性を保持します。それができたら、XML ノードの読み取りをクラス自体に委譲できます (ここでご容赦ください。私は Java プログラマーではないので、疑似コードを使用します)。

public class BasketballPerformance extends SportPerformance {
  private Integer points;

  //Constructor
  public BasketballPerformance(Attributes attributes)
  {
     this.points = attributes.getValue("Points");
  }

  public getPoints() 
  {
    return this.points;
  }
}

クラスFootballPerformanceとクラスBaseballPerformanceは非常に似ており、一連の属性を取得し、それらに基づいて自身を設定します。同じ考え方をPlayerクラスに適用することで、オブジェクトの作成を次のように分散化できます。

public Sport createSportPerformanceInstance(String name, Attributes attributes) 
{
if (name.equalsIgnoreCase("football"))
    {return new BasketballPerformance(attributes);}
else 
if (name.equalsIgnoreCase("baseball"))
    {return new BaseballPerformance(attributes);}
...
}


public void load(String localName, String qName, Attributes attributes) 
{
SportPerformance sportPerformance = this.createSportPerformanceInstance(localName, attributes);
Player player = new Player(Attributes attributes);
player.sportPerformance = sportPerformance;
}

良い副作用として、後で新しいスポーツを追加する場合、createSportPerformanceInstance単一の大きなメソッドに飛び込むのではなく、新しいクラスを実装してメソッドに新しいブランチを追加するだけでよいことに注意してください。

Playerコードは、1 つだけではなくパフォーマンスのコレクションを保持しPlayerHandler、新しいプレーヤーを作成する前にプレーヤーの存在をチェックすることで、後で改善できます。新しいメソッドは次のようになります。

public void load(String localName, String qName, Attributes attributes) 
{
SportPerformance sportPerformance = this.createSportPerformanceInstance(localName, attributes);
String playerName=attributes.getValue("name");
Player player;
  if (!this.playerExists(playerName)) 
  {
     player = new Player(attributes);
  } else 
     {
       player = this.getPlayerByName(playerName);
     }
  player.addPerformance(sportPerformance);
}

良い点は、インターフェイスを実装することで、並べ替え順序をプレーヤー自身に委譲できるようになったことComparableです。モデルは、モデル化しようとしている現実によりよく適合します。これは、異なるスポーツで異なるパフォーマンスを持つ 1 人のプレーヤーがいるからです。

そうは言っても、創造的な設計パターン、特にBuilderFactory、およびAbstract Factoryにインスピレーションを見つけることができます。

HTH

于 2013-02-14T20:58:44.737 に答える