1.) Это похоже на вопрос экзамена по программированию. В таких случаях, если вы не знаете, что делать, используйте шаблон ! Таким образом, каждое состояние должно быть сгенерировано StateFactory и предоставить экземпляру Factory некоторую информацию о мире, чтобы он мог решить, какой конкретный экземпляр State создать.
Вот что регистрирует:
public class World implements StateChangeListener {
private Animal dog_;
private Animals cats_;
private final List<StateChangeListener> listeners = new ArrayList<StateChangeListener>();
public World() {
listeners.add(this);
}
// Instead of sending DogRequests to Dogs via the sendDogRequest method:
public <RequestType extends Request> void sendRequest(
Animal<RequestType, ?> animal, Request<RequestType> request) {
animal.sendRequest(request);
for(StateChangeListener listener : listeners) {
listener.stateChanged(animal, request);
}
}
public void stateChanged(Animal<?, ?> animal, State<?> state) {
// ... log here ...
}
...
И эти вещи из Фабрики (возможно, немного разбросанные, Дженерики могут работать неправильно; о).
public enum LocationEnum {
HOME, PARK, POND, FOREST
}
public interface StateFactory<StateType extends State> {
State<StateType> create(Animal<StateType, ?> animal, Context context);
}
// Do stuff Dogs do.
public class DogStateFactory<DogState> {
public State<DogState> create(Animal<DogState, ?>, Context context) {
if(context.currentAnimalLocation==LocationEnum.POND) {
return new IgnoreEverythingState();
}else if(context.currentAnimalLocation==LocationEnum.HOME){
return new PerpetualBarkState();
}else {
return new FollowEveryCatState();
}
}
}
public class Animal<RequestType extends Request, StateType extends State> {
private StateFactory<StateType> stateFactory;
private State<StateType> currentState_;
public void sendRequest(Request<RequestType> request) {
request.sendToState(currentState_);
}
// A specific animal knows what it wants to do, depending on it's current
// state and it's situational context. We don't want other animals
// to set the state for us.
public void determineState() {
currentState_ = stateFactory.create(this, new Context(...));
// One might want to extend the messaging stuff in a way that
// the World instance can log this state change.
}
}
public class Dog extends Animal<DogRequest, DogState> {
public Dog() {
this.stateFactory = new DogStateFactory<DogState>();
}
}
2.) Если вы хотите, чтобы Мир знал обо всем, что происходит в нем, вы можете заменить сообщениями установщиков состояний сообщениями и позволить экземпляру Мира прослушивать изменения состояния каждого.