Skip to content

도메인 개발 후 Alarm 적용 방법

Jaehun Choi edited this page Sep 24, 2022 · 1 revision

Alarm

Alarm의 구조는 아래와 같이 이뤄져있다.

Alarm EventListener -> AlarmEvent <- each domains

1. Events

도메인 이벤트를 발행하는 클래스. 최초에 Bean이 생성될 때 ApplicationContext를 set하여 EventPublisher를 생성한다.

도메인 이벤트를 발행하려면 아래와 같이 코드를 작성할 수 있다.

Events.publish(ReservationSentEvent.from(reservation));

2. AlarmEvent

Alarm을 발생시키는 모든 Event의 부모 Event. 따라서, 어떤 도메인에서 Alarm을 발생시키고 싶으면 Common 패키지에 위치하여 각 도메인과 알람의 양방향 연관관계를 끊어두었다.

toAlarmSpecification()을 통해 AlarmSpec을 만들 수 있다.

@Override
public AlarmSpecification toAlarmSpecification() {
   return new AlarmSpecification(
              getAlarmType(),
              receiverIds,
              List.of(String.valueOf(senderId), couponTitle, couponType)
          );
}

3. AlarmSpecification

Alarm 도메인을 생성하기 위한 스펙이다. AlarmType, targets, contents를 담아 스펙이 전송되고 알람 도메인에서 이를 받아 처리한다. 알람 생성 사용자 입장에서 이 부분까지만 알아도 충분하다.

4. MessageFormStrategy

마지막으로 메세지 폼을 만드는 전략 패턴이다. 알람 도메인에 누구에게 무엇을 보낼지 결정했다면, MessageFormStrategy를 상속받는 클래스를 생성하여 form을 만들면된다. 나중에 폼이 많아질 경우 DB에 저장하여 폼을 가져다 사용하는 형태로의 변환도 고려해볼 수 있다.

@Override
public Message createFormat(final Alarm alarm) {
    validateContent(alarm);
    List<String> receiverEmails = alarmMemberProvider.getReceiverEmails(alarm.getTargetIds());
    String senderName = alarmMemberProvider.getSenderName(alarm.getContentAt(SENDER_ID_INDEX));

    return Message.builder()
            .email(receiverEmails)
            .title(COFFEE_PRETEXT)
            .titleLink(alarmLinkGenerator.getRootUrl())
            .content(MessageFormat.format(SENDER, senderName))
            .content(MessageFormat.format(TITLE, alarm.getContentAt(TITLE_INDEX)))
            .content(MessageFormat.format(TYPE, COFFEE_TYPE))
            .build();
}

예시

// 1. 알람 발행을 원하는 도메인 패키지에 AlarmEvent를 상속받는 Event 클래스 생성
class CouponSentEvent extends AlarmEvent {
  
  private final List<Long> receiverIds;
  private final Long senderId;
  private final String couponTitle;
  private final String couponType; 

  @Override
  public AlarmSpecification toAlarmSpecification() {
    // 알람스펙에 맞게 생성
  }
}

// 2. 도메인 로직에서 Event 발행
class Coupon {
  void send() {
    // do coupon send ...
    Events.publish(CouponSentEvent.of(this));
  }
}

// 3. Message Format 생성
class CouponSentMessageFormStrategy implements MessageFormStrategy {
  @Override
  public Message createFormat(final Alarm alarm) {
     // 원하는 형식에 맞게 form 생성
  }
}