Os eventos são usados apenas para programação da GUI?
Como você lida com a programação de back-end normal quando algo acontece com essa outra coisa?
Os eventos são usados apenas para programação da GUI?
Como você lida com a programação de back-end normal quando algo acontece com essa outra coisa?
Respostas:
Não. Eles são realmente úteis para implementar Observadores e garantir que as classes sejam fechadas para modificação.
Digamos que temos um método que registra novos usuários.
public void Register(user) {
db.Save(user);
}
Então alguém decide que um email deve ser enviado. Nós poderíamos fazer isso:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
Mas acabamos de modificar uma classe que deveria estar fechada para modificação. Provavelmente é bom para esse pseudocódigo simples, mas provavelmente o caminho para a loucura no código de produção. Quanto tempo até esse método ter 30 linhas de código pouco relacionadas ao objetivo original de criar um novo usuário?
É muito mais agradável permitir que a classe execute sua funcionalidade principal e promover um evento informando quem está ouvindo que um usuário foi registrado, e eles podem tomar as medidas necessárias (como enviar um email).
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
Isso mantém nosso código limpo e flexível. Uma das partes geralmente negligenciadas da OOP é que as classes enviam mensagens umas para as outras. Eventos são essas mensagens.
Não.
Um exemplo clássico de eventos usados na lógica que não é da GUI são os gatilhos do banco de dados.
Triggers são códigos executados quando um determinado evento acontece (INSERT, DELETE, etc). Parece um evento para mim.
Esta é a definição de evento da Wikipedia:
Na computação, um evento é uma ação ou ocorrência reconhecida pelo software que pode ser manipulada pelo software. Eventos de computador podem ser gerados ou acionados pelo sistema, pelo usuário ou de outras maneiras. Normalmente, os eventos são manipulados de forma síncrona com o fluxo do programa, ou seja, o software pode ter um ou mais locais dedicados onde os eventos são manipulados, freqüentemente um loop de eventos. Uma fonte de eventos inclui o usuário, que pode interagir com o software por meio de, por exemplo, pressionamentos de tecla no teclado. Outra fonte é um dispositivo de hardware, como um timer. O software também pode acionar seu próprio conjunto de eventos no loop de eventos, por exemplo, para comunicar a conclusão de uma tarefa. Diz-se que o software que altera seu comportamento em resposta a eventos é orientado a eventos, geralmente com o objetivo de ser interativo.
Nem todos os eventos são gerados pelo usuário. Alguns são gerados por um timer como um crontab de um INSERT de banco de dados, como mencionei antes.
A definição também afirma que alguns programas ou sistemas são "orientados a eventos, geralmente com o objetivo de serem interativos" , dos quais se pode derivar que o objetivo ou a utilidade dos eventos não são apenas, mas frequentemente, fornecer interatividade (como GUIs) embora não necessariamente GUIs, pois os programas CLI também podem ser interativos).
Na verdade, a programação baseada em eventos também é usada para programação de servidores de alto desempenho.
Em uma carga de trabalho típica do servidor, na maioria das vezes o processamento de um resultado realmente vem de E / S. Por exemplo, retirar dados de uma unidade de disco rígido (7200 RPM) pode levar até 8,3 ms. Para um processador moderno de GHz, isso equivaleria a ~ 1 milhão de ciclos de clock. Se uma CPU esperasse os dados de cada vez (sem fazer nada), perderíamos MUITOS ciclos de clock.
As técnicas de programação tradicionais resolvem isso introduzindo vários threads . A CPU tenta executar centenas de threads simultaneamente. No entanto, o problema desse modelo é que, cada vez que uma CPU alterna o encadeamento, são necessários centenas de ciclos de clock para alternar o contexto . Uma troca de contexto ocorre quando a CPU copia a memória local do encadeamento nos registros da CPU e também armazena o registro / estado do encadeamento antigo na RAM.
Além disso, cada thread deve usar uma certa quantidade de memória para armazenar seu estado.
Hoje, houve um empurrão para os servidores que possuem um único encadeamento, executado em um loop. Em seguida, as peças de trabalho são enviadas para uma bomba de mensagens , que atua como uma fila para o encadeamento único (como em um encadeamento da interface do usuário). Em vez de esperar o trabalho terminar, a CPU define um evento de retorno de chamada, para coisas como acesso à unidade de disco rígido. O que reduz a alternância de contexto.
O melhor exemplo desse servidor é o Node.js , que demonstrou ser capaz de lidar com 1 milhão de conexões simultâneas com hardware modesto, enquanto um servidor Java / Tomcat enfrentaria alguns milhares.
Os eventos também são muito usados na programação de rede (por exemplo, Nginx) para evitar loops de espera ocupada e fornecer uma interface limpa para saber exatamente quando uma determinada operação está disponível (E / S, dados urgentes etc.). Essa também é uma solução para o problema do C10k .
A idéia básica é fornecer ao sistema operacional um conjunto de soquetes (ou seja, conexões de rede) para monitorar eventos, todos eles ou apenas alguns dos quais você está particularmente interessado (dados disponíveis para leitura, por exemplo); quando essa atividade é detectada pelo sistema operacional em um dos soquetes da lista, você recebe uma notificação do evento que estava procurando pela API, que precisará descobrir de onde vem e agir de acordo. .
Agora, essa é uma visão abstrata e de baixo nível, além de ser difícil de obter escala adequada. No entanto, existem muitas estruturas de nível superior que lidam com isso de maneira uniforme entre plataformas: Twisted for Python, Boost.Asio para C ++ ou libevent for C me vem à mente.
Os sistemas incorporados quase sempre são inerentemente orientados a eventos, mesmo que não sejam programados explicitamente como tal.
Esses eventos vêm de interrupções de hardware, pressionamentos de botão, leituras de período analógico-digital, expiração do temporizador etc.
Os sistemas embarcados de baixa potência são ainda mais propensos a serem orientados a eventos; eles passam a maior parte do tempo dormindo (CPU dormindo no modo de baixo consumo de energia), esperando que algo aconteça (que "algo" é um evento).
Uma das estruturas mais comuns e populares para sistemas embarcados controlados por eventos é a Quantum Platform (QP) (o QP também funciona no Linux, Windows e em qualquer sistema operacional semelhante ao unix.) As máquinas de estado são uma opção natural para a programação orientada a eventos, como o programa não é "seqüencial" no sentido típico, é um conjunto de "retornos de chamada" que são chamados, dependendo do estado do sistema e do evento atual.
Mensagens de evento Gregor Hohpe.
Arquiteturas orientadas a eventos Gregor Hohpe.
Arquitetura SEDA , Galês, Culler, Brewer.
como você lida com a programação de back-end normal quando algo acontece faz essa outra coisa?
Máquina de estados finitos é uma abordagem comum
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
Nos sistemas incorporados, os eventos ocorrem durante as interrupções. Existem muitas fontes de interrupções, desde temporizadores até E / S.
Além disso, o RTOS também pode ter eventos. Um exemplo está aguardando uma mensagem de outra tarefa.
Para sistemas não incorporados, mas algo que eu estava fazendo em C # era o sistema SCADA. Havia muitos eventos vinculados ao que estava acontecendo no armazém quando a carga foi descarregada, parte do evento gerado pelo sistema e outra parte estava gravando um novo estado no banco de dados. É claro que tínhamos algum cliente da GUI, mas era apenas para mostrar o estado do banco de dados que refletia o estado do armazém. Portanto, era um software de servidor back-end baseado em eventos e encadeamentos. Muito difícil de desenvolver.