对于我正在实施的特定状态模式,我不确定最佳的OO设计方法应该如何。请考虑以下几点:使用状态模式解耦状态
public class World {
private Animal dog_;
private Animals cats_;
…..
public void sendDogRequest(DogRequest request) {
dog_.sendRequest(request);
}
…
public Cat getCat(String catName) {
…
return cat;
}
...
}
public class Animal<RequestType extends Request, StateType extends State> {
private State<StateType> currentState_;
….
public void sendRequest(RequestType request) {
request.sendToState(currentState_);
}
public void setState(StateType state) {
currentState_ = state;
}
}
public class Dog extends Animal<DogState> {
…
}
public class DogState extends State {
public DogState(Dog dog) {
…
}
public void seeCat(Cat cat) { }
}
public class OnLeashState extends DogState {
public void seeCat(Cat cat) {
dog.setState(new BarkingState());
}
}
public class OffLeashState extends DogState {
public void seeCat(Cat cat) {
dog.setState(new ChasingAfterAnimalState(cat));
cat.sendRequest(new RunAwayRequest(cat));
}
}
public interface Request<StateType extends State> {
public void sendToState(StateType state);
}
public class DogRequest extends Request<DogState> { }
public class SeeCatRequest extends DogRequest {
private Cat cat_;
public SeeCatRequest(Cat cat) {
cat_ = cat;
}
public void sendToState(DogState state) {
state.seeCat(state);
}
}
public class Controller() {
public Controller(World model, View view) {
…
}
...
public void catSelected(String catName) {
Cat cat = world.getCat(catName);
Dog dog = world.getDog();
world.sendDogRequest(new SeeCatRequest(cat));
}
…
}
我犹豫的面积是这里的字new
,即惯例。例示与另一个国家的new SomeState()
,或在Controller
或另一个State
内的new SomeRequest()
。在我看来,这会产生国家与兄弟姐妹之间的高度耦合,以及Controller
和State
。
的要求如下:
- 它必须是可以添加新的国家,例如添加
SniffingState
。 它也必须有可能用新的替代现有的国家。例如,我应该能够用不同的
OffLeashState
替换OffLeachState
,执行不同的操作。例如(由于某种原因,该代码将无法格式化):公共类OffLeachState2扩展DogState {
公共无效seeCat(猫猫){
如果(dog.knows(CAT)){
//狗变为 “PlayWithCatState”
//猫得到一个 “PlayWithDog” 要求
}其他{
//狗变为 “ChaseAnimalState”
}
}
}最后,必须记录
World
类中的所有更改。这意味着世界级的记录器正在跟踪正在发生的所有事情。这也是因为世界级是一个模型,并且必须启动一个notifyObservers()
以便视图知道要做些什么。
我的问题是,国家,请求等应该存储在哪里?例如:
Dog
应该有状态“getters”吗?例如,dog.getBarkingState()
,dog.getOnLeashState()
等?这似乎是有道理的,但它并不能改变类别。也就是说,每次我添加一个新的DogState
类时,我也必须确保Dog
有一个吸气剂。此外,World
不知道这些更改,因此它不记录它们也不通知观察者。是否应该有一个名为
DogStates
的类,我可以运行DogStates.getBarkingState()
?再一次,类似的问题与上述相同。他们应该是
World
班的一部分吗?例如,world.setDogState(dog, world.getDogBarkingState()
?这将解决记录/更新问题,但对World
类负责太多。它应该是它们的一些组合,例如
world.setState(dog, dog.getBarkingState()
?这可能会很好,但不能保证类型安全。例如,我可以传递一个Dog
对象与CatState
,它不知道区别。
解决方案#4似乎对我最好,但我想对此问题提出一些其他意见。
同样的问题适用于Request
对象。我本来想通过这都与对象相关联,例如world.sendRequest(dog, DogRequests.SEE_CAT)
字符串发送Request
S,但我过不了猫对象作为参数。
非常感谢您的宝贵时间!
非常感谢您的及时回复!你介意包含一些代码作为例子吗?对于1,我的理解是它会涉及诸如'dogStateFactory.createBarkingState()'之类的东西?对于2,你会在设置新状态后放置'notifyWorld()'吗? –
好的。让我们看看我的晚餐受损脑子吐出了什么......要编辑我的答案。 – chabicht
谢谢!哦,也许我应该开始编写编程考试。 :)我想出了整个场景来隔离我在较大范围内遇到的问题。 –