DDD 도메인 이벤트

오늘 나는 2022년 6월 5일을 배웠다


  • Eventos de domínio
  • Quando utilizar
  • Componentes
  • Dinâmica
  • Implementação



  • Eventos de domínio



    A essência de um evento de domínio é que você o usa para capturar coisas que podem desencadear uma mudança no estado do aplicativo que você está desenvolvendo. Esses objetos de evento são processados para causar alterações no sistema e armazenados parar fornecer um AuditLog
    Fowler, Martin



    Ou seja quando algo acontece no sistema eu posso baseado nesse evento executar uma operação e armazenar o evento para um caso deauditia no futuro

    Todo evento deve ser Representativeado em uma ação presentada no passado, exemplo UserCreated


    Quando 유틸리티



    Normalmente um domain event deve ser utilizado quando queremos notificar outros Bounded Contexts de uma mudança de estado

    예: Um sistema de E-commerce quando um pedido é criado, podemos emitir um evento de OrderPlaced e então o boundedContext de emissão de notas fiscais vai escutar esse evento e emitir a nota para aquele pedido


    구성품


  • 이벤트
    Tem uma data e hora, e contem o que aconteceu naquela data e hora
    예: produto com nome X mudou para Y
  • 핸들러
    Executa o processamento quando o evento é chamado
    예: depois de criar um usuário eviar um email, a parte de enviar email é um handler
  • 이벤트 디스패처
    Armazenar 및 Executar OS Handlers de um event quando ele é disparado
  • 에 대한 응답



    디나미카


  • 크리아 음 "이벤트 디스패처"
  • 크리아 음 "이벤트"
  • "Handler"또는 "Evento"항목
  • "이벤트 디스패처"가 아닌 핸들러 또는 이벤트 등록자

  • E ai quando dermos um notify no Event dispatcher passando o evento, todos os handlers serão executados


    구현



    nossas 인터페이스로서 primeiro vamos criar는 펠로 디스패처, 펠로스 이벤트 및 펠로스 핸들러를 구현합니다.

    export interface EventInterface<T=any> {
      dateTimeOcurred: Date;
      eventData: T;
    }
    
    export interface EventHandlerInterface<T extends EventInterface=EventInterface>{
      handle(event: T): void;
    }
    
    export interface EventDispatcherInterface{
      notify(event: EventInterface): void;
      register(eventName: string, eventHandler: EventHandlerInterface): void;
      unregister(eventName: string, eventHandler: EventHandlerInterface): void;
      unregisterAll(): void;
    }
    


    e ai vamos criar a nossa classe de 이벤트 디스패처

    export class EventDispatcher implements EventDispatcherInterface{
      private eventHandlers: { [eventName: string]: EventHandlerInterface[] } = {};
    
    
      get getEventsHandler(): { [eventName: string]: EventHandlerInterface[] }{
        return this.eventHandlers;
      } 
    
      notify(event: EventInterface): void {
        const eventName = event.constructor.name;
        if(this.eventHandlers[eventName]){
          this.eventHandlers[eventName].forEach(eventHandler => {
            eventHandler.handle(event);
          })
        }
      }
    
      register(eventName: string, eventHandler: EventHandlerInterface<EventInterface>): void {
            if (!this.eventHandlers[eventName]) {
            this.eventHandlers[eventName] = [];
          }
    
          this.eventHandlers[eventName].push(eventHandler);
      }
    
      unregister(eventName: string, eventHandler: EventHandlerInterface<EventInterface>): void {
        if (!this.eventHandlers[eventName]) {
          throw new Error(`${eventName} event does not exist.`);
        }
    
        const index = this.eventHandlers[eventName].indexOf(eventHandler);
        if (index !== -1){
          this.eventHandlers[eventName].splice(index, 1);
        }else{
          throw new Error(`${eventName} event handler not registered.`);
        }
      }
      unregisterAll(): void {
        this.eventHandlers = {};
      }
    
    }
    


    Nessa classe vamos ter um objeto com os 이벤트 핸들러 e vamos verificar se o evento qual o handler quer ser registrado já existe, se já existir vamos somente adicionar o handler ao evento, se não existir vamos criar o evento e adicionar o handler em seguida . Também nessa classe temos o método notify, que recebe o evento e percorre todos os 핸들러 associados a ele executando o método 핸들

    E ai vamos criar o nosso evento

    export class ProductCreatedEvent implements EventInterface{
      dateTimeOcurred: Date;
      eventData: any;
    
      constructor(eventData: any){
        this.dateTimeOcurred = new Date();
        this.eventData = eventData;
      }
    }
    


    eo nosso 핸들러 para esse evento que nesse caso será o de enviar 이메일 quando o produto for criado

    export class SendEmailWhenProductIsCreatedHandler implements EventHandlerInterface<ProductCreatedEvent>{
      handle(event: ProductCreatedEvent): void {
        console.log("Sending email to user...")
      }
    }
    


    e para fazermos isso funcionar basta a seguinte implementação

        const eventDispatcher = new EventDispatcher();
        const eventHandler = new SendEmailWhenProductIsCreatedHandler();
        const spyEventHandler = jest.spyOn(eventHandler, "handle");
    
        eventDispatcher.register("ProductCreatedEvent", eventHandler)
    
    
        const productCreatedEvent = new ProductCreatedEvent({
          name: "Product 1",
          description: "Product 1 description",
          price: 100
        });
    
        eventDispatcher.notify(productCreatedEvent)
    


    então toda vez que um novo produto for criado basta a chamarmos a função notify que executa todos os 핸들러 associados ao evento que ela recebeu

    Ainda estou aprendendo sobre DDD e se quiser ver melhor o código pode dar uma olhada nesse Repositório

    좋은 웹페이지 즐겨찾기