java - 在状态模式中实现继承层次结构

标签 java c# php design-patterns state-pattern

我有一个与此非常相似的设计:

enter image description here

这里的NewOrderRegisteredGranted都有常用的方法AddOrderline()Cancel () ,因此将这两个方法重构为父类很容易。

当我想要取消已发货行(当前未在图中显示)时,就会出现问题。

由于 Shipped 行不支持 AddOrderline() 那么我需要破坏 NewOrder 的父类,注册授予到2个类,第一个用于Cancel(),另一个用于AddOrderline()

现在 NewOrder 必须扩展 2 个父类才能获取 2 个函数。

注释

  1. 这个例子非常简单。我的真实应用程序大约有 12 个状态。
  2. 代码是 PHP 语言,但欢迎使用 C# 或 Java 解决方案,因为我认为解决方案将是相似的,因为它们都不支持多重继承。

最佳答案

我会考虑将接口(interface)与实现分离。例如在Java中

interface Cancellable {
   void cancel();
}
interface Shippable{
   void ship();
}

等等

public class NewState implements Cancellable, Shippable {
  public void cancel() { ... }
  public void ship() { ... }
}

如果您有一个底层私有(private)状态,它可以实现所有所需的接口(interface),而您的公共(public)状态只需要委托(delegate)那些支持的状态。例如

 public class UnderlyingState implements Cancellable, Shippable ... {
    public void cancel() { ... }
    public void ship() { ... }
 }

  public class ShippableState implements Shippable {
     private UnderlyingState ustate = new UnderlyingState();
     public void cancel() {
        // you can *only* cancel this
        ustate.cancel();    
     }
   }

在上面,您可能需要返回一个新的状态对象(而不是 void)并让您的 Order 采用该新状态。 UnderlyingState 对象将强制执行某些状态机。

令人头疼的是,随着状态数量的增加,您的接口(interface)和实现也会增加。

关于java - 在状态模式中实现继承层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14813860/

相关文章:

c# - 如何获得返回要调用的表达式而不是解释为表达式的函数

c# - .NET 4.6 和 C#6 中是否集成了动态语言运行时 (DLR)?

php - 尝试创建一个页面,如果是第一次登录,则检查纯文本密码,否则检查哈希密码(php)

php - 将 ü 转换为 u

php - json_decode,尝试访问数组元素

java - java 程序出现运行时错误

java - Java 中十进制数的正则表达式是什么?

java - 如何获取地理位置详细信息位置错误原因

java - 有没有办法在java日历中将 float 添加到毫秒?

c# - 检测目录中的更改