好的,由于服务器端响应配置不佳,我无法找到编写代码的有效方法 由于我试图传达的例子相当复杂,我将尝试使用现实生活中的例子来帮助。
所以我要说我负责体育奖励计划,我正试图创建一个“顶级运动员页面”。该页面将显示三种运动类别中的顶级男女运动员;棒球,篮球和足球。对此的一个转折是,可能有一名男性获胜者而没有女性获胜者,反之亦然,或根本没有获胜者。最重要的是,女性只能是棒球运动员或篮球运动员,而男性可以是篮球运动员和足球运动员三者之一。棒球与其他任何东西都没有组合。最后,如果男性和女性玩家都存在,则必须首先显示女性。所有三个类别都具有不同的属性,例如,与棒球“Homeruns = 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>
(如果球员名称与足球和篮球相匹配,那么男性就是你将两者结合起来的时候) 正如你所看到的那样,响应是发送回不感兴趣的玩家(不要问为什么),我必须过滤掉,以及当玩家有多项运动时它不会合并数据。 所以对于我的方法,我有一个xml处理程序工厂,它将xml发送到指定的“Players”处理程序。这看起来像是:
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);}}
我为对象创建了一个类文件:
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;
}
我正在使用名为“playerSorter”的类进行所有排序,其中addPlayer()方法仅在满足指定条件时填充列表,然后我有一个getPlayers()方法调用我的checkForAthleteWithInTwoSports()方法(通过并看看是否是篮球和足球中的球员)而不是返回排序列表,其中女性首先显示(如果适用)。从我的主页面调用getPlayers()方法,然后将其设置为适配器类。 一个更好的xml响应会使这样的任务更容易,但事实并非如此,我想找到一种更有效的方法来做到这一点。如果有人能帮助我找到一个好的设计模式来解决这个问题,或者我会非常感激它的任何建议。(此外,这些类别的属性不仅仅是“HomeRuns,point或touchdown”,只是为了简化。)
答案 0 :(得分: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
,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
方法中添加一个新的分支,而不是潜入一个单一的大方法。 / p>
稍后可以通过让Player
保持一组演出而不仅仅是一个并且在创建新玩家之前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
界面将排序顺序委托给玩家自己,并且模型也更适合你想要建模的现实,因为你有一个玩家拥有不同运动的不同表现。
话虽如此,您可能会在Creational design patterns中找到一些灵感,特别是Builder,Factory和Abstract Factory。
HTH