Floresta

Logo da aplicação Android Floresta
Floresta

A aplicação tem como principal função de ajudar os intervenientes a registar o peso das árvores de forma fácil e rápido.

Com esta aplicação, é possível registar os pesos das árvores e, no término do registo, fornecer o orçamento previsto. Também é possivel partilhar dados registados e alterar os preços de vários tipos de árvore. Actualmente, na aplicação, existe Pinheiro Manso, Pinheiro Bravo, Sobreiro e Eucalipto.

Experimentam e dão-me o vosso feedback.

Caso queiram acrescentar mais funcionalidades à aplicação Floresta, contactam-me!

MVC – Model, View and Controller

Design patterns são as chaves para o estudo de MVC. Se teve dificuldades de entender o funcionamento de MVC, aconselho vivamente o estudo de Design Patterns antes de MVC.

  • Model – Model lida com todos os dados, todos os estados e toda a lógica da aplicação. O modelo é abstraído para a View e a Controller, contudo fornece uma interface para manipular e retornar o seu estado e pode enviar notificações de mudanças do estado aos observers. Dum ponto de vista de design pattern, a Observer Pattern é aplicada no Model.
  • View – View dá uma apresentação do Model. A View, geralmente, obtém o estado e os dados que são necessários para mostrar o output. Nota que os dados vêem. Dum ponto de vista de design pattern, a Composite Pattern é aplicada na View.
  • Controller – lida com as acções do utilizador e descobre a melhor estratégia ao Model. Dum ponto de vista de design pattern, a Strategy Pattern é aplicada no Controller.

State Pattern vs Strategy Pattern

Se repararem bem, os diagramas de classes da Strategy Pattern e da State Pattern são iguais mas diferem no seu propósito.

Com a State Pattern, temos um conjunto de comportamentos encapsulados nos objectos State; em qualquer altura, o objecto Context irá delegar um dos seus estados. Ao longo do tempo, o estado actual muda através dum conjunto de estados para reflectir o estado interno da Context. Por esta razão, o comportamento da Context muda ao longo do tempo. O cliente sabe, normalmente, muito pouco, se existerem, acerca dos objectos de estado (State).

Com Strategy Pattern, o cliente especifica o contexto composto com objectos Strategy. Enquanto a Strategy Pattern fornece a flexibilidade de mudar o objecto Strategy na execução, frequentemente, há um objecto Strategy que é mais apropriado para objecto Contexto.

Em geral, considera da Strategy Pattern como uma alternativa flexível para herança. Se usar herança para definir o comportamento duma classe então estará preso com aquele comportamento mesmo na altura da necessidade de mudá-lo.

Também considera da State Pattern como uma alternativa de colocação de muitas declarações condicionais (if…else) por encapsular os comportamentos dentro dos objectos State. Pode simplesmente mudar o estado do objecto no contexto de mudar o seu comportamento.

State Pattern

State – allows an object to alter its behavior when its iternal state changes. The object will appear to change its class. – Page 410, Chapter 10, Head First Design Patterns

Em português, a State Pattern permite um objecto alterar o seu comportamento quando o seu estado interno muda. O objecto, ao mudar o seu estado, será instanciado pela outra classe que define o seu estado actual.

State Pattern
Diagrama de classes da State Pattern

Analisando o diagrama de classes da State Pattern, considere as seguintes exposições:

  • Context: define a interface de interesses aos clientes. Mantém a referência duma subclasse ConcreteState que define o seu estado actual;
  • State: define uma interface para encapsular o comportamento associado com um determinado estado da Context;
  • ConcreteState: cada subclasse implementa um comportamento associado ao estado da Context;

Amostra de código da classe “Context”

public class GumballMachine {
 
	State soldOutState;
	State noQuarterState;
	State hasQuarterState;
	State soldState;
 
	State state = soldOutState;
	int count = 0;
 
	public GumballMachine(int numberGumballs) {
		soldOutState = new SoldOutState(this);
		noQuarterState = new NoQuarterState(this);
		hasQuarterState = new HasQuarterState(this);
		soldState = new SoldState(this);

		this.count = numberGumballs;
 		if (numberGumballs > 0) {
			state = noQuarterState;
		} 
	}
 
	public void insertQuarter() {
		state.insertQuarter();
	}
 
	public void ejectQuarter() {
		state.ejectQuarter();
	}
 
	public void turnCrank() {
		state.turnCrank();
		state.dispense();
	}

	void setState(State state) {
		this.state = state;
	}
 
	void releaseBall() {
		System.out.println("A gumball comes rolling out the slot...");
		if (count != 0) {
			count = count - 1;
		}
	}
 
	int getCount() {
		return count;
	}
 
	void refill(int count) {
		this.count = count;
		state = noQuarterState;
	}

    public State getState() {
        return state;
    }

    public State getSoldOutState() {
        return soldOutState;
    }

    public State getNoQuarterState() {
        return noQuarterState;
    }

    public State getHasQuarterState() {
        return hasQuarterState;
    }

    public State getSoldState() {
        return soldState;
    }
 
	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("\nMighty Gumball, Inc.");
		result.append("\nJava-enabled Standing Gumball Model #2004");
		result.append("\nInventory: " + count + " gumball");
		if (count != 1) {
			result.append("s");
		}
		result.append("\n");
		result.append("Machine is " + state + "\n");
		return result.toString();
	}
}

Amostra de código da classe “State”

public interface State {
 
	public void insertQuarter();
	public void ejectQuarter();
	public void turnCrank();
	public void dispense();
}

Amostra de código da classe “ConcreteState”

public class HasQuarterState implements State {
	GumballMachine gumballMachine;
 
	public HasQuarterState(GumballMachine gumballMachine) {
		this.gumballMachine = gumballMachine;
	}
  
	public void insertQuarter() {
		System.out.println("You can't insert another quarter");
	}
 
	public void ejectQuarter() {
		System.out.println("Quarter returned");
		gumballMachine.setState(gumballMachine.getNoQuarterState());
	}
 
	public void turnCrank() {
		System.out.println("You turned...");
		gumballMachine.setState(gumballMachine.getSoldState());
	}

    public void dispense() {
        System.out.println("No gumball dispensed");
    }
 
	public String toString() {
		return "waiting for turn of crank";
	}
}

Quando se deve usar State Pattern?

  1. quando um comportamento dum objecto depende o seu estado e deve mudar o seu comportamento na execução dependendo num determinado estado;
  2. quando existir várias declarações condicionais(if…else) que dependem do estado dum objecto. Este estado, normalmente, é representado por uma ou mais constantes enumeradas;

As conclusões que eu retiro deste estudo são:

  • coloca todos os comportamentos associados a um determinado estado para um objecto porque todas as especificações de estado residem nas classes ConcreteState. Novos estados e transições podem ser adicionados facilmente definindo as novas subclasses;
  • as transicções de estado são explicitas;
  • os objectos da classe State podem ser partilhados.