首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态行为如何在Java中改变状态?

动态行为如何在Java中改变状态?
EN

Stack Overflow用户
提问于 2016-05-04 16:33:08
回答 4查看 1.7K关注 0票数 4

我正在一个简单的类似Zork的环境中与我的Java类的学生一起工作,在这个环境中,玩家会从一个位置到另一个位置遇到项目。这些项目应该有动态行为,这样一本书就可以读到你烧了它,或者鸭子可以飞到它飞得太久,累坏了。诸若此类。

学生们和我探索了基本的策略模式(我正在适应“头第一”设计模式,而忽略了样板):

代码语言:javascript
复制
public class Duck {

   String name;
   Int health;
   FlyBehavior flyBehavior;

   public void performFly() {
      flyBehavior.fly();
   }

   public void setFlyBehavior(FlyBehavior f) {
      flyBehavior = f;
   }
}

public interface FlyBehavior {
   public void fly();
}

public class FlyGracefully implements FlyBehavior {
   public void fly() {
      System.out.println("I fly so gracefully!");
   }
}

public class TooTiredToFly implements FlyBehavior {
   public void fly() {
      System.out.println("I'm too tired to fly.");
   }
}

省去了main方法的细节,这让我们可以将不同的飞行行为转换到我们的鸭子身上。这很容易,因为它返回一个空并打印到sysout。

但如果我们需要这种行为来与鸭子的状态互动呢?我们可以这么说:

  • 当鸭子累得飞不起来时,它的名字就改为“精疲力竭的鸭子”。其他行为也可以改变它的名称。
  • 当鸭子受到攻击(即将发生),它的健康就会下降。当它的健康度太低时,它的flyBehavior切换到TooTiredToFly行为。

但我假设动态行为,至少在这种模式下,无法访问他们所处的对象的状态。

是否有创建动态行为的通用策略,这些行为与所处对象的状态交互?我想教一些可以理解的东西,所以把自己放在中级高中程序员的脑子里。

EN

回答 4

Stack Overflow用户

发布于 2016-05-04 16:46:14

根据我上面的评论,这些内容.

代码语言:javascript
复制
// Creating an interface for flyable things e.g. Duck, Airplane, etc.
// You don't have to do this. You could just pass your Duck
// object instead and call its methods directly.
public interface Flyable {
    void performFly();
}

public class Duck implements Flyable {
    // All your Duck stuff as above in here.
}

public abstract class FlyBehavior {
    private Flyable parent;

    public FlyBehavior(Flyable parent) {
        this.parent = parent;
    }

    public abstract void fly();

    protected Flyable getParent() {
        return this.parent;
    }
}

public class FlyGracefullyBehavior extends FlyBehavior {
    public FlyGracefullyBehavior(Flyable parent) {
        super(parent);
    }

    @Override
    public void fly() {
        // Now you can get access to the original parent here.
        Flyable parent = this.getParent();
    }
}

public class TooTiredToFlyBehavior extends FlyBehavior {
    public TooTiredToFlyBehavior(Flyable parent) {
        super(parent);
    }

    @Override
    public void fly() {
        // Now you can get access to the original parent here.
        Flyable parent = this.getParent();
    }
}

或者,您可以简单地将父状态传递到FlyBehavior类的fly方法中,即behavior.fly(state); --这取决于您:)

票数 2
EN

Stack Overflow用户

发布于 2016-05-04 17:10:58

下面是您所描述的使用策略模式的基本示例。我试图保持它尽可能简单,所以一些最佳实践被忽略了(例如声明常量),这样您就可以专注于策略设计,而不会被信息淹没。

代码语言:javascript
复制
public interface Animal
{
  public String getName();

  public void attacked(int health);
}

public interface Bird extends Animal
{
  public void fly();
}

public class Duck implements Bird
{
  private Int health = 100;
  private DuckBehavior state = new HealthyDuck();

  public getName()
  {
    return state.getName();
  }

  public void fly()
  {
    state.fly();
  }

  public void attacked(int hitpoints)
  {
    health = health - hitpoints;

    if (health < 50) {
      state = new HurtDuck();
    } else if (health < 0) {
      state = new DeadDuck();
    }
  }
}

interface DuckBehavior
{
  public getName();

  public void fly();
}

public class HealthyDuck implements DuckBehavior
{
  public getName()
  {
    return "Healthy Duck";
  }

  public void fly()
  {
     System.out.println("I fly so gracefully!");
  }
}

public class HurtDuck implements DuckBehavior
{
  public getName()
  {
    return "Hurt Duck";
  }

  public void fly()
  {
     System.out.println("I'm too tired to fly.");
  }
}

public class DeadDuck implements DuckBehavior
{
  public getName()
  {
    return "Dead Duck";
  }

  public void fly()
  {
     System.out.println("I'm too dead to fly.");
  }
}
票数 2
EN

Stack Overflow用户

发布于 2016-05-04 16:49:04

让我们在设计中添加一个新接口,如下所示:Flyable.java

代码语言:javascript
复制
public interface Flyable{
   public void modifyTargetName(String newName);
}

让我们修改FlyBehavior.java及其实现类。让我们在其中定义一个方法public void setFlyableTarget( Flyable target )

FlyBehavior.java

代码语言:javascript
复制
public interface FlyBehavior {
   public void fly();
   public void setFlyableTarget( Flyable target );
}

FlyGracefully.java

代码语言:javascript
复制
public class FlyGracefully implements FlyBehavior {
   public void fly() {
      System.out.println("I fly so gracefully!");
   }
   public void setFlyableTarget( Flyable target ){
      target.modifyTargetName("GraceFul Flyer");
   }
}

TooTiredToFly.java

代码语言:javascript
复制
public class TooTiredToFly implements FlyBehavior {
   public void fly() {
      System.out.println("I'm too tired to fly.");
   }
   public void setFlyableTarget( Flyable target ){
      target.modifyTargetName("TiredFlyer");
   }
}

Duck.java让它实现Flyable.java

代码语言:javascript
复制
public class Duck implements Flyable{
    String name;
    Int health;
    FlyBehavior flyBehavior;

    public void modifyTargetName(String newName){
        this.name = newName;
    }
    public void performFly() {
       flyBehavior.fly();
    }

    public void setFlyBehavior(FlyBehavior f) {
       flyBehavior = f;
       f.setFlyableTarget(this);
    }
 }

这里的好处是,我们没有公开具体的实现,因此代码仍然是单元可测试的,并且对于适应变化是很好的。坚持DIP :依赖反转原理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37033361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档