我在Stack Overflow中搜索了这个subjet arround。我找到了以下解决方案:
Explanation of Visitor Pattern
现在,我的情况与此相似。但是,我需要避免使用" instanceOf
"。
我的游戏中包含名为MonkeyTower
,CannonTower
,OctoTower
的塔...而其他一些类使用instanceOf
进行比较。
以下是使用instanceOf
:
BloonsTower.java
public void mousePressed(Point p) {
Tower t = null;
selectedTower = towerInfo[ insertTowerIdx ].getTower();
if( selectedTower instanceof MonkeyTower )
t = tCreator.createMonkey();
else if( selectedTower instanceof OctoTower )
t = tCreator.createOctogonal();
else if( selectedTower instanceof CannonTower )
t = tCreator.createCannon();
else if( selectedTower instanceof MortarTower )
t = tCreator.createMortar();
setMoney( money - towerInfo[ insertTowerIdx ].getPrice() );
t.setPosition( p );
world.addTower(t);
currentState = new SelectTowerState();
}
ManipulatorCreator.java
if( t instanceof MonkeyTower )
return null;
else if( t instanceof OctoTower )
return new OctoManipulator( t );
else if( t instanceof CannonTower )
return null;
else if( t instanceof MortarTower )
return new MortarManipulator( (MortarTower)t );
return man;
GameWriter:
public void saveFile( File file, int round, int money, int lives, World m ) throws IOException {
PrintWriter out = new PrintWriter( new BufferedWriter( new FileWriter( file) ) );
out.println( round );
out.println( money );
out.println( lives );
Tower []torres = m.getTowers();
out.println( torres.length ); // escrever o nº de torres
for( Tower t : torres ){
Point p = t.getComponent().getPosicao();
// escrever a posição e o tipo de torre
out.print(p.x+"\t" + p.y+"\t" );
if( t instanceof MonkeyTower )
out.println( "macaco" );
else if( t instanceof OctoTower )
out.println( "octo" );
else if( t instanceof CannonTower )
out.println( "canhao" );
else if( t instanceof MortarTower )
out.println( "morteiro" );
}
out.close();
}
我创建的是访问每个塔的访客班级:
public class TowerVisitor implements Visitor{
public void visit(MonkeyTower monkey) {
// TODO Auto-generated method stub
}
public void visit(CannonTower cannon) {
// TODO Auto-generated method stub
}
public void visit(MortarTower mortar) {
// TODO Auto-generated method stub
}
public void visit(OctoTower octo) {
// TODO Auto-generated method stub
}
}
而且,在我创建的每个塔中都有一个方法accept
可以自行返回
现在,我已经陷入了方法visit
中的内容,以及如何使用该模式切换所有instanceOf
。
感谢。
答案 0 :(得分:2)
您应该使用核心Object Oriented Programming模式,即继承,而不是访问者模式。您有几种不同类型的塔,以及类似的操作(创建,操作,toString等),这些操作应针对每种类型的塔进行不同的实施。继承的典型例子。
public abstract class Tower {
public abstract Tower create();
public abstract Manipulator manipulate();
}
---
public class MortarTower extends Tower {
@Override
public MortarTower create() {
return new MortarTower();
}
@Override
public MortarManipulator manipulate() {
return new MortarManipulator(this);
}
@Override
public String toString() {
return "morteiro";
}
}
---
public void mousePressed(Point p) {
selectedTower = towerInfo[insertTowerIdx].getTower();
setMoney(money - towerInfo[insertTowerIdx].getPrice());
Tower t = selectedTower.create();
t.setPosition(p);
world.addTower(t);
currentState = new SelectTowerState();
}
等等。
答案 1 :(得分:0)
您必须使用FactoryMethod
或AbstractFactory
模式(如果您想创建Tower的ManipulatorDactory独立项)而不是访问者。
有关详细信息,请查看此Factory Method和Abstract Facotry。
一些示例代码:
public class FactoryMethodDemo{
public FactoryMethodDemo(){
}
public Tower getTower(String type){
if ( type.equalsIgnoreCase("monkey")){
return new MonkeyTower();
}else if ( type.equalsIgnoreCase("octo")){
return new OctoTower();
}else if ( type.equalsIgnoreCase("canon")){
return new CannonTower();
}else if ( type.equalsIgnoreCase("mortal")){
return new MortarTower();
}
return null;
}
public static void main(String args[]){
FactoryMethodDemo factory = new FactoryMethodDemo();
Tower tower = factory.getTower(args[0]);
System.out.println("Tower:"+tower);
}
}
abstract class Tower{
Manipulator manipulator = null;
public Tower(){
}
public String toString(){
return this.getClass().getSimpleName()+":manipulator:"+manipulator;
}
public Manipulator getManipulator(){
return manipulator;
}
}
class MonkeyTower extends Tower{
public MonkeyTower(){
}
}
class OctoTower extends Tower{
public OctoTower(){
manipulator = new OctoManipulator();
}
}
class CannonTower extends Tower{
public CannonTower(){
}
}
class MortarTower extends Tower{
public MortarTower(){
manipulator = new MortarManipulator();
}
}
class Manipulator{
}
class OctoManipulator extends Manipulator{
}
class MortarManipulator extends Manipulator{
}
输出:
D:\Study\Java>java FactoryMethodDemo monkey
Tower:MonkeyTower:manipulator:null
D:\Study\Java>java FactoryMethodDemo mortal
Tower:MortarTower:manipulator:MortarManipulator@4187a8e0
D:\Study\Java>java FactoryMethodDemo octo
Tower:OctoTower:manipulator:OctoManipulator@46fb3d6
D:\Study\Java>java FactoryMethodDemo canon
Tower:CannonTower:manipulator:null
相关的SE问题:
Factory Pattern. When to use factory methods?
What is the basic difference between the Factory and Abstract Factory Patterns?