(→Porta: classe Door) |
(→O estado da porta: classe DoorState) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
A uma aplicação de teste que simula alguns estímulos aos quais a porta deve responder. | A uma aplicação de teste que simula alguns estímulos aos quais a porta deve responder. | ||
− | < | + | <source lang="java"> |
public class StatePattern { | public class StatePattern { | ||
public static void main(String[] args) { | public static void main(String[] args) { | ||
Line 15: | Line 15: | ||
} | } | ||
} | } | ||
− | </ | + | </source> |
Se não se utilizasse o padrão State, fazendo com que sejam os objectos do estado a responder aos estímulos, o controlo da máquina de estados teria de ser implementado directamente na porta fazendo com que houvesse mais código a manter e dificultando a gestão dos estados de forma independente, especialmente, mas sem limitação, no que respeita à definição de novos estados e comportamentos a eles associados. | Se não se utilizasse o padrão State, fazendo com que sejam os objectos do estado a responder aos estímulos, o controlo da máquina de estados teria de ser implementado directamente na porta fazendo com que houvesse mais código a manter e dificultando a gestão dos estados de forma independente, especialmente, mas sem limitação, no que respeita à definição de novos estados e comportamentos a eles associados. | ||
Line 26: | Line 26: | ||
Note-se que a definição dos objectos dos estados como constantes pode não ser a melhor solução: alguns estados podem ter necessidade de manter informação sobre o decorrer da execução ou podem diferir de outras instâncias da mesma classe no valor dos seus atributos (no caso da porta, isso poderia corresponder, por exemplo, à velocidade de abertura ou fecho da porta). | Note-se que a definição dos objectos dos estados como constantes pode não ser a melhor solução: alguns estados podem ter necessidade de manter informação sobre o decorrer da execução ou podem diferir de outras instâncias da mesma classe no valor dos seus atributos (no caso da porta, isso poderia corresponder, por exemplo, à velocidade de abertura ou fecho da porta). | ||
− | < | + | <source lang="java"> |
class Door { | class Door { | ||
private DoorState _state = new DoorClosed(this); | private DoorState _state = new DoorClosed(this); | ||
Line 37: | Line 37: | ||
public void status() { System.out.println(_state.status()); } | public void status() { System.out.println(_state.status()); } | ||
} | } | ||
− | </ | + | </source> |
=== O estado da porta: classe DoorState === | === O estado da porta: classe DoorState === | ||
Esta classe representa a abstracção do estado da porta. Os estados concretos vão aumentar a funcionalidade desta classe, de acordo com o comportamento desejado. | Esta classe representa a abstracção do estado da porta. Os estados concretos vão aumentar a funcionalidade desta classe, de acordo com o comportamento desejado. | ||
− | < | + | <source lang="java"> |
abstract class DoorState { | abstract class DoorState { | ||
protected Door _door; | protected Door _door; | ||
Line 55: | Line 55: | ||
public String status() { return getClass().getName(); } | public String status() { return getClass().getName(); } | ||
} | } | ||
− | </ | + | </source> |
=== Os vários estados da porta: classes concretas === | === Os vários estados da porta: classes concretas === | ||
Cada uma das classes implementa o estado correspondente a uma dada situação da porta. É nestas classes que a resposta aos estímulos é realmente definida. | Cada uma das classes implementa o estado correspondente a uma dada situação da porta. É nestas classes que a resposta aos estímulos é realmente definida. | ||
− | < | + | <source lang="java"> |
class DoorOpen extends DoorState { | class DoorOpen extends DoorState { | ||
public DoorOpen(Door door) { super(door); } | public DoorOpen(Door door) { super(door); } | ||
− | public void click() { _door.setState(_door | + | public void click() { _door.setState(new DoorStayOpen(_door)); } |
− | public void timeout() { _door.setState(_door | + | public void timeout() { _door.setState(new DoorClosing(_door)); } |
} | } | ||
class DoorOpening extends DoorState { | class DoorOpening extends DoorState { | ||
public DoorOpening(Door door) { super(door); } | public DoorOpening(Door door) { super(door); } | ||
− | public void click() { _door.setState(_door | + | public void click() { _door.setState(new DoorClosing(_door)); } |
− | public void complete() { _door.setState(_door | + | public void complete() { _door.setState(new DoorOpen(_door)); } |
} | } | ||
class DoorClosed extends DoorState { | class DoorClosed extends DoorState { | ||
public DoorClosed(Door door) { super(door); } | public DoorClosed(Door door) { super(door); } | ||
− | public void click() { _door.setState(_door | + | public void click() { _door.setState(new DoorOpening(_door)); } |
} | } | ||
class DoorClosing extends DoorState { | class DoorClosing extends DoorState { | ||
public DoorClosing(Door door) { super(door); } | public DoorClosing(Door door) { super(door); } | ||
− | public void click() { | + | public void click() { _door.setState(new DoorOpening(_door)); } |
− | public void complete() { | + | public void complete() { _door.setState(new DoorClosed(_door)); } |
} | } | ||
class DoorStayOpen extends DoorState { | class DoorStayOpen extends DoorState { | ||
public DoorStayOpen(Door door) { super(door); } | public DoorStayOpen(Door door) { super(door); } | ||
− | public void click() { _door.setState(_door | + | public void click() { _door.setState(new DoorClosing(_door)); } |
} | } | ||
− | </ | + | </source> |
[[category:Ensino]] | [[category:Ensino]] |
A porta automática pode estar en vários estados que determinam a sua resposta a estímulos. Os vários estados são "Closed" (porta fechada); "Closing" (porta a fechar); "StayOpen" (permanentemente aberta); "Open" (aberta); "Opening" (porta a abrir). Os estímulos são "click" (botão de abrir/fechar premido); "complete" (fim do ciclo de abertura/fecho); "timeout" (passagem de tempo num dado estado).
A uma aplicação de teste que simula alguns estímulos aos quais a porta deve responder.
public class StatePattern {
public static void main(String[] args) {
Door door = new Door(); // Closed
door.click();
door.complete();
door.timeout();
door.click();
door.status();
}
}
Se não se utilizasse o padrão State, fazendo com que sejam os objectos do estado a responder aos estímulos, o controlo da máquina de estados teria de ser implementado directamente na porta fazendo com que houvesse mais código a manter e dificultando a gestão dos estados de forma independente, especialmente, mas sem limitação, no que respeita à definição de novos estados e comportamentos a eles associados.
As classes seguintes ilustram os intervenientes neste padrão.
Esta classe representa a porta nas condições descritas acima. Note-se a definição das respostas aos estímulos em função do estado.
Note-se que a definição dos objectos dos estados como constantes pode não ser a melhor solução: alguns estados podem ter necessidade de manter informação sobre o decorrer da execução ou podem diferir de outras instâncias da mesma classe no valor dos seus atributos (no caso da porta, isso poderia corresponder, por exemplo, à velocidade de abertura ou fecho da porta).
class Door {
private DoorState _state = new DoorClosed(this);
protected void setState(DoorState state) { _state = state; }
public void click() { _state.click(); }
public void complete() { _state.complete(); }
public void timeout() { _state.timeout(); }
public void status() { System.out.println(_state.status()); }
}
Esta classe representa a abstracção do estado da porta. Os estados concretos vão aumentar a funcionalidade desta classe, de acordo com o comportamento desejado.
abstract class DoorState {
protected Door _door;
public DoorState(Door door) { _door = door; }
public abstract void click();
public void timeout() { }
public void complete() { }
public String status() { return getClass().getName(); }
}
Cada uma das classes implementa o estado correspondente a uma dada situação da porta. É nestas classes que a resposta aos estímulos é realmente definida.
class DoorOpen extends DoorState {
public DoorOpen(Door door) { super(door); }
public void click() { _door.setState(new DoorStayOpen(_door)); }
public void timeout() { _door.setState(new DoorClosing(_door)); }
}
class DoorOpening extends DoorState {
public DoorOpening(Door door) { super(door); }
public void click() { _door.setState(new DoorClosing(_door)); }
public void complete() { _door.setState(new DoorOpen(_door)); }
}
class DoorClosed extends DoorState {
public DoorClosed(Door door) { super(door); }
public void click() { _door.setState(new DoorOpening(_door)); }
}
class DoorClosing extends DoorState {
public DoorClosing(Door door) { super(door); }
public void click() { _door.setState(new DoorOpening(_door)); }
public void complete() { _door.setState(new DoorClosed(_door)); }
}
class DoorStayOpen extends DoorState {
public DoorStayOpen(Door door) { super(door); }
public void click() { _door.setState(new DoorClosing(_door)); }
}