A camada de serviços


A camada de serviços contém a concretização das várias opções oferecidas pelos vários menus da aplicação. Esta camada é composta essencialmente pelos vários comandos ou serviços que concretizam as opções disponibilizadas nos vários menus da aplicação. Nesta secção apresentamos apenas parte do código desta camada. Os restantes comandos estão disponíveis no código disponibilizado dom a concretização desta aplicação exemplo

Listar os números inseridos

Este comando é responsável por apresentar todos os números guardados pela aplicação. A série de números é mantida pela classe IntegerManger da camada de lógica de negócio. Desta forma, a entidade receiver que deve estar associada a este comando é do tipo IntegerManager. A associação entre instâncias deste comando e o seu receiver é estabelecida no processo de criação de um comando pelo que o construtor desta classe deve ter o IntegerManager a associar como parâmetro. A concretização da funcionaldiade deste comando deve ser realizada no método execute(): primeiro, pede a lista de números inseridos pelo utilizador à entidade do domínio da aplicação que mantém a série de números inseridos pelo utilizador. Esta entidade é acedida através do atributo _receiver. Depois, constroi-se incrementalmente o texto a apresentar ao utilizador adicionando cada número da série numa linha separada através da invocação do método addLine sobre a instância de Display que está disponível para qualquer comando via atributo _display. Após se ter construído todo o texto, indica-se ao Display referenciado por _display para finalmente apresentar o texto final ao utilizador invocando o método display().

package ex.app.main;

import java.util.List;
import ex.core.IntegerManager;
import pt.tecnico.uilib.menus.Command;
import java.util.function.Predicate;
public class ListNumbers extends Command<IntegerManager> {        
  //Constructor
  public ListNumbers(IntegerManager ent) {
    super("Listar Números", ent, x -> { return !ent.getNumbers().isEmpty();});
  }
  protected void execute() { // executed when this option is selected
    List<Integer> list = _receiver.getNumbers();
    
    for (Integer number : list)
      _display.addLine(number.toString());
    _display.display();
  }
}

O construtor desta classe não invoca o construtor usual da super classe (Command), utilizando outro que permite a especificação da visibilidade do comando a criar. Neste caso concreto, o comando criaodo só é visível caso a entidade receiver do comando tenha números. Se o IntegerManager não tiver nenhum número associado, então este comando não será visível quando o menu dor apresentado.

Apresentar o menu de edição

Este comando é responsável por apresentar o menu de edição. Assim, a concretização do método execute() é muito simples: apenas tem que se criar uma instância de EditMenu (a classe que define o menu de edição) e abrir o menu através da invocação do método open() sobre o menu criado.


package ex.app.main;

import ex.core.IntegerManager;
import ex.app.edit.EditMenu;
import pt.tecnico.uilib.menus.Command;

public class ShowEditMenu extends Command<IntegerManager> {        
  //Constructor
  public ShowEditMenu(IntegerManager ent) {
    super("Abrir Menu Edição", ent);
  }
  
  protected void execute() { // executed when this option is selected
    EditMenu menu = new EditMenu(_receiver);
    menu.open();
  }
}
Esta funcionalidade pode ser concretizada de uma forma mais simples utilizando o comando DoOpenMenu já fornecedido pela framework. Neste caso, a criação do menu principal deve criar uma instância de DoOpenmenu em vez de ShowEditMenu (que deixa de ser necessário e pode ser apagado):
package ex.app.main;

import ex.core.IntegerManager;
import pt.tecnico.uilib.menus.Menu;
import pt.tecnico.uilib.menus.DoOpenMenu;
import ex.app.edit.EditMenu;

public class MainMenu extends Menu {

    //Constructor
    public MainMenu(IntegerManager ent) {
        super("MENU PRINCIPAL",
              new ListNumbers(ent), new ShowNumberOfIntegers(ent), new DoOpenMenu("Abrir Menu Edição", new EditMenu(ent))
              //new ListNumbers(ent), new ShowNumberOfIntegers(ent), new ShowEditMenu(ent)
              );
    }
}

Adicionar um número 

Dado que apenas é necessário ler um inteiro, o formulário apenas irá conter um pedido do tipo InputInteger, o qual tem que ser criado e adicionado ao formulário. Uma forma mais rápida de especificar o código para criar o pedido e associá-lo ao formulário é utilizar um dos vários métodos add disponíveis na classe Form. Existe um método add para cada tipo de dados a inserir pelo utilizador. Neste exemplo é utilizado o método addInputInteger, o qual recebe a mensagem a colocar no pedido e cria o pedido, associa o pedido criado ao formulário e devolve uma referência para o pedido criado. Utilizando esta abordagem, o método execute do comando apenas terá que invocar o método parse sobre o formulário do comando e depois aceder ao valor inserido para cada pedido invocando método value() sobre o pedido.


package ex.app.edit;

import ex.core.IntegerManager;
import pt.tecnico.uilib.menus.Command;

public class AddNumber extends Command<IntegerManager> {
  //Constructor
  public AddNumber(IntegerManager ent) {
    super("Adicionar Número", ent);
    addIntegerField("number", "Introduza um número: ");
  }

  protected void execute() {  // executed when this option is selected
    Integer number = integerField("number");
    String message;

    if (_receiver.addNumber(number))
      message = "Número adicionado: " + number;
    else
      message = "Número não adicionado";

    _display.popup(message);
  }
}