각각 다른 알림 타입에 대해서 객체지향적으로 처리해보자
개요
꼬꼬면 서비스에서 알림을 구현하다가 같은 알림임에도 불구하고 여러 타입으로 나뉘는 것을 알게 되었다.

현재의 알림의 경우 서버에서 다루는 알림은 세 가지가 있다.
- 누군가 내 면접을 조회했을 때
- 상대방이 내 면접에 좋아요를 눌렀을 때
- 상대방이 내 면접을 보고 각 답변에 좋아요를 눌렀을 때 의 경우로 나뉘는 상황에서 나는 각각의 알림을 어떻게 UI에 표시할지를 생각하며 구현하고 있었다. 그런데 가면 갈수록 해당 방식의 문제점에 대해서 조금 생각을 하게 되었고, 이에 객체지향 개념을 적용하여 문제를 조금 더 간단하게 표현할 수 있을 것 같았기에 이러한 리팩토링 과정을 말해보려 한다.
기존의 문제점
기존의 문제점은 여러가지 Notification에 대해 따로 처리를 해줘야 한다는 점이다. 만약 컴포넌트에 각각의 알림을 띄우려고 한다면,
// 각각의 컴포넌트를 하나씩 구현하기..
const AnswerLikeComponent = () => {
...
}
const InterviewLikeComponent = () => {
...
}
const InterviewViewCountComponent = () => {
...
}
function NotificationItem({notification} : {notification : Notification}) {
switch(notification.type){
case AnswerLike:
...
case InterviewLike:
...
case InterviewViewCount:
...
등등...
}
}와 같이 계속해서 각 컴포넌트에 대해서 만든다고 하더라도 안쪽 텍스트만 바뀌는 것임에도 불구하고 계속해서 분기처리의 늪에 빠지게 되며, 알림 전체의 부분들을 고친다고 하더라도 모든 세부알림 컴포넌트를 고쳐야 하는 등 컴포넌트의 유지보수가 어려워지게 된다.
const transferNotificationMessage = () => {
switch(notification.type){
case AnswerLike:
...
case InterviewLike:
...
case InterviewViewCount:
...
등등...
}
}
function NotificationItem({notification} : {notification : Notification}){
return (
<div>transferNotificationMessage(notification.type)</div>
)
}이를 해결하기 위해 개별적인 컴포넌트로 나누기 보다는 메시지만 변환하여 사용하는 방식을 택한다면 이런 식으로 분기처리를 하여 조금 더 가독성이 좋게 바꿀 수 있을 것이다. 하지만 여기서 더 나아가

객체지향적으로 개선하기
export type NotificationDetails =
| {
notification_type: "ANSWER_LIKE";
answer_id: number;
interview_id: number;
liker_member_id: number;
like_count: number;
}
| {
notification_type: "INTERVIEW_VIEW_COUNT";
interview_id: number;
view_count: number;
}
| {
notification_type: "INTERVIEW_LIKE";
interview_id: number;
liker_member_id: number;
like_count: number;
};각각의 Notification에 대해서 바뀌는 정보
export abstract class BaseNotification implements BaseNotificationInterface {
public type: NotificationType;
public createdAt: string;
public isRead: boolean;
constructor(
type: NotificationType,
createdAt: string,
isRead: boolean = false
) {
this.type = type;
this.createdAt = createdAt;
this.isRead = isRead;
}
abstract getMessage(): string;
}추상 클래스를 미리 구현해놓아 해당 클래스의 메서들을 통해 각각이 다른 속성을 가지고 있더라도, 하나의 메서드를 통해서 해당하는 알림의 메시지 내용을 바로 받을 수 있게끔 할 수 있다.