将条件替换为多态 - 类型更改时如何处理

本文关键字:何处理 处理 替换 条件 多态 类型 | 更新日期: 2023-09-27 18:26:06

对于一个个人项目,我正在开发一个基于Web的小型游戏。

我有一个具有Status属性的Card类,到处都是 case 语句。我想,嘿,这是用多态替换条件的好机会!

问题是,我有几种方法可以做这样的事情:

public class Card
{
    public void ChangeStatus()
    {
      switch (Status)
      {
        case MyStatusEnum.Normal:
          Status = MyStatusEnum.Underwater;
          break;
        case MyStatusEnum.Underwater:
          Status = MyStatusEnum.Dead;
          break;
        // etc...
      }
    }
}

在新的NormalCard类中重构它时,我像这样重写ChangeStatus方法:

public override void ChangeStatus()
{
    base.Status = MyStatusEnum.Underwater;
}

问题是这个NormalCard对象具有Underwater的状态。 我无法重新分配this的类型,我真的不想将方法的返回从void更改为CardBase。 我有哪些选择? 有没有标准的方法可以做到这一点?

编辑 Tormod 让我直截了当。 我想要状态模式。谢谢大家!

将条件替换为多态 - 类型更改时如何处理

在您的情况下,我有一个包含CardStatus属性的Card对象。CardStatus的子类型对应于前面的枚举值。重构依赖于当前状态的行为,但状态转换除外,位于 CardStatus 子类型中。

IMO 中的第一个示例中的状态转换应保留在 Card 对象内。状态更改感觉更像是包含卡的行为,而不是状态对象的行为。您可以做的是让 CardStatus 对象告诉您在事件发生后要转换为什么状态。

一个粗略的例子:(显然还有更多可以使用的变体。

应用程序接口

interface ICardStatus {
    ICardStatus NextStatus(Card card);
    void DoStuff(Card card);
}
class Card {
    ICardStatus Status = new NormalCardStatus();
    void DoStuff() {
        Status.DoStuff(this);
    }
    void ChangeStatus() {
        Status = Status.NextStatus(this);
    }
}

状态实现

class NormalCardStatus : ICardStatus {
    ICardStatus NextStatus(Card card) {
        return new UnderwaterCardStatus();
    }
    void DoStuff(Card card) {
        // ...
    }
}
class UnderwaterCardStatus : ICardStatus {
    ICardStatus NextStatus(Card card) {
        return new DeathStatus();
    }
    void DoStuff(Card card) {
        // ...
    }
}
class DeathCardStatus : ICardStatus {
    ICardStatus NextStatus(Card card) {
        // ...
    }
    void DoStuff(Card card) {
        throw new Exception("Cannot do anything while dead");
    }
}

你可以用多态性编写Status类:

class Status
{
    Status GetNextStatusWhenFooHappens() {}
    Status GetNextStatusWhenBarHappens() {}
    Status GetNextStatusWhenBloopHappens() {}
}

每种方法都返回要移动到的状态,或您现在在case中正在执行的任何其他操作。然后,您可以为每个特定状态覆盖这些方法。Card类不会与此实现多态,但它将包含多态Status成员。

在某些情况下,

用多态性替换条件很有用,但不清楚它在这里是否合适......至少不是直枚举。您可以引入"智能枚举"类型而不是MyStatusEnum,其中每个值都知道"下一个"值 - 那么你不一定使用多态性,但您将使用一组固定的值,其中包含比标准枚举更多的信息。

另一种选择是从"当前状态"到"下一个状态"的简单Dictionary<MyStatusEnum, MyStatusEnum>。这真的取决于你是否需要做更多的事情。我怀疑我们真的无法仅根据您提供的代码提供非常好的建议。