Neste vídeo vamos falar tudo sobre o padrão de projeto State. Padrão que oferece bastante dinamismo a sistema. Neste padrão de projeto a gente vai falar sobre o comportamento de sistema tempo de execução. Então é padrão comportamental. Qual que é o objetivo do padrão? É permitir que objeto altere o seu comportamento quando seu estado interno muda. Então quando muda o estado que o sistema está, o estado que objeto está, o comportamento daquele objeto muda. Parece que o objeto mudou de classe de uma hora para outra, mas na verdade ele não mudou de classe, é o padrão state que está controlando essa mudança de comportamento. Como que a gente faz funcionar isso? Vamos lembrar o que é uma máquina de estados? Então aqui a gente tem exemplo de uma máquina de estados, pode ser de uma eclusa, ou de uma porta de elevador, por exemplo. Então a porta de elevador tem quatro estados, o estado aberto onde a porta tá aberta, e quando a porta está aberta a gente pode dar comando para ela de fechar, fecha. E daí ela muda de estado, sai do estado aberta e vai para o estado fechando. A medida que a porta está fechando, ela está no estado fechando. Se a gente mandar de novo o comando fecha enquanto ela está fechando não muda nada, ela já está fechando. Então fica nesse estado fechando. Se por acaso ela está fechando e alguém dá o comando abra, no meio do caminho ela sai do estado fechando e vai para o estado abrindo e começa a abrir. Se ela termina de abrir até o final e você pode ter, por exemplo, sensor ali que detecta que abriu até o final, se esse sensor detectou que abriu até o final daí ela volta para o estado opened, aberto. Se eu fechar e deixar ela fechar até o final e o sensor detecta que ela fechou, daí eu passo para esse estado fechado. Se eu estou no estado fechado e mando o comando fechado nada acontece, mas se eu mando o comando aberto daí muda para o estado abrindo. Então esse é exemplo de máquina de estados e a gente vê que cada estado o sistema tem comportamento pouco diferente. Então se eu dou o comando fechar e a porta já está fechada é comportamento diferente de que se a porta está aberta. Então cada estado muda pouco o comportamento do sistema e o padrão State ajuda a implementar esse tipo de coisa. Então como é que funciona? O livro GoF dá exemplo que eu gosto muito, que é exemplo de conexões de rede TCP/IP que é uma conexão da internet. Como que eles modelam isso? Então tem essa classe chamada TCPConnection que representa uma conexão de cliente até servidor numa rede de internet. E como é que funciona? Essa classe TCPConnection ele tem esses métodos, Abrir, Fechar e Acknowledge que verifica o estado da conexão. A gente poderia ter também outros comandos aqui como escrever dados na conexão, ler dados da conexão. Só que essa classe TCPConnection, na verdade, ela não implementa realmente o comando de abrir, fechar e escrever e ler dados, por que? Porque dependendo do estado da conexão, esses comandos tem significados diferentes. Então se a conexão está fechada e a gente manda abrir, daí ela tem que fazer todo processo ali, executar vários comandos de abrir uma conexão TCP/IP. Se a gente manda abrir a conexão, mas a conexão já está aberta, ela não deve fazer nada. A mesma coisa, se a gente manda ler dados de uma conexão e a conexão está aberta eu vou conseguir ler os dados, mas se eu mando ler dados de uma conexão que está fechada não vou conseguir fazer nada. Então o comportamento desses métodos muda de acordo com o estado. E como que é representado esse estado? Essa classe TCPConnection vai ter uma referência, atributo dela para uma outra classe chamada TCPState. Essa sim vai representar o estado da conexão. Essa TCPState é uma classe abstrata, Java poderia ser uma interface, e ela tem vários tipos de subclasses, de implementações, uma para cada estado que ela está. Então se a conexão está estabelecida, ela tem essa implementação TCPEstablished que vai fazer o que faz com Open, Close e outros métodos aqui quando a conexão está estabelecida. Já quando a conexão está fechada, tem esse TCPClosed, que representa o estado fechado. Quando tem uma conexão do servidor TCP/IP esperando por novas conexões do cliente, fica nesse estado TCPListen. Então cada desses estados vai implementar esses métodos de uma forma diferente e a gente vai ver que na classe TCPConnection também tem uma forma de mudar de estado para outro. Eu vou mostrar para vocês aqui exemplo, só que dessa vez eu vou variar pouco. Eu sempre tenho mostrado exemplos Java e outras linguagens que eu gosto muito tipo do Python e do Ruby, mas vamos mudar. Vou usar o exemplo do GoF mesmo que eu peguei desse site aqui, se vocês quiserem vocês podem entrar nesse site para ver o endereço, o código completo. É site da Universidade de Illinois Chicago e é C++. C++ é uma linguagem que eu acho pouco feinha, mas que é uma linguagem que às vezes a gente usa quando você quer muito desempenho, sistema de altíssimo desempenho, mantendo a orientação objetos, C++ pode ser a linguagem que a gente tem que escolher. Então como é que funciona a classe TCPConnection C++? Tem esses vários métodos, TCPConnection, esse aqui é construtor e depois tem dois tipos de Opened, ativo e passivo, fechar, Closed, Send é para mandar dados numa determinada conexão e outros comandos. Aqui para receber dados e assim por diante. Mas tem também esse método ChangeState que é para mudar de estado para outro. E daí essa classe TCPConnection tem uma variável de instância que é esse State. Sublinhado State é uma referência, apontador, C++ tem apontadores, é apontador para objeto do tipo TCPState. E a gente vai ver a implementação de todos esses métodos, na verdade eles simplesmente delegam para esse TCPState e a gente pode mudar de estado para outro de acordo com o estado da conexão. E daí como funciona então? Esse TCPState, na verdade é essa classe aqui onde a gente vai ter esses vários métodos abstratos, isso aqui vai ser uma classe abstrata, que aqui tá definindo os parâmetros, a assinatura dos métodos. E tem também esse método ChangeState, que ele faz uma determinada conexão mudar de estado para outro estado. Então esse ChangeState ele vai atualizar o valor dessa variável state. Daí como é que é a implementação dessas coisas? Aqui tem o construtor do TCPConnection. O que faz o construtor? Na variável state, que é essa variável que eu falei que guarda o estado, ele faz o TCPClosed Instance. Esse aqui está usando o padrão single tone para pegar uma instância dessa classe TCPClosed. Então ele usa single tones para estes vários estados concretos, para o TCPState. Então quando eu crio uma nova conexão ela se inicializa no estado fechado, inicialmente a conexão está fechada, o construtor já deixa fechada. Depois eu posso chamar esse método ChangeState para mudar de estado para o outro. E daí a gente vai ver que todos esses métodos ActiveOpen, PassiveOpen, Close, Acknowledged, Syncronize e assim por diante, a única coisa que eles fazem é delegar a execução do método para o state. Então por exemplo, ActiveOpen simplesmente está chamando o método ActiveOpen do state. Essa flechinha aqui C++ é chamada de método, Java seria ponto só. Então estou delegando a execução do ActiveOpen para a minha instância, state e sempre passo como parâmetro apontador para eu mesmo. This é apontador para a própria TCPConnection porque a TCPConnection pode ter algum estado que seja útil para implementar esse método ActiveOpen. Então todos os métodos são implementados por delegação para o meu estado e depois a gente tem a classe TCPState, que aí implementa realmente os vários métodos. Vamos ver aqui exemplos de implementação. Então por exemplo, a classe TCPEstablished é uma subclasse de TCPState, esse é o jeito de dizer que é uma subclasse C++, ele vai ter essa referência aqui para uma instância, usando o padrão single tone e vai implementar esses dois métodos. A implementação vem mais para frente, por exemplo aqui é realmente [SOM] implementação. Então por exemplo, na classe TCPClosed se vem ActiveOpen passando como parâmetro uma conexão, daí tá simplesmente como comentário mas viria uma série de comandos usando sockets de TCP/IP para estabelecer a conexão. Então serão vários comandos para estabelecer a conexão. Depois que você tem a certeza que a conexão está estabelecida, daí ele chama o método para mudar de estado a minha conexão teve que mudar de estado para esse TCPEstablished. Então o próprio método, a própria classe Closed aqui faz a mudança de estado e muda o estado chamando single tom aqui para pegar uma instância desse TCPEstablished. Então depois desse comando muda o comportamento dessa TCPConnection, porque a TCPConnection deixou de ter como seu estado TCPClosed e passou a ter como seu estado o TCPEstablished. Então é padrão bem interessante, quem quiser olhar com mais calma esse código C++ que eu passei muito rápido, entra nesse endereço e dá uma olhada. É legal você ter pouco de contato com o código C++ que a gente vai ver que ele é bem semelhante ao Java, mas diferente vários aspectos. Então voltando para onde a gente estava, vamos ver o formato genérico do padrão. A ideia que você vai ter uma classe, que aqui é chamada de contexto, que tem algumas requisições, alguns métodos. Mas você quer que a implementação desse método mude a medida que muda o estado a classe. Como você faz isso? Você faz essa classe ter apontador para uma outra classe que vai ser estado e aqui vai ser uma interface ou uma classe abstrata e para cada estado você implementa uma classe concreta e esse método aqui, que aqui está chamado de Handle, você implementa de formas diferentes cada desses estados. E daí o contexto, a implementação desse método, o contexto vai ser simplesmente delegar para o estado a execução do método. Então dessa forma você vai mudando de estado, vai mudando o comportamento. Esse é o formato genérico do padrão. Para terminar, caso de uso que o livro GoF apresenta para esse padrão é programa para fazer desenhos. Para fazer desenhos de círculos, figuras geométricas e etc. Tem dois programas bem antigos lá da década de 90 que já implementavam esse padrão, os programas Hotdraw e Unidraw. Você com certeza já usou algum programinha desse tipo. E qual é a ideia do uso desse padrão? Esses programas de desenho, geral, tem várias ferramentas ali, uma ferramenta para você fazer seleções, uma ferramenta para se criar novas figuras geométricas, uma ferramenta para você digitar algum texto no meio do seu desenho. E você vai usar o mouse, apertar botões do mouse, digitar coisa no teclado, só que o que o mouse faz, o que o teclado faz diferentes momentos depende de qual ferramenta que você usou. Então aqui eles tem esse DrawingController, o controlador do desenho, que ele tem uma referência para uma ferramenta e essa ferramenta que está sendo usada pode mudar de momento para o outro. Então pode ter uma ferramenta de criar novos elementos gráficos, pode ter uma ferramenta de selecionar, pode ter uma ferramenta de inserir texto. E daí, uma vez que você aperta botão do mouse, ou que você aperta algo do teclado o comportamento muda de acordo com qual ferramenta você está selecionando. Para fazer essa apresentação eu estou usando, por exemplo, o LibreOffice e aqui tem algo semelhante. Então, por exemplo, se eu aperto no mouse essa cruzinha, se eu aperto aqui, mudo a minha ferramenta para essa ferramenta de zoom o mouse vira uma lupa. E agora quando eu clico aqui, o que ele faz? Ele faz zoom. [SOM] Então a gente vê que o comportamento mudou. Se eu agora aperto e mudo para esta ferramenta de desenhar uma curva, mudou até o formato do mouse, virou essa coisa de desenhar uma curva. Daí se eu venho aqui eu desenho uma curva. Então o comportamento do sistema muda de acordo com o estado e para mudar de estado para outro eu seleciono essas diferentes ferramentas que tem no meu sistema. Então provavelmente o LibreOffice também usa o padrão state. Então resumindo o padrão state dá flexibilidade sistema permitindo que ele tenha comportamentos diferentes diferentes momentos. Parece que o objeto mudou de classe, então é jeito de você dar bastante dinamismo para o seu sistema. Espero que vocês tenham gostado do state.