状态模式共享状态对象高效和可扩展实现之间的共同知识
State Pattern share common knowledge between state object efficient and extandable implementation
我正在使用状态模式,但我发现的示例是出于教育目的,我想知道在这种模式中 在状态之间共享对象 的最佳实践是什么,即一个布尔值、一个列表以及 用于一个状态对象以更改自动机对象中的状态引用。
我将建立一个简单的模型作为示例。
public abstract class State {
Automata automata;
public State( Automata automata){
this.automata = automata;
}
public abstract void action();
}
public class State1 extends State {
public State1(Automata automata){
super(automata)
}
@Override
public void action() {
// GET : Use obj1
// POST :Set in automata state to State2
}
}
public class State2 extends State {
public State2(Automata automata){
super(automata)
}
@Override
public void action() {
// GET :Use obj1
// POST :Set in automata state to State1
}
}
public class Automata {
private State state1 = new State1(this);
private State state2 = new State2(this);
private State state = state1;
public void takeAction() {
state.action()
}
}
我尝试了以下解决方案:
- 对于 GET 将
obj1
存储在自动机中并使用 getter 和 setter。对于 POST 在自动机中存储状态并使用 getter 和 setter。这种方法将通过使用 getter 使代码不必要地变长,并且随着 obj1
和状态的变化列表变得难以维护。
- 使用私有内部 classes。将
State, State1
和 State2
声明为私有内部 classes 并直接访问 obj1
和状态。仅仅因为文件的长度而难以维护和更新。无法与其他人共享 Automata
class.
- 创建字段public。我不想公开所有这些字段。
- 使用 singleton/static class 方法分享
obj1
的
我不太了解包私有访问。
在我的设计中,我将此模式与模板方法模式结合起来作为辅助信息。
我知道一刀切方法不存在,但是使用此模式的常见最佳实践是什么?
我会这样做:
public class Automata {
List<String> someList;
boolean someBoolean;
private State currentState;
public void performAction() {
currentState = currentState.action(this);
}
interface State {
State action(Automata context);
}
enum States implements State {
IDLE {
@Override
public State action(Automata context) {
if (context.someBoolean) {
return WORKING;
}
return this;
}
},
WORKING {
@Override
public State action(Automata context) {
if (context.someList.size() > 7) {
return IDLE;
}
return this;
}
}
}
}
状态的设置现在在 Automata
的 performAction()
中完成,无需在每个状态中执行此操作。我使用枚举作为状态的实现,因为当您想将状态实现为纯函数时,它们非常有用。但是,如果您的状态本身不是无状态的,您可能希望将状态实现为静态内部 类.
关注@rinde post,我很好奇这是否是一个可接受的解决方案
public abstract class State {
public State(){
}
public abstract void action(sharedState);
public class SharedState{
Obj1 obj1;
State state1;
State state2;
State curState;
//Getters and setters
}
}
public class State1 extends State {
@Override
public void action(SharedState sharedState) {
// GET : Use obj1
sharedState.obj1.doSomething()
// POST :Set in automata state to State2
sharedState.curState = sharedState.state2;
}
}
//..same for State2
public class Automata {
State.SharedState sharedState;
public Automata(){
sharedState.setState1(new State1());
sharedState.setState2(new State2());
}
public void takeAction() {
sharedState.getCurrentState().action(sharedState);
}
}
我正在使用状态模式,但我发现的示例是出于教育目的,我想知道在这种模式中 在状态之间共享对象 的最佳实践是什么,即一个布尔值、一个列表以及 用于一个状态对象以更改自动机对象中的状态引用。
我将建立一个简单的模型作为示例。
public abstract class State {
Automata automata;
public State( Automata automata){
this.automata = automata;
}
public abstract void action();
}
public class State1 extends State {
public State1(Automata automata){
super(automata)
}
@Override
public void action() {
// GET : Use obj1
// POST :Set in automata state to State2
}
}
public class State2 extends State {
public State2(Automata automata){
super(automata)
}
@Override
public void action() {
// GET :Use obj1
// POST :Set in automata state to State1
}
}
public class Automata {
private State state1 = new State1(this);
private State state2 = new State2(this);
private State state = state1;
public void takeAction() {
state.action()
}
}
我尝试了以下解决方案:
- 对于 GET 将
obj1
存储在自动机中并使用 getter 和 setter。对于 POST 在自动机中存储状态并使用 getter 和 setter。这种方法将通过使用 getter 使代码不必要地变长,并且随着obj1
和状态的变化列表变得难以维护。 - 使用私有内部 classes。将
State, State1
和State2
声明为私有内部 classes 并直接访问obj1
和状态。仅仅因为文件的长度而难以维护和更新。无法与其他人共享Automata
class. - 创建字段public。我不想公开所有这些字段。
- 使用 singleton/static class 方法分享
obj1
的
我不太了解包私有访问。
在我的设计中,我将此模式与模板方法模式结合起来作为辅助信息。
我知道一刀切方法不存在,但是使用此模式的常见最佳实践是什么?
我会这样做:
public class Automata {
List<String> someList;
boolean someBoolean;
private State currentState;
public void performAction() {
currentState = currentState.action(this);
}
interface State {
State action(Automata context);
}
enum States implements State {
IDLE {
@Override
public State action(Automata context) {
if (context.someBoolean) {
return WORKING;
}
return this;
}
},
WORKING {
@Override
public State action(Automata context) {
if (context.someList.size() > 7) {
return IDLE;
}
return this;
}
}
}
}
状态的设置现在在 Automata
的 performAction()
中完成,无需在每个状态中执行此操作。我使用枚举作为状态的实现,因为当您想将状态实现为纯函数时,它们非常有用。但是,如果您的状态本身不是无状态的,您可能希望将状态实现为静态内部 类.
关注@rinde post,我很好奇这是否是一个可接受的解决方案
public abstract class State {
public State(){
}
public abstract void action(sharedState);
public class SharedState{
Obj1 obj1;
State state1;
State state2;
State curState;
//Getters and setters
}
}
public class State1 extends State {
@Override
public void action(SharedState sharedState) {
// GET : Use obj1
sharedState.obj1.doSomething()
// POST :Set in automata state to State2
sharedState.curState = sharedState.state2;
}
}
//..same for State2
public class Automata {
State.SharedState sharedState;
public Automata(){
sharedState.setState1(new State1());
sharedState.setState2(new State2());
}
public void takeAction() {
sharedState.getCurrentState().action(sharedState);
}
}