Java 策略模式:调用方作为属性的策略?
我使用策略模式,因此我有我的Java 策略模式:调用方作为属性的策略?,java,design-patterns,circular-dependency,strategy-pattern,Java,Design Patterns,Circular Dependency,Strategy Pattern,我使用策略模式,因此我有我的策略抽象类、我的具体策略类和我的播放器类。在我的ConcreteStrategy中,我必须访问我的Player对象 知道Player有一个Strategy,而且正如我的老师告诉我的,我不能在Strategy课上包括Player,如何访问Player而不将其包含在Strategy中?您可以将Player作为ConcreteStrategy的实例变量,例如 class PlayerStratey implements Strategy { Player playe
策略
抽象类、我的具体策略
类和我的播放器
类。在我的ConcreteStrategy
中,我必须访问我的Player
对象
知道
Player
有一个Strategy
,而且正如我的老师告诉我的,我不能在Strategy
课上包括Player
,如何访问Player
而不将其包含在Strategy
中?您可以将Player
作为ConcreteStrategy
的实例变量,例如
class PlayerStratey implements Strategy {
Player player;
public PlayerStrategy(Player pl) {
player = pl;
}
@Override
public void executeStrategy() {
System.out.printf("Player %s is executing his strategy!%n", player);
}
}
编辑:
至于“一个玩家有一个策略,而不是相反”,这对我来说几乎是一个实现细节。下面是一个带有内部类的PlayerStrategy
:
class Player {
Strategy strategy = new PlayerStrategy();
// now the player "has a" strategy.
public Strategy getStrategy() {
return strategy();
}
class PlayerStrategy implements Strategy {
@Override
public void executeStrategy() {
System.out.printf("Player %s is executing his strategy!%n", Player.this);
}
}
}
至于这是否有效,它确实取决于
策略的确切用途。您需要为我们提供策略所代表的实际界面。因为玩家做了一些需要策略的事情,您可以将玩家
实例传递给策略方法
您应该通过strategy接口在您的player类中注入具体的策略。然后,该策略将玩家作为参数:
1-接口:
public interface Strategy {
public void apply(Player player);
}
2-具体战略:
public class StrategyOne implements Strategy{
public void apply(Player player) {
System.out.println(this.getClass().getSimpleName() +" on " + player.getName());
}
public class StrategyTwo implements Strategy {
public void apply(Player player) {
System.out.println(this.getClass().getSimpleName() +" on " + player.getName());
}
}
3-上下文(这里是您的玩家类):
5-产出:
玩家玩家向导对玩家向导应用策略一
玩家玩家向导在玩家2上应用策略1
playerTwo对playerTwo应用策略二
游戏者游戏者对游戏者应用策略二
然后,您让您的玩家将分配给他的策略应用到该策略所针对的玩家上。您可以为玩家
类创建一个抽象(有关更多信息,请阅读依赖项反转),并将其作为参数传递给策略
抽象类。这样,细节保持解耦
如果您确实需要避免循环依赖,您可以尝试从Player
类中提取您需要在策略中使用的任何内容到一个新类,然后通过Strategy
类上的方法(或构造函数)将其作为参数传递 在Strategy
类/接口中的抽象runStrategy(Player p)
方法怎么样?这或使用泛型类型在策略
类中不包含单词Player
。请添加一些类UML类图,如果没有编码,请添加一些代码片段。这会有帮助。@f1sh,请不要在评论中回答问题。在下面添加一个或多个答案。它不应该是另一种方式吗?我的意思是一个玩家有策略,而不是策略有玩家。@BraulioLopez这是我的问题。。。这样做真的合法吗?@KevinV根据你的老师,这不是:“正如我的老师告诉我的,我不能在策略课上包括玩家”@KevinV,你不会在策略课上包括玩家,所以实现了松散耦合,这就是模式的要点。如果你听老师的解释,他可能会弄错;)至于谁拥有什么(玩家/策略),这几乎是一个实现细节。我可以稍后提供一个替代方案。这并不能真正回答我的问题…从我对你的问题的理解来看,你想要使用一种策略模式,玩家在其中使用给定的策略。在这种情况下,玩家取决于所选择的策略。你的意思是你试图让策略依赖于玩家吗?简言之,我对“我如何才能访问玩家而不将其包括在我的策略中?”的回答是你不这样做。玩家访问你暗示的策略:“知道玩家有策略”@KevinV好的,我想我现在明白你的意思了=)看看更新
public class StrategyOne implements Strategy{
public void apply(Player player) {
System.out.println(this.getClass().getSimpleName() +" on " + player.getName());
}
public class StrategyTwo implements Strategy {
public void apply(Player player) {
System.out.println(this.getClass().getSimpleName() +" on " + player.getName());
}
}
public class Player {
private Strategy strategy;
private String name;
public String getName(){
return name;
}
public Player(Strategy strategy, String name){// construct using your chosen strategy
this.strategy = strategy;
this.name = name;
}
public void executeStrategy(Player player){
System.out.print("Player "+ this.getName()+ " applies ");
strategy.apply(player);
}
}
public static void main(String[] args) {
Player playerOne = new Player(new StrategyOne(), "playerOne");
Player playerTwo = new Player(new StrategyTwo(), "playerTwo");
playerOne.executeStrategy(playerOne);
playerOne.executeStrategy(playerTwo);
playerTwo.executeStrategy(playerTwo);
playerTwo.executeStrategy(playerOne);
}