Programação avançada – capitulo 8 – maquina de estados, exemplo1
Exemplo de uma maquina de estado, simples, usando as referências a um mecanismo de um elevador
Em que ficou:
Com:
package me_me_elevador; import me_me_elevador.IU.Texto.UsaElevador; import me_me_elevador.logica.Elevador; public class Me_ME_elevador { public static void main(String[] args) { Elevador e = new Elevador(); UsaElevador usaE = new UsaElevador(e); //interface com o utilizador usaE.corre(); } }
package me_me_elevador.IU.Texto; import me_me_elevador.logica.*; import me_me_elevador.util.IUUtil; public class UsaElevador { //o interface com o utilizador, com o nosso elevador. private Elevador elevador; private boolean sair = false; public UsaElevador(Elevador elevador) { this.elevador = elevador; } public void corre() { while (!sair) { //saber em que estado estou IEstado estado = elevador.getEstado(); if (estado instanceof RC) { iuRC(); } else if (estado instanceof Andar1) { iuAndar1(); } else if (estado instanceof Andar2) { iuAndar2(); } else if (estado instanceof Andar3) { iuAndar3(); } } } private void iuRC() { //opcoa 1 //pedir ao utilizador: sair ou subir int opcao = IUUtil.getOpcao("Piso R/C", "Ir embora", "Subir"); switch (opcao) { case 0: sair = true; break; case 1: //fazer evoluir a maquina de estados elevador.sobe(); break; } } private void iuAndar1() { int opcao = IUUtil.getOpcao("Piso 1 andar","Descer", "Subir"); switch (opcao) { case 0: //fazer evoluir a maquina de estados elevador.desce(); break; case 1: //fazer evoluir a maquina de estados elevador.sobe(); break; } } private void iuAndar2() { int opcao = IUUtil.getOpcao("Piso 2 andar","Descer", "Subir"); switch (opcao) { case 0: //fazer evoluir a maquina de estados elevador.desce(); break; case 1: //fazer evoluir a maquina de estados elevador.sobe(); break; } } private void iuAndar3() { int opcao = IUUtil.getOpcao("Piso 3 andar","Descer"); switch (opcao) { case 0: //fazer evoluir a maquina de estados elevador.desce(); break; } } }
package me_me_elevador.logica; public class Andar1 extends Piso{ @Override public IEstado sobe() { //altero de estado return new Andar2(); } @Override public IEstado desce() { //altero de estado return new RC(); } }
package me_me_elevador.logica; public class Andar2 extends Piso{ @Override public IEstado sobe() { return new Andar3(); } @Override public IEstado desce() { return new Andar1(); } }
package me_me_elevador.logica; public class Andar3 extends Piso{ @Override public IEstado sobe() { //fico no mesmo estado return this; } @Override public IEstado desce() { //altero de estado return new Andar2(); } }
package me_me_elevador.logica; public class Elevador { //é a maquina de estados, que faz alterar os estados IEstado estado; public Elevador() { //o estado incial//arranque é então: estado = new RC(); } public IEstado getEstado() { return estado; } public void setEstado(IEstado estado) { this.estado = estado; } //podia ter outras informações, como o numero de pessoas //as luzes que estão ou não ligadas.. //métodos que dão origem à mudança de estado public void sobe() { setEstado(estado.sobe()); //versão1 //this.estado = estado.sobe(); //versão2 } public void desce() { setEstado(estado.desce()); //versão1 //this.estado = estado.desce(); //versão2 } }
package me_me_elevador.logica; public interface IEstado { //acções comuns a cada uma dos estados:RC,andar1,andar2... //interface geral IEstado sobe(); IEstado desce(); }
package me_me_elevador.logica; public abstract class Piso implements IEstado { //classe para implementação default, sem alterar o estado //serve para simplifcar todas as outras @Override public IEstado sobe() { return this; } @Override public IEstado desce() { return this; } }
package me_me_elevador.logica; public class RC extends Piso{ @Override public IEstado sobe() { //altero de estado return new Andar1(); } @Override public IEstado desce() { //fico no mesmo estado return this; } }
package me_me_elevador.util; import java.util.Scanner; public class IUUtil { // v1 public static int getOpcao(String question, String... options) { System.out.println(question); char[] ops = new char[options.length]; for (int i = 0; i < options.length; i++) { char o = '\0'; int c = 0; while (c < options[i].length()) { o = Character.toUpperCase(options[i].charAt(c)); for (int j = 0; j < i; j++) { if (ops[j] == o) { o = '\0'; break; } } if (o != '\0') { break; } c++; } if (c >= options[i].length()) { return -1; } ops[i] = o; if (i > 0) { System.out.print(", "); } if (c > 0) { System.out.print(options[i].substring(0, c)); } System.out.print("(" + ops[i] + ")" + options[i].substring(c + 1)); } System.out.println(); Scanner sc = new Scanner(System.in); while (true) { System.out.print("Option: "); char o = Character.toUpperCase(sc.nextLine().charAt(0)); for (int i = 0; i < ops.length; i++) { if (o == ops[i]) { return i; } } } } }
No interface IEstado, são colocados todas as ações dos estados, mesmo que não façam sentido em alguns dos estados.
A class Piso, faz a implementação default de alguns dos estados para que não tenhamos que estar a repetir código nos diferentes estados.
Tags : java, Máquina de estados, Programação avançada
0 thoughts on “Programação avançada – capitulo 8 – maquina de estados, exemplo1”