私が実装している特定の状態パターンに関して、最適な 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()
を別の状態でインスタンス化するか、または別のnew SomeRequest()
内でインスタンス化します。これは、州とその兄弟、および とs の間の高い結合を生み出すように私には思えます。Controller
State
Controller
State
要件は次のとおりです。
- を追加するなど、新しい状態を追加できる必要があり
SniffingState
ます。 また、既存の状態を新しい状態に置き換えることが可能でなければなりません。たとえば、別のアクションを実行する別
OffLeachState
のものに置き換えることができるはずです。OffLeashState
例(何らかの理由でコードがフォーマットされません):public class OffLeachState2 extends DogState {
public void seeCat(Cat cat) {
if (dog.knows(cat)) {
// 犬は "PlayWithCatState" に変わります
// 猫は "PlayWithDog" リクエストを受け取り
ます } else {
// 犬は " に変わりますChaseAnimalState"
}
}
}World
最後に、クラス内のすべての変更をログに記録する必要があります。つまり、World クラスには、進行中のすべてを追跡するロガーがあるということです。これは、World クラスがモデルでありnotifyObservers()
、ビューが何かを行うことを認識できるように を起動する必要があるためでもあります。
私の質問は、状態、要求などをどこに保存する必要があるかです。例えば:
に状態「ゲッター」が必要
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
オブジェクトを で渡すことができますCatState
が、違いはわかりません。
解決策 #4 が私には最善のように思えますが、この問題について他の意見が欲しいです。
同じ質問がオブジェクトにも当てはまりRequest
ます。Request
もともと、オブジェクトに関連付けられた文字列で sを送信したかったのworld.sendRequest(dog, DogRequests.SEE_CAT)
ですが、 cat オブジェクトを引数として渡すことができませんでした。
お時間をいただきありがとうございました!