instanceOf(状态模式)的替代方案

Sta*_*nko 4 java design-patterns instanceof state-pattern

我在使用状态模式时遇到问题,我不知道如何在State不使用的情况下检查 a是否属于某个实例instanceOf(因为这被认为是一种不好的做法)。

TCPConnection持有一个TCPState对象。假设我想获得所有TCPConnections具有 state 的TCPEstablished。我该怎么做? 在此处输入图片说明

一种方法是:

public List<TCPConnection> getAllEstablished() {
  List<TCPConnection> list = new ArrayList<TCPConnection>();

  for(TCPConnection tcp : allConnections) {
      if(tcp.getState().instanceOf(TCPEstablished)) {
          list.add(tcp);
      }
  }

  return list;
}
Run Code Online (Sandbox Code Playgroud)

但这使用instanceOf,我宁愿不使用它。有没有更好的方法?还是我的使用instanceOf有效?

pro*_*kor 5

是的,使用instanceOf被认为是一种气味。此外,检查状态对象的类型与状态模式本身的想法背道而驰(将依赖状态的行为封装在子类型中,这样检查就变得不必要了)。

尽管如此,您可以在技术上instanceOf通过添加另一个操作来摆脱TCPState,例如bool isEstablished(),并实现它以便它只返回trueon TCPEstablished

interface TCPState {
    ...
    boolean isEstablished();
}

class TCPEstablished implements TCPState {
    ...
    boolean isEstablished() {
        return true;
    }
}

class TCPClosed implements TCPState {
    ...
    boolean isEstablished() {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

将操作添加到TCPConnection

class TCPConnection {
    ...
    boolean isEstablished() {
        return this.getState().isEstablished();
    }
}
Run Code Online (Sandbox Code Playgroud)

那么您的操作getAllEstablished将如下所示:

List<TCPConnection> getAllEstablished() {
    List<TCPConnection> list = new ArrayList<TCPConnection>();

    for(TCPConnection tcp : allConnections) {
        if(tcp.isEstablished()) {
            list.add(tcp);
        }
    }

    return list;
}
Run Code Online (Sandbox Code Playgroud)

instanceOf离开了。但是这值得吗?