我阅读了此链接enter link description here, 学习状态设计模式。
接口类:
public interface State {
void doAction();
}
onState类:
public class TVStartState implements State {
@Override
public void doAction() {
System.out.println("TV is turned ON");
}
}
offState:
public class TVStopState implements State {
@Override
public void doAction() {
System.out.println("TV is turned OFF");
}
}
TvContext类:
public class TVContext implements State {
private State tvState;
public void setState(State state) {
this.tvState=state;
}
public State getState() {
return this.tvState;
}
@Override
public void doAction() {
this.tvState.doAction();
}
}
测试类:
public static void main(String[] args) {
TVContext context = new TVContext();
State tvStartState = new TVStartState();
State tvStopState = new TVStopState();
context.setState(tvStartState);
context.doAction();
context.setState(tvStopState);
context.doAction();
}
现在我有两个问题:
1-为什么TVContext类implements
声明并且Composition
在一起?
是OO中的bug吗?
因为例如 Cat继承自Animal类和has_a动物(在这种情况下)。
2-如果此TestClass中的最终程序员将上下文传递给context.setState()
而不是 tvStartState 或 tvStopState ,则程序成功编译但在运行时错误。
对于状态设计模式”中的第二个问题,可以使用same name method
代替继承。但不是装饰设计模式。
答案 0 :(得分:8)
TVContext
类实现State
并且组成在一起?该示例不正确,TVContext
不应实现接口State
。从状态设计模式的UML图中,我们可以看到仅类Context
组成实现接口State
的属性。
context.setState()
而不是 tvStartState 或 tvStopState ,则程序会成功编译,但会出错运行时间。它编译的原因是因为 context 正在实现接口State
,但是由于运行java.lang.StackOverflowError
是递归调用,所以它在运行时由于context.setState()
而失败。本身,没有退出条件。从State
类中删除接口TVContext
可以解决此问题。
在装饰器设计模式中,目的是向 Component 类添加新行为。这就是为什么使用继承将新方法添加到 Component 的原因。
在状态设计模式中,目的是更改 Context 类的行为。例如,如果我们使用继承通过抽象类而不是接口来实现,则具体状态类上的操作需要覆盖抽象类中定义的操作。这就是为什么在这种情况下界面更有意义的原因。