【发布时间】:2019-02-19 14:04:56
【问题描述】:
考虑一个制造太空船的太空船工厂。当它生产一艘飞船时,它会更新它所居住的星球上的当前资源,并更新飞船存储的状态。因此,宇宙飞船工厂是两个观察者的出版商。即星球上的资源和宇宙飞船的储存。 .使用观察者设计模式时,观察者必须实现发布者可以在发布者想要发布时调用的更新方法。发布者将其观察者列表存储在 Arraylist 中,并通过迭代每个观察者来调用更新,如下所示:
public class SpaceShipFactory implements Publisher{
private ArrayList<Observer> observers;
private int mmRequired;
private int eRequired;
private int cRequired;
private int dRequired;
private int vRequired;
public void notifyObservers() {
for(Observer obs : observers)
obs.update(this.mmRequired, this.eRequired, this.cRequired , this.dRequired, this.vRequired );
}
}
问题是,我们要更新的星球资源存储和宇宙飞船存储是不同的。即,一个减少资源的数量,另一个增加宇宙飞船的数量。因此他们的更新方法可能有不同的签名。所以我们不能对两个观察者使用相同的更新方法。因此我们需要一一调用更新,如下伪代码所示:
public void notifyObservers() {
for(Observer obs : observers)
if(obs.equals(PlanetResourceStorage)
obs.update(this.mmRequired, this.eRequired, this.cRequired , this.dRequired, this.vRequired );
else if (obs.equals(SpaceShipStorage)
obs.update(numberOfManifacturedLightFight, numberOfManifacturedHeavyFighter, numberOfFacturedStarDestoyer,NumberOfFacturedBattleShips,NumberofFacturedDeathStars)
}
}
我想知道我们是否应该这样做?也许我们应该创建一个更新方法,它包含发布者想要发布的所有可能值的参数,并且观察者可以使用它们,即使他们不需要知道更新方法的所有参数。例如:
public class SpaceShipFactory implements Publisher{
private ArrayList<Observer> observers;
private int metalRequired;
private int energyRequired;
private int carbonRequired;
private int deuteriumRequired;
private int vibraumRequired;
private int numberOfStarDestoyerBuilt;
public void notifyObservers() {
for(Observer obs : observers)
obs.update(this.metalRequired, this.energyRequired, this.carbonRequired , this.deuteriumRequired, this.vibriumRequired, this.numberOfStarDestoyerBuilt );
}
}
因此在行星资源更新的实际实现中,关于建造船只数量的参数被忽略了。我还发现输入给定更新方法的所有参数非常乏味,我想知道是否有更简单的方法。
例如,行星资源的更新实现是:
public class PlanetResources implements Observer {
//Amount of resources of each type
private int metallicMicrolattice;
private int energy;
private int carbyne;
private int deuterium;
private int vibranium;
// The factories to produce the Resources
private Publisher aMetallicMicrolatticeFactory;
private Publisher aSolarPlant;
private Publisher aCarbyneFactory;
private Publisher aHeavyWaterExtractor;
private Publisher aVibraniumMine;
// The Factory to produce mission units
private Publisher aShipFactory;
public void update(int mmAmount, int pEAmount, int pCAmount, int pDAmount,
int pVAmount, int numberOfManifacturedLightFight, int numberOfManifacturedHeavyFighter, int numberOfFacturedStarDestoyer,int numberOfFacturedBattleShips,int numberofFacturedDeathStars) {
this.metallicMicrolattice = this.metallicMicrolattice + mmAmount;
this.setCarbyne(this.getCarbyne()+pCAmount);
this.deuterium = this.deuterium + pDAmount;
this.energy = this.getEnergy() + pEAmount;
this.vibranium = this.vibranium + pVAmount;
// TODO Auto-generated method stub
}
}
飞船存储的更新方法是:
public class StationedShip implements Observer
{
private ArrayList<SpaceShip> lightFighters;
private ArrayList<SpaceShip> heavyFighters;
private ArrayList<SpaceShip> cruisers;
private ArrayList<SpaceShip> battleShips;
private ArrayList<SpaceShip> bombers;
private ArrayList<SpaceShip> battleCuisers;
private ArrayList<SpaceShip> starDestoyers;
private ArrayList<SpaceShip> superStarDestoyers;
private ArrayList<SpaceShip> deathStars;
private ArrayList<SpaceShip> espoinageProbes;
private ArrayList<SpaceShip> IonShooters;
private ArrayList<SpaceShip> smallTransforters;
private ArrayList<SpaceShip> largeTransporters;
private ArrayList<SpaceShip> recyclers;
private ArrayList<SpaceShip> colonialShips;
@Override
public void update(int planetMetallicMicrolattice, int planetEnergy, int planetCarbyne, int planetDeuterium,
int planetVibranium,numberOfManifacturedLightFight, int numberOfManifacturedHeavyFighter, int numberOfFacturedStarDestoyer,int numberOfFacturedBattleShips,int numberofFacturedDeathStars) {
//code to add ships to the arraylist of ships
}
}
【问题讨论】:
-
更新方法很复杂,一个函数里有这么多参数也不行。它增加了耦合性和复杂性。
标签: java