|
|
(7 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| + | {{NAVPO}} |
| {{TOCright}} | | {{TOCright}} |
| O padrão "state" permite que um objecto altere o seu comportamento quando o seu estado muda. | | O padrão "state" permite que um objecto altere o seu comportamento quando o seu estado muda. |
Line 7: |
Line 8: |
| [[Image:state-dpcd.png|500px]] | | [[Image:state-dpcd.png|500px]] |
| | | |
− | ==Exemplo: Porta Automática == | + | == Exemplos == |
| | | |
− | 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).
| + | * [[State Pattern (padrão de desenho)/Porta Automática|Porta Automática]] |
| | | |
− | [[Image:state-dp-state-diagram-door.png|500px]]
| + | == Exercícios == |
| | | |
− | A uma aplicação de teste que simula alguns estÃmulos aos quais a porta deve responder.
| + | * [[State Pattern (padrão de desenho)/Exercício 01: Semáforo|Exercício 1: Semáforo]] |
| + | * [[State Pattern (padrão de desenho)/Exercício 02: Máquina de Lavar|Exercício 2: Máquina de Lavar]] |
| | | |
− | public class StatePattern {
| + | [[category:Ensino]] |
− | public static void main(String[] args) {
| + | [[category:PO]] |
− | 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.
| |
− | | |
− | === 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:Teaching]] | |