# State

State é um padrão de projeto de software usado quando o comportamento de um objeto muda, dependendo do seu estado.

## Introdução

Em certas ocasiões, quando o contexto em que está a desenvolver requer um objeto que possua comportamentos diferentes dependendo de qual estado se encontra, é difícil manejar a mudança de comportamento e os estados desse objeto, tudo dentro do mesmo bloco de código. O padrão State propõe uma solução para esta complicação, criando basicamente, um objeto para cada estado possível do objeto que o chama.

## Objetivo

Permite que um objeto altere seu comportamento de acordo com o estado interno que se encontra em um momento dado.

## Motivação

O padrão State é motivado por aqueles objetos que, em seu estado atual, varia o seu comportamento devido as diferentes mensagens que possa receber. Como exemplo, tomamos uma classe Livro, um objeto desta classe terá respostas diferentes, dependendo do seu estado(Disponível ou Emprestado). Por exemplo invocando o método reservar de um objeto da classe Livro seu comportamento será diferente, se o Livro está no estado Disponível ou no estado Emprestado.

### Diagrama de Classes

O seguinte diagrama é uma representação da estrutura e relações das classes que servem de modelo para os objetos.

### Diagrama de Estados

No seguinte diagrama representamos os possíveis estados ou situações em que um Livro pode se encontrar no decorrer da execução em nosso sistema.

## Problema

Há uma extrema complexidade no código quando tentamos gerênciar comportamentos diferentes, dependendo de um número de estados diferentes. Também manter o código torna-se difícil, e mesmo em alguns casos, podem apontar a uma inconsistência de estados atuais na forma de implementação dos diferentes estados no código (por exemplo, com variáveis ​​para cada estado).

## Considerações

Devemos analisar a complexidade em comparação com outras soluções.

## Solução

Se implementa uma classe para cada estado diferente do objeto e o desenvolvimento de cada método para cada estado em particular. O objeto da classe a que pertencem esses estados resolvem os diferentes comportamentos, dependendo de sua condição, com as instâncias das classes de estado. Assim, sempre está presente em um objeto o seu estado atual e se comunica com ele a resolvendo suas responsabilidades.
A idéia principal do padrão State é a introdução de um classe abstrata EstadoLivro que representa os estados e uma interface para todas as classes que representam os próprios estados. Por exemplo, as classes Disponível e Prestado implementam responsabilidades especiais para os estados Disponível e Prestado respectivamente do objeto Livro. A classe Livro mantém uma instância de alguma subclasse de EstadoLivro com o atributo estado que representa o estado actual do Livro. Na implementação dos métodos de Livro haverá chamadas a esses objetos que serão representados pelo atributo estado para a execução das responsabilidades, dependendo de qual estado se encontre em esse momento, enviará essas chamadas para um objeto ou outro das subclasses de EstadoLivro.

## Os participantes

* Contexto: Este integrante define a interface com o cliente. Mantém uma instância de Estado Concreto que define seu estado atual.
* Estado: Define uma interface para encapsular as responsabilidades associadas a um estado particular de contexto.
* Subclasse EstadoConcreto: Cada uma dessas subclasses implementa o comportamento ou responsabilidade de Contexto.
O Contexto delega o estado específico para o objeto EstadoConcreto atual. Um objeto de Contexto pode passar-se como parâmetro a um objeto Estado. Assim, a classe Estado pode acessar o contexto, se fosse necessário. Contexto é a interface principal para o cliente. O cliente pode configurar um contexto com objetos Estado. Uma vez feito isso, os clientes não têm de lidar com objetos de tipo Estado diretamente. Tanto o objeto de Contexto como os objetos de EstadoConcreto podem decidir a mudança de estado.

## Colaborações

O padrão de State pode usar o padrão Singleton quando necessita a existência de apenas uma instância de cada estado. Se pode utilizar quando se compartem os objetos como Flyweight existindo uma única instância de cada Estado e esta é compartilhada com mais de um objeto.

## Como funciona

A classe Contexto envia mensagens para os objetos de EstadoConcreto dentro de seu código para dar a estes a responsabilidade que deve ser cumprida pelo objeto Contexto. Então, o objeto Contexto vai mudando as responsabilidades de acordo com o estado em que se encontra, devido a que também muda de objeto EstadoConcreto ao fazer a mudança de estado.

## Quando usá-lo?

Está recomendado quando um determinado objeto tem estados e responsabilidades diferentes, dependendo de qual estado você está em determinado momento. Também pode ser usada para simplificar os casos em que há código complicado e extenso de decisão que depende do estado do objeto

## Vantagens e desvantagens

São as seguintes vantagens:
* É fácil de localizar as responsabilidades de estados específicos, devido a que os encontram nas classes que correspondem a cada estado. Isto proporciona uma maior clareza no desenvolvimento e na manutenção subsequente. Esta facilidade é fornecida pelo fato de que diferentes estados são representados por um único atributo (estado) e não envolvidos em diferentes variáveis ​​e grandes condicionais.
* Faz as mudanças de estado explícitas, posto que em outro tipo de implantação os estados são alterados, modificando os valores em variáveis, enquanto aqui fazer-se representar cada estado.
* Os objetos Estado podem ser compartilhados se eles não contêm variáveis ​​de instância, isto pode ser alcançado se o estado está totalmente codificado representando seu tipo. Quando isso é feito, os estados são flyweights sem estado intrínseco.
* Facilita a expansão de estados.
* Permite a um objeto alterar de classe em tempo de execução dado que ao modificar suas responsabilidades pela de outro objeto de outra classe, a herança e responsabilidades do primeiro mudaram pelas do segundo.
Desvantagem:
* Aumenta o número de subclasses.

## Conclusões

O padrão não indica exatamente onde definir as transições de um estado para outro. Há duas maneiras de contornar isso. Uma delas é definir essas transições dentro da classe Contexto, a outra é definir essas transições nas subclasses de Estado. É mais conveniente utilizar a primeira solução quando o critério a ser aplicado é fixo, ou seja, não mudará. O segundo é conveniente quando este critério é dinâmico. A desvantagem aqui é apresentada na dependência de código entre as subclasses.
Precisamos também avaliar a implementação ao criar instâncias de estado concreto diferentes ou usar a mesma instância compartilhada. Isto irá depender se a mudança de estado é menos frequente ou mais frequente, respectivamente.