(→Porta automática) |
(→Exemplos) |
||
Line 27: | Line 27: | ||
} | } | ||
− | === | + | 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. | ||
+ | |||
+ | === Porta: classe Door === | ||
+ | |||
+ | 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. | ||
+ | |||
+ | class Door { | ||
+ | public final DoorState CLOSED = new DoorClosed(this); | ||
+ | public final DoorState OPENING = new DoorOpening(this); | ||
+ | public final DoorState OPEN = new DoorOpen(this); | ||
+ | public final DoorState CLOSING = new DoorClosing(this); | ||
+ | public final DoorState STAYOPEN = new DoorStayOpen(this); | ||
+ | |||
+ | private DoorState _state = CLOSED; | ||
+ | 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()); } | ||
+ | } | ||
+ | |||
+ | === 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. | ||
+ | |||
+ | 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(); } | ||
+ | } | ||
+ | |||
+ | === Os vários estados da porta: classes concretas === | ||
+ | |||
+ | Cada uma das classes implementa o estado correspondente a uma dada situação da porta. É nests classes que a resposta aos estÃmulos é realmente definida. | ||
+ | |||
+ | class DoorOpen extends DoorState { | ||
+ | public DoorOpen(Door door) { super(door); } | ||
+ | public void click() { _door.setState(_door.STAYOPEN); } | ||
+ | public void timeout() { _door.setState(_door.CLOSING); } | ||
+ | } | ||
+ | |||
+ | class DoorOpening extends DoorState { | ||
+ | public DoorOpening(Door door) { super(door); } | ||
+ | public void click() { _door.setState(_door.CLOSING); } | ||
+ | public void complete() { _door.setState(_door.OPEN); } | ||
+ | } | ||
+ | |||
+ | class DoorClosed extends DoorState { | ||
+ | public DoorClosed(Door door) { super(door); } | ||
+ | public void click() { _door.setState(_door.OPENING); } | ||
+ | } | ||
+ | |||
+ | class DoorClosing extends DoorState { | ||
+ | public DoorClosing(Door door) { super(door); } | ||
+ | public void click() { _porta.setState(_door.OPENING); } | ||
+ | public void complete() { _porta.setState(_door.CLOSED); } | ||
+ | } | ||
+ | |||
+ | class DoorStayOpen extends DoorState { | ||
+ | public DoorStayOpen(Door door) { super(door); } | ||
+ | public void click() { _door.setState(_door.CLOSING); } | ||
+ | } | ||
+ | |||
[[category:OOP]] | [[category:OOP]] |
O padrão "state" permite que um objecto altere o seu comportamento quando o seu estado muda.
O padrão state tem a seguinte estrutura de classes:
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.
class Door { public final DoorState CLOSED = new DoorClosed(this); public final DoorState OPENING = new DoorOpening(this); public final DoorState OPEN = new DoorOpen(this); public final DoorState CLOSING = new DoorClosing(this); public final DoorState STAYOPEN = new DoorStayOpen(this); private DoorState _state = CLOSED; 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. É nests classes que a resposta aos estÃmulos é realmente definida.
class DoorOpen extends DoorState { public DoorOpen(Door door) { super(door); } public void click() { _door.setState(_door.STAYOPEN); } public void timeout() { _door.setState(_door.CLOSING); } }
class DoorOpening extends DoorState { public DoorOpening(Door door) { super(door); } public void click() { _door.setState(_door.CLOSING); } public void complete() { _door.setState(_door.OPEN); } }
class DoorClosed extends DoorState { public DoorClosed(Door door) { super(door); } public void click() { _door.setState(_door.OPENING); } }
class DoorClosing extends DoorState { public DoorClosing(Door door) { super(door); } public void click() { _porta.setState(_door.OPENING); } public void complete() { _porta.setState(_door.CLOSED); } }
class DoorStayOpen extends DoorState { public DoorStayOpen(Door door) { super(door); } public void click() { _door.setState(_door.CLOSING); } }