我在使用状态模式时遇到了问题,我不知道如何在不使用State的情况下检查一个instanceOf是否属于某个实例(因为这被认为是一种糟糕的实践)。
TCPConnection持有一个TCPState对象。假设我想得到所有具有状态TCPConnections的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;
}但是它使用的是instanceOf,而我更不愿意使用它。有什么更好的方法吗?或者我对instanceOf的使用有效吗?
发布于 2015-04-23 18:07:44
是的,instanceOf的使用被认为是一种气味。此外,检查状态对象的类型违背了状态模式本身的思想(在子类型中封装状态依赖行为,这样就没有必要进行这种检查)。
不过,从技术上讲,您可以通过向instanceOf添加另一个操作(例如bool isEstablished())来摆脱bool isEstablished(),并实现它,使其只在TCPEstablished上返回true。
interface TCPState {
...
boolean isEstablished();
}
class TCPEstablished implements TCPState {
...
boolean isEstablished() {
return true;
}
}
class TCPClosed implements TCPState {
...
boolean isEstablished() {
return false;
}
}将操作添加到TCPConnection
class TCPConnection {
...
boolean isEstablished() {
return this.getState().isEstablished();
}
}那么您的getAllEstablished操作将如下所示:
List<TCPConnection> getAllEstablished() {
List<TCPConnection> list = new ArrayList<TCPConnection>();
for(TCPConnection tcp : allConnections) {
if(tcp.isEstablished()) {
list.add(tcp);
}
}
return list;
}instanceOf走了。但值得吗?
发布于 2015-04-23 17:53:01
你可以把你的州变成一个国家
public enum TCPState{
ESTABLISHED,
LISTEN,
CLOSED;
..methods go here
}因为枚举值是完全成熟的对象,所以它们可以重写方法来执行特定于状态的行为。然后,您可以执行equals()甚至==检查来检查状态。
for(TCPConnection tcp : allConnections) {
if(tcp.getState()==TCPState.Established)) {
list.add(tcp);
}
}编辑
下面是如何使每个枚举值对一个方法具有不同的实现。
假设TCPState实现了一个接口,或者有一个抽象方法foo()
public enum TCPState{
ESTABLISHED,
LISTEN,
CLOSED;
public abstract void foo();
}然后,可以对每个值以不同的方式实现该方法,如下所示:
public enum TCPState{
ESTABLISHED{
@Override
public void foo(){
System.out.println("established");
}
},
LISTEN{
@Override
public void foo(){
System.out.println("listening");
}
},
CLOSED{
@Override
public void foo(){
System.out.println("closed");
}
}
;
public abstract void foo();
}或者,您可以在TCPSTate中创建一个基本实现,而不是声明它为abstract,然后只在需要执行不同操作的值中使用重写。
https://stackoverflow.com/questions/29830832
复制相似问题