对于我正在实施的特定状态模式,我不确定最佳 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()
用另一个 State 或new SomeRequest()
在 theController
或 another中实例化 a State
。在我看来,这会在 States 和它们的兄弟姐妹以及 theController
和State
s 之间产生高度耦合。
要求如下:
- 必须可以添加新状态,例如添加
SniffingState
. 还必须可以用新的国家取代现有的国家。例如,我应该能够
OffLeachState
用OffLeashState
执行不同操作的不同替换。例如(由于某种原因,代码不会格式化):public class OffLeachState2 extends DogState {
public void seeCat(Cat cat) {
if (dog.knows(cat)) {
// 狗更改为 "PlayWithCatState"
// 猫收到 "PlayWithDog" 请求
} else {
// 狗更改为 " ChaseAnimalState"
}
}
}World
最后,必须记录类中的所有更改。这意味着 World 类有一个记录器,可以跟踪正在发生的一切。这也是因为 World 类是一个模型,并且必须触发 anotifyObservers()
以便视图知道要做什么。
我的问题是,状态、请求等应该存储在哪里?例如:
应该有状态“吸气剂”
Dog
吗?例如dog.getBarkingState()
,,,dog.getOnLeashState()
等?这似乎是有道理的,但它不会使Dog
班级抵制改变。即,每次我添加一个新DogState
类时,我还必须确保它Dog
有一个吸气剂。此外,他们World
不知道这些更改,因此它不会记录它们,也不会通知观察者。应该有一个班级叫
DogStates
我可以跑DogStates.getBarkingState()
吗?再次,与上述类似的问题。他们应该成为
World
班级的一部分吗?例如,world.setDogState(dog, world.getDogBarkingState()
?这将解决日志记录/更新问题,但会给班级带来太多责任World
。例如,它应该是它们的某种组合
world.setState(dog, dog.getBarkingState()
吗?这可能很好,但不能保证类型安全。例如,我可以传入一个Dog
带有 a 的对象CatState
,它不会知道其中的区别。
解决方案#4 对我来说似乎是最好的,但我想对这个问题提出一些其他意见。
同样的问题也适用于Request
对象。我最初想Request
通过与对象关联的字符串发送 s,例如world.sendRequest(dog, DogRequests.SEE_CAT)
,但后来我无法将 cat 对象作为参数传递。
非常感谢您的宝贵时间!