Design patterns 什么是最好的方法,使用;“国家”;设计模式,改变状态?
我目前对州设计模式的理解基本上是这样的: 在对象中封装处于特定状态的对象的所有行为。将请求委托给“当前”状态对象 我的问题是:处理状态转换的最佳方式是什么?在我的例子中,“当前”状态对象很可能是决定我们需要转换到哪个其他状态的对象。我想到了两种实现方法:Design patterns 什么是最好的方法,使用;“国家”;设计模式,改变状态?,design-patterns,oop,Design Patterns,Oop,我目前对州设计模式的理解基本上是这样的: 在对象中封装处于特定状态的对象的所有行为。将请求委托给“当前”状态对象 我的问题是:处理状态转换的最佳方式是什么?在我的例子中,“当前”状态对象很可能是决定我们需要转换到哪个其他状态的对象。我想到了两种实现方法: state objects方法可以返回一些特定的值,这意味着“我正在请求状态转换”。然后,主对象可以查询当前状态以确定我们应该转换到哪个新状态,调用ChangeState(),然后将原始请求路由到新状态 状态对象本身可以调用父对象上的Chang
ChangeState()
,然后将原始请求路由到新状态ChangeState()
,然后将导致状态更改的请求传递给新对象我希望有更好的方法来处理这种情况。你觉得怎么样?我更喜欢state方法返回新的state对象(它减少了耦合,更适合于S.O.L.I.D.原则) 以下示例(此想法用于实际项目):
我认为您可能将自己局限于只考虑实现状态模式的对象(上下文对象和状态对象)。情况并非如此,还涉及其他对象(客户机)。持有对上下文对象的引用的客户机应该负责转换状态,这是可能的 考虑这个虚构的例子:
// Paintbrush is the context object
class Paintbrush {
// The State object, ColourState would be the abstraction
private ColourState colourState;
// ... other class stuff
public paint() {
// Delegation to the state object
this.colourState.paintInYourSpecificColour();
}
public void setColourState(ColourState newState) {
this.colourState = newState;
}
}
对于上下文对象来说,这应该是足够的实现了。请注意,colorstate
和Paintbrush
类都不知道状态转换。这是为了减少责任的数量,以及提供更灵活的设计
基本上,状态的改变可能是调用类的责任。如何在代码中真正实现这一点是实现细节,但需要注意的是,上下文对象和状态对象都不负责转换状态
我试图确保我没有使用斯特劳曼论点,但我将继续使用这个例子。假设在不同的点上,您想要绘制不同的图案,并且所使用的颜色必须按照特定的顺序,您的客户将决定何时更改状态,如下所示:
public void paintRainbow() {
paintbrush.setColourState(new RedColourState());
// do painting...
// Change state to next colour
paintbrush.setColourState(new OrangeColourState());
// Chane state again, and so on...
}
您可以拥有由状态或上下文对象指定的颜色顺序,即拥有名为RainbowPaintbrush
的Paintbrush子类,它将选择下一种颜色。或者您的状态对象可以选择下一个状态,在这种情况下,您必须有一个红色彩虹颜色状态
,它知道下一个状态是橙色彩虹颜色状态
,依此类推。但这两个示例的问题是,您必须进入并(通过扩展)修改上下文和状态对象,以实现不同的转换集。但是,如果两者都不知道转换,并且这是调用类的责任,那么这可以在不更改状态或上下文对象的情况下完成。即
public void paintChessboard() {
paintbrush.setColourState(blackColourState);
// do painting...
// change state
paintbrush.setColourState(whiteColourState);
// etc...
}
这是一个简化的例子,但通常都成立
快速阅读维基百科上的内容可以看出,各个州都知道下一个州,所以我认为这样做并不无效。我想总的来说,这是一个权衡,你希望控制在哪里,以及它将如何适应你的问题。这就是使用具体的状态对象进行转换如何适合我的跛脚示例:
public class RedRainbowColourState implements ColourState {
public void doPaint(Paintbrush paintbrush) {
// do painting
ColourState nextStateInRainbow = new OrangePaintbrushColourState();
paintbrush.setColourState(nextStateInRainbow);
}
但请注意,使用这种方式在所有状态之间进行转换所需的状态类数量激增。然而,这里的一个优势是,客户可以免除如何创建单个状态的责任和知识。在你的情况下,这可能是更好的过渡方式
总之,您可以让各个状态执行转换,甚至是上下文对象。另一种选择是让客户端处理状态转换。您的一个标记拼写错误-我无法修复它,因为我没有足够的代表。正如您提到的,当前的
状态决定下一个状态,那么第二种方法不仅是一种更好的方法,而且也是正确的方法。仅供参考:设计模式思维导图:你能解释一下这是如何与坚实的原则更加一致并减少耦合的吗?谢谢
public class RedRainbowColourState implements ColourState {
public void doPaint(Paintbrush paintbrush) {
// do painting
ColourState nextStateInRainbow = new OrangePaintbrushColourState();
paintbrush.setColourState(nextStateInRainbow);
}