Skip to content
isdnetworks
Go back

예외를 다 흡수하려던 표준 모델

연동 채널 여섯을 하나의 모델로 다루려 했는데 예외가 늘면서 모델이 계속 복잡해졌다.

Table of contents

Open Table of contents

하나의 모델에 담기

여섯 채널의 주문을 한 클래스로 담고 채널마다 다른 것이 나올 때마다 필드를 하나씩 늘려 갔다.

public ?string $giftMessage = null;        // A 채널만
public ?bool   $isSubscription = null;     // B 채널만
public ?string $deliveryWindow = null;     // C 채널만

필드가 스물여덟 개가 됐고 대부분이 특정 채널에만 있었다. 한 모델로 담는다는 목표는 지켜졌지만 그 모델이 여섯 채널의 합집합이 됐다.

쓰는 쪽의 부담

쓰는 쪽에서 어떤 필드가 어느 채널에 있는지 알 수 없었다. 값을 읽기 전에 항상 존재 여부를 확인해야 했고 결국 채널까지 함께 봤다.

if ($order->channel === 'B' && $order->isSubscription) { ... }

모든 예외를 담으려 하니 담은 쪽에서 다시 갈라야 했고 그러면 하나로 담은 의미가 없다. 채널을 안 보려고 만든 모델인데 쓰는 자리마다 채널을 본다.

공통과 예외의 분리

여섯 채널에 모두 있는 공통 필드 다섯만 남기고 나머지는 전부 별도 자리에 담았다.

public function extra(string $key): mixed {
    return $this->extra[$key] ?? null;
}

이렇게 하면 채널별 값이라는 사실이 코드에 드러난다. 같은 값이라도 공통 필드로 읽는 것과 별도 자리에서 꺼내는 것은 읽는 사람에게 다른 신호를 준다.

채널별 처리도 따로 뒀는데 채널마다 자기 형식을 공통 형태로 바꾸는 구현을 두고 공통 흐름에서는 채널을 아예 보지 않는다.

무엇이 공통인지 세는 기준

무엇을 공통으로 둘지는 짐작하지 않고 채널별로 세어서 정했고 여섯 채널에 모두 있는 것만 공통으로 뒀다.

배송비가 애매했다. 넷에 있고 둘에 없어서 공통으로 둘까 했다. 없는 두 곳에서 0으로 두면 되는지 물어보니 배송비 개념이 없는 채널이라 0이 아니라 해당 없음이었다. 대부분에 있다고 공통이 아니고 없는 곳에서 그 값이 뜻을 갖는지를 봐야 했다.

새 필드가 나올 때의 판단 순서도 정했다. 몇 개 채널에 있는지 세고 전부에 있으면 공통으로 두고 일부면 별도 자리에 둔다. 별도 자리의 값을 공통 흐름이 봐야 하면 구조가 안 맞는 신호로 본다.

실제로 그런 것이 하나 나왔다. 정산에서 선물 여부에 따라 수수료가 달라져 공통 흐름이 그 값을 봐야 했다. 값이 아니라 선물인지 아닌지만 공통으로 올리고 내용은 그대로 뒀다.

담을 수 없는 것

한 채널은 주문 구조가 아예 달랐는데 다른 채널이 주문 하나에 상품 여럿을 담는 것과 달리 그 채널은 상품마다 주문이 따로 생긴다.

같은 모델로 담으려니 억지가 돼서 그 채널만 앞에서 우리 구조로 바꾸고 그 뒤로는 다른 채널과 같은 흐름을 타게 했다.

전부 같은 모델로 담는 것이 목적이 아니라 공통 흐름을 타게 하는 것이 목적이었다. 목적을 바꿔 잡고 나니 담을 수 없는 것을 억지로 담지 않아도 됐다.

정리


Share this post on:

Previous Post
제외를 적용하고 센다
Next Post
주 계정을 기준으로 잡은 구조