如何使用工厂模式重构Java代码?

如何使用工厂模式重构Java代码?,java,refactoring,Java,Refactoring,我想使用工厂模式创建一个新方法addShip,它在运行时确定要初始化的Ship类型 while(!g.allShipsPlaced()) { NumberGenerator gen = new NumberGenerator(); int x = gen.rand(10); int y = gen.rand(10); int o = gen.rand(1); x = gen.rand(10);

我想使用工厂模式创建一个新方法addShip,它在运行时确定要初始化的Ship类型

    while(!g.allShipsPlaced())
    {
        NumberGenerator gen = new NumberGenerator();
        int x = gen.rand(10);
        int y = gen.rand(10);
        int o = gen.rand(1);

        x = gen.rand(10);
        y = gen.rand(10);
        o = gen.rand(2);        
        System.out.println("vertical sub x = " + x + "\n");
        System.out.println("vertical sub y = " + y + "\n");
        g.addSub(x,y, o);

        x = gen.rand(10);
        y = gen.rand(10);
        o = gen.rand(2);        
        System.out.println("vertical battle x = " + x + "\n");
        System.out.println("vertical battle y = " + y + "\n");
        g.addBattle(x,y, o);    

        x = gen.rand(10);
        y = gen.rand(10);
        o = gen.rand(2);                
        System.out.println("vertical air x = " + x + "\n");
        System.out.println("vertical air y = " + y + "\n");
        g.addAir(x,y, o);

        x = gen.rand(10);
        y = gen.rand(10);
        o = gen.rand(2);                
        System.out.println("vertical mine x = " + x + "\n");
        System.out.println("vertical mine y = " + y + "\n");
        g.addMine(x,y, o);

        x = gen.rand(10);
        y = gen.rand(10);
        o = gen.rand(2);
        System.out.println("horizontal dest x = " + x + "\n");
        System.out.println("horizontal dest y = " + y + "\n");
        g.addDest(x,y, o);

    }

    System.out.println("agent grid");
    System.out.println(g.toString());

    return g;
}
比如说,

    x = gen.rand(10); 
    y = gen.rand(10);
    o = gen.rand(2);        
    System.out.println("vertical sub x = " + x + "\n");
    System.out.println("vertical sub y = " + y + "\n");
    g.addShip(x, y, o, "Submarine");
    /* x,y are the coordinates to define where to place the ship and o
    defines how to place the ship (horizontal or vertical) */
从字符串类型可以看出应该初始化哪种类型的船,这意味着您需要调用addSubside方法


这里是原始代码的链接。您可以在代理类中找到此代码。非常感谢您的帮助。

如果您想在代码中使用Factory模式,您应该执行以下操作:

  • 从抽象类
    Ship
    扩展所有
    Ship
  • 创建一个抽象类
    AbstractShipFactory
    ,它有一个方法
    shipCreateShip(int,int,int)
  • 创建具体的类,如
    BattleShipFactory
    DestShipFactory
    等,这些类扩展
    AbstractShipFactory
    并覆盖
    createShip
  • 在代码中使用工厂:

    while(!g.allShipsPlaced())
    {
        NumberGenerator gen = new NumberGenerator();
        AbstractShipFactory battleFactory = new BattleShipFactory();
        ...
        g.addShip(battleFactory.createShip(gen.rand(), gen.rand(), gen.rand()));
        ...
    }
    

  • 这叫做工厂法。请注意,您必须为每种新产品类型创建新工厂

    使用
    枚举
    开关
    。是什么阻止您创建这样的方法?正如您所说,您可以传递一个字符串来确定类型。在内部,在传递的类型上使用if-else/switch,在传递值的同时调用相应的方法。例如,Grid类对于首先需要通用化的每艘船都有大量重复的代码。这是一项艰巨的任务,如果不真正为您重构整个代码,IMO将无法回答。最好的方法是识别重复的代码并开始推广它。只有这样,你才能想到工厂模式。@bot你能给我一些关于如何在网格类中泛化代码的建议吗?有什么模式或者你有更好的建议吗?@Claire现在不用担心模式。只需观察网格类并识别重复的代码。然后考虑将此代码移动到一个新类中,以便您可以从应用程序中的任何位置调用它。这可以通过继承或组合来实现。看看OP发布的整个代码。还有很多工作要做。在您考虑创建工厂之前,还有很多代码需要推广。我应该如何以及在何处实现addShip方法(可能在Grid类中)`public Ship addShip(int i,int j,int s,String type){Ship Ship Ship=factory.createShip(i,j,s,type);return Ship;}`我想到了这一点,但我在扩展AbstractShipFactory的具体类中也遇到了一个问题:`public class BattleFactory extensed AbstractShipFactory{@Override public Ship createShip(int x,int y,int o,String type){Ship Ship;addBattle(x,y,o);//我不知道如何实现这个方法return Ship;}`你不应该在
    addShip
    参数中指定
    String type
    。你的
    addShip
    方法应该有类似
    public void addShip(Ship)的签名
    ,所有船舶创建必须在混凝土工厂中进行。从代码中删除所有
    字符串类型
    ,并使用多态性。