避免使用带有返回实现策略模式的通用对象的工厂的原始类型警告

问题描述

我的目标是有一个抽象的Game类,其构造函数接受一个GameEngine,该类适用于派生的Game类。这个抽象的Game类将实现适用于所有Game实现的通用方法。您可以将GameEngine视为一种策略模式,Game会将方法委托给该模式。

因此,在创建带有Game的{​​{1}}时,我不在乎工厂返回的GameFactory什么实现。我只想确保通过适当的Game实现构造Game实现。但是,如果我只是从工厂返回原始类型GameEngine,那么我当然会收到Game警告。

此外,理想情况下,Raw use of parameterized class 'Game'方法不必传递类型,而只是基于GameFactory.createGame(settings)的某些属性来推断类型。

这是我所拥有代码的要旨:

settings

我是否滥用/误解了仿制药以实现我规定的目标?

仍然可以强制将适当的public abstract class GameEngine<T extends Game<T>> { public void doSomethingallEnginesUnderstand(T game); } public class LocalGameEngine extends GameEngine<LocalGame> { } public class RemoteGameEngine extends GameEngine<RemoteGame> { } public abstract class Game<T extends Game<T>> { private final GameEngine<T> gameEngine; protected Game(GameEngine<T> gameEngine) { this.gameEngine = gameEngine; } protected abstract T getSelf(); public final void doSomethingallEnginesUnderstand() { gameEngine.doSomethingallEnginesUnderstand(getSelf()); } } public class LocalGame extends Game<LocalGame> { public LocalGame(LocalGameEngine gameEngine) { super(gameEngine); } @Override protected LocalGame getSelf() { return this; } } public class RemoteGame extends Game<RemoteGame> { public RemoteGame(RemoteGameEngine gameEngine) { super(gameEngine); } @Override protected RemoteGame getSelf() { return this; } } public class GameFactory { // returns raw type Game public Game createGame(GameSettings settings) { if(settings.totalPlayers() > 1) { return new RemoteGame(new RemoteGameEngine()); } else { return new LocalGame(new LocalGameEngine()); } } } 实现传递给构造函数,而使Game成为泛型类?

解决方法

我觉得您过度使用了泛型,而我发现Game<T extends Game<T>>是一个过大的杀伤力。我将以这种方式设计它:

  • 使LocalGameRemoteGame扩展Game(无通用类型)。 @Override getSelf方法时使用多态性:

    public class LocalGame extends Game {
    
        public LocalGame(LocalGameEngine gameEngine) {
             super(gameEngine);
        }
    
        @Override
        protected LocalGame getSelf() {
            return this;
        }
    }
    
    public class RemoteGame extends Game {
    
         public RemoteGame(RemoteGameEngine gameEngine) {
             super(gameEngine);
         }
    
         @Override
         protected RemoteGame getSelf() {
             return this;
         }
    }
    
  • 使LocalGameEngineRemoteGameEngine扩展GameEngine(无通用类型)

    // actuyally,this abstract class can be an interface instead
    public abstract class GameEngine {
        public void doSomethingAllEnginesUnderstand(Game game) {}
    }
    
    public class LocalGameEngine extends GameEngine { }
    
    public class RemoteGameEngine extends GameEngine { }
    
  • 使Game需要GameEngine的任何子类,泛型部分只能在构造函数中使用,而无需使整个Game泛型({ {1}}。

    Game<T>
  • 整个public abstract static class Game { private final GameEngine gameEngine; protected <T extends GameEngine> Game(T gameEngine) { this.gameEngine = gameEngine; } protected abstract Game getSelf(); public final void doSomethingAllEnginesUnderstand() { gameEngine.doSomethingAllEnginesUnderstand(getSelf()); } } 变得简单了:

    GameFactory