์๋ ํ์ธ์,
์ค๋์ ๋ฐ์ดํฐ ์์ง ๊ณผ์ ์์ ๋ฐ์ํ ๋ฌธ์ ์ ๊ทธ ํด๊ฒฐ์ฑ , ๊ทธ๋ฆฌ๊ณ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋์ ํ์ฌ ์ป์ ๊ฐ์ ๊ธฐํ์ ๋ํด ์ด์ผ๊ธฐํ๋ ค๊ณ ํฉ๋๋ค.
๋ฌธ์ ์ ํ์
๋ฌธ์ ๋ฅผ ํ์ ํ๊ธฐ ์ํด ์ฝ๋์ ์ด๋ฒคํธ ๋ช ์ธ์๋ฅผ ์ดํด๋ณด์์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ๋ฌด๋ ค 100๊ฐ๊ฐ ๋๋ ์ด๋ฒคํธ์ ๊ทธ์ ํด๋นํ๋ ์์ฑ๋ค์ด ์์๋๋ฐ์. ์ด ๋ง์ ์์ ๋ฐ์ดํฐ ์์ง์์๋ ํด๋จผ ์๋ฌ๊ฐ ์์์ผ๋ฉด ์ข๊ฒ ์ง๋ง, ๊ทธ๋ฐ ๋ณด์ฅ์ด ์์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ง clickPayNow ์ด๋ฒคํธ ๋ด์ ๋ค๋ฅธ ์์ฑ์ ์ ๊ทผํ ๋ ์คํ๊ฐ ์๋ ์์ฑ์ ์ ๊ทผํ๋ฉด undefined๋ฅผ ๋ฐํํ๊ฒ ๋ฉ๋๋ค. ์ด ์ํ์์ ์ด undefined ๊ฐ์ ์ ๊ทผํ๋ ค ํ๋ฉด ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด JavaScript์์๋ ์ด์ฌํ ๋ฐฉ์ด ์ฝ๋๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ด๋ null ๋๋ undefined๋ฅผ ์ฒดํฌํ๊ฑฐ๋ optional chaining์ผ๋ก ์ฒดํฌํ๋ ๋ฐฉ๋ฒ ๋ฑ์ด ์์ต๋๋ค. ์ด๋ ๊ฒ ์์ฑํ ์ฝ๋๋ ์ฝ๋ ํ์ง์ ํฅ์์ํค๊ณ ๋ฐํ์ ์๋ฌ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ง์์์๋ ์ด๋ฌํ ์์ ์ด ๋ฒ๊ฑฐ๋ก์ธ ์ ์์ต๋๋ค.
๊ทธ๋์ ์ ๋ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ ๊ทน์ ์ผ๋ก ๋์ ํ์ฌ ์์ฐ์ฑ๊ณผ ์ ํ๋๋ฅผ ๋์ด๋ ๋ฐฉ์์ ๋ชจ์ํ์ต๋๋ค.
ํ์ ์ ์ฉํ๊ธฐ
๋จผ์ ssomeeMixpanel.track()
์ด๋ ํจ์๋ ์ด๋ฒคํธ ๋ช
์ธ์์ ์ ์๋ ์ด๋ฒคํธ ์ด๋ฆ๊ณผ ์ด๋ฒคํธ ์ด๋ฆ์ ํด๋น๋๋ ์์ฑ๋ค์ ์ธ์๋ก ๋ฐ์ต๋๋ค. ์ด๋ก์จ mixpanel API๋ก ์ ๋ฌ ํ ์ ์์ต๋๋ค.
export const ssomeeMixpanel = () => {
return {
track(eventType, properties) {
// ํจ์ ๊ตฌํ...
try {
mixpanel.track(eventType, properties);
return;
} catch (error) {
console.warn(`fail to send to mixpanel eventName: ${eventType}`);
}
},
}
}
ssomeeMixpanel.track("page_viewed", "" )
track()
ํจ์์ ํ์
์ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค. ์ ์ ์ฒซ ์๋๋ ์ด๋ฒคํธ์ด๋ฆ์ ์ ๋์จ์ ์ด์ฉํ์๋ ๊ฑฐ์์ต๋๋ค.
์ ๋์จ ํ์
์ ํฉ์งํฉ์ ๊ฐ๋
์ผ๋ก ์ด ํ์
๋๋ ์ ํ์
์ ํ์ฉํ๊ฒ ํ๋ ํ์
์
๋๋ค. eventType
์ ์ธ์ํ์
์ผ๋ก page_viewed
๋๋ "sign_up" ๋๋ "login" ์ด ๋ฉ๋๋ค.
type MixpanelEventName=
"page_viewed"|
"sign_up"|
"login"
interface MixpanelProperties {
page_path?: string;
tab_viewed?: string;
scroll?: number;
}
export const ssomeeMixpanel = () => {
return {
track(eventType:MixpanelEventName , properties: MixpanelProperties) {
// ํจ์ ๊ตฌํ...
try {
mixpanel.track(eventType, properties);
return;
} catch (error) {
console.warn(`fail to send to mixpanel eventName: ${eventType}`);
}
},
}
}
์ ๋์จ ํ์ ์ค์ ๋ง์ผ๋ก๋ ์๋์ ์ด๋ฏธ์ง์ ๊ฐ์ด ์ด๋ฒคํธ ์ด๋ฆ๊ณผ ์์ฑ์์ ์๋ ์ถ๋ก ์ด ๊ฐ๋ฅํ๊ฒ ๋์๊ณ , Excel ํ์ผ๋ก ์ด๋ฒคํธ ์ด๋ฆ์ ํ์ธํ๋ ์๊ณ ๋ฅผ ๋ ์ ์์์ต๋๋ค.
ํ์ง๋ง ์์ ํ์ผ์ ์๋ค๊ฐ๋ค ํ๋ฉด์ ์ด๋ฒคํธ์ 30๊ฐ๊ฐ ๋๋ ์์ฑ์ ์ด๋ค๊ฑธ ๊ณจ๋ผ์ผ ํ ์ง ๋งค๋ฒ ํ์ธํด์ผ ํ์์ต๋๋ค.
์ ๋์จ ํ์ ์ ํฉ์งํฉ๊ณผ ๊ฐ์ ๊ฐ๋ ์ผ๋ก, ์ฌ๋ฌ ํ์ ์ค ํ๋๋ฅผ ๋ํ๋ด๋ฉฐ, ์ด๋ฅผ ํตํด ์ ์๋ ๋ชจ๋ ํ์ ์ ํฌ๊ดํฉ๋๋ค. ์ฒซ๋ฒ ์งธ ์ธ์์ ๋ฐ๋ผ ๋๋ฒ์งธ ์ธ์์์ ์๋ ์ถ๋ก ๋๋ ํ์ ์ ๊ตฌ์ฒด์ ์ผ๋ก ์ค์ ํ๋ ๊ฒ์ ํ์ ์ ๋์จํ๊ฒ ์ ์ํ๋ ๊ฒ๋ณด๋ค ์ด๋ฒคํธ ์์ฑ์ ์ ํํ๊ณ ์ ์ํ๊ฒ ์ ๋ฌํ๋ ๋ฐ ๋ ์ ๋ฆฌํ์ต๋๋ค. ๋น๋ก ๋์ค์ ๋ณ๊ฒฝ์ด ํ์ํ ์๋ ์์ง๋ง, ํ์ฌ ์ ํฌ๊ฐ ์ง๋ฉดํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ๋ ์ด ๋ฐฉ๋ฒ์ด ๋ ์ ํฉํ๋ค๊ณ ์๊ฐํ์ด์. ๊ทธ๋์ ์ฒซ๋ฒ ์งธ ์ธ์์ ํ์ ์ ๋ฐ๋ผ, ๋๋ฒ ์งธ ์ธ์์ ํ์ ์ ์๊ฒฉํ๊ฒ ์ ์ฉํ๊ธฐ๋ก ํ์ต๋๋ค.
์ ๊ฐ ์ํ๋๊ฑด ํน์ eventType์ ์ ํํ๋ฉด, event์ ํด๋นํ๋ properties๋ค์ด ์๋์ผ๋ก ์ถ๋ก ๋๊ธฐ๋ฅผ ๋ฐ๋ฌ์ด์.
properties ์ธ์ ์๋ฆฌ์์๋ ์ด๋ค eventType์ ์ ํํ๋์ง ์ ์ ์์๊น์? ๋ฐ๋ก ์ ๋ค๋ฆญ์ ์ด์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ๋ฉด, ํน์ ํ์ ์ ์ ๋ ฅ๋ฐ์ ๊ทธ์ ๋ฐ๋ผ ๋ฐํ๋๋ ํ์ ์ ๋์ ์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค.
๋จผ์ ์ ๋ค๋ฆญ T
๋ฅผ ์ฌ์ฉํ์ฌ track()
์ ์ฒซ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ์ด๋ฒคํธ ๋ค์๋ค ์ค ํ๋๋ง ์ ํ ์ ์๊ฒ ํ์
์ ์ฝ์ ๋ก๋๋ค.
track<T extends MixpanelEventName>(eventType:T, properties: ){
},
๊ทธ๋ฆฌ๊ณ ์ฒซ๋ฒ ์งธ ๋งค๊ฐ๋ณ์์ ์ฌ์ฉํ๋ T
๊ฐ , ๋๋ฒ์งธ ๋งค๊ฐ๋ณ์์์ properties๋ฅผ ๊ฒฐ์ ํ ๋ ์ด๋ค ์ด๋ฒคํธ ๋ค์์ ์ฌ์ฉํ๋์ง ์๊ธฐ ์ํด T
๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ ์กฐ๊ฑด๋ถ ํ์
์ด ํ์ํฉ๋๋ค. ์กฐ๊ฑด๋ถ ํ์
์ ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ํ์
์ ๋ค๋ฅด๊ฒ ํ ๋น ํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์
๋๋ค.
์กฐ๊ฑด๋ถ ํ์ ์ ํ์ฉํ์ฌ ๊ฐ์ ์ ํด๋ณด์ฃ !
์ผ๋จ ๋จผ์ ์ด๋ฒคํธ ์ ์์์ ๋ฐ๋ฅด๋ฉด page_viewed
๋ฅผ ์ ํํ์ ๋ class_id
, page_path
, tab_viewed
, scroll
์ด๋ ์์ฑ๋ค์ด ํ์ํ์ต๋๋ค.
์ด ์์ฑ๋ค์ 'MixpanelProperties' ์ธํฐํ์ด์ค๋ก ์ง์ ๋์ด ์๋๋ฐ์. ์ฌ์ค MixpanelProperties ๋ 50๊ฐ๊ฐ ๋์ต๋๋ค. ๊ทธ๋์ ์ฌ๊ธฐ์ ํ์ํ ์์ฑ์ ์ ํํด์ผ ํ์๋๋ฐ์ ์ด๋ด ๋ ์ฌ์ฉํ๋ ์ ํธ๋ฆฌํฐ ํ์
์ธ Pick
์ ์ฌ์ฉํฉ๋๋ค.
type PAGE_VIEWED_PROPERTIES = Pick<
MixpanelProperties,
"class_id" | "page_path" | "tab_viewed" | "scroll"
>;
์ด์ PAGE_VIEWED_PROPERTIES
๋ page_viewed
๋ผ๋ ์ด๋ฒคํธ๋ค์์ด ์์ ๋ ์ฌ์ฉ ํ ์ ์๋๋ก ์กฐ๊ฑด๋ถ ํ์
์ ๋ง๋ญ๋๋ค.
// ์กฐ๊ฑด๋ถ ํ์
์์
type EventProperties<T extends UnionMixpanelEventName> =
T extends "page_viewed" ? PAGE_VIEWED_PROPERTIES :
T extends "button_clicked" ? BUTTON_CLICKED_PROPERTIES :
T extends "sign_up" ? SIGN_UP_PROPERTIES :
// ... ๋๋จธ์ง ์ด๋ฒคํธ ์ ํ์ ๋ํ ์ฒ๋ฆฌ
never;
์กฐ๊ฑด๋ถ ํ์ ์ ์ด๋ ๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉํ๋ ์ผํญ์ฐ์ฐ์๋ฅผ ํตํด ํํํฉ๋๋ค.
MixpanelPropertyMapper
๋ T ์ฆ ์ด๋ฒคํธ ํ์
์ด ํ์ฌ ์ด๋ค ์ด๋ฒคํธ ํ์
์ด ์ฌ์ง๋ ๋ชจ๋ฅด์ง๋ง ํจ์๊ฐ ํธ์ถ๋ ๋ ์ด๋ฒคํธ ํ์
์ ํด๋นํ๋ ์์ฑ๋ค์ ์ด๋ค ๊ฒ์ ๋ณด์ฌ์ค์ง๋ฅผ ์ ํ๋ ํ์
์
๋๋ค.
T extends "page_viewed" ? PAGE_VIEWED_PROPERTIES : ...
์ด ๋ถ๋ถ์ ๋ง์ฝ T ์ฆ ์ด๋ฒคํธํ์
์ด page_viewed`` ๊ฐ๋ค๋ฉด, ๊ฒฐ๊ณผ ํ์
์
PAGE_VIEWED_PROPERTIES` ๋ฉ๋๋ค.
ํจ์๋ฅผ ์ฌ์ฉํ๋ ์ธก์์์ ๊ฒฐ๊ณผ๋ฅผ ํ๋ฒ ๋ณด์ฃ .
์๋ํ๋๋ก ์ด๋ฒคํธํ์ ์ ๋ง์ถ properties๋ค์ด ๋์์ต๋๋ค. ์ ๊ฐ ์ํ๋ ํ์ ์ถ๋ก ์ ์ด๋ค์ต๋๋ค.
์ฝ๋๋ฅผ ๋ค์ ํ๋ฒ ๋ณผ๊ฒ์.
type MixpanelEventProperties<
T extends UnionMixpanelEventName
> = T extends MixpanelEventNames["PAGE_VIEWED"]
? PAGE_VIEWED_PROPERTIES
: T extends MixpanelEventNames["BNANNER_CLICKED"]
? BANNER_CLICKED_PROPERTIES
: T extends MixpanelEventNames["BUTTON_CLICKED"]
? BUTTON_CLICKED_PROPERTIES
: T extends MixpanelEventNames["SIGN_UP_BEGIN"]
? SIGN_UP_BRGIN_PROPERTIES
: T extends MixpanelEventNames["SIGN_UP"]
? SGIN_UP_PROPERTIES
: T extends MixpanelEventNames["LOGIN"]
? LOGIN_PROPERTIES
: T extends MixpanelEventNames["POP_UP"]
? POP_UP_PROPERTIES
: T extends MixpanelEventNames["ORDER_BEGIN"]
? ORDER_BEGIN_PROPERTIES
: T extends MixpanelEventNames["ORDER_COMPLETED"]
? ORDER_COMPLETED_PROPERTIES
: T extends MixpanelEventNames["ORDER_CONTINUED"]
? ORDER_CONTINUED_PROPERTIES
: T extends MixpanelEventNames["ORDER_STOP"]
? ORDER_STOP_PROPERTIES
: T extends MixpanelEventNames["ORDER_CANCEL"]
? ORDER_CANCEL_PROPERTIES
: T extends MixpanelEventNames["REFUND_EXCHANGE"]
? REFUND_EXCHANGE_PROPERTIES
: T extends MixpanelEventNames["REVIEW_SUBMIT"]
? REVIEW_SUBMIT_PROPERTIES
: T extends MixpanelEventNames["BANK"]
? BANK_PROPERTIES
: T extends MixpanelEventNames["WITHDRAW"]
? WITHDRAW_PROPERTIES
: T extends MixpanelEventNames["NOTIFICATION"]
? NOTIFICATION_PROPERTIES
: T extends MixpanelEventNames["ADD_ACCOUNT"]
? ADD_ACCOUNT_PROPERTIES
: never;
์ด ์ฝ๋ ์์ผ๋ก ์ ์ง ๋ ๊ธธ์ด์ง ๊ฒ ๊ฐ์ง ์๋์? ์๋ง 1000์ค๋ ๊ฐ๋ฅํ์ง ์์๊น์? ์ด ๋ฐฉ์์ ์ฝ๋๊ฐ ์ ์ ๋ ๊ธธ์ด์ง๊ณ ๋ณต์กํด์ง๋ ๊ฒฝํฅ์ด ์์์ต๋๋ค. ํนํ ์ผํญ ์ฐ์ฐ์๊ฐ ์ค์ฒฉ๋๋ฉด์ ๊ฐ๋ ์ฑ์ด ํฌ๊ฒ ๋จ์ด์ก์ฃ . ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ์ข ๋ ์ต์ํ๊ณ ๊ฐ๊ฒฐํ ๊ตฌ์กฐ๋ก ์ ๊ทผํ๊ธฐ๋ก ํ์ต๋๋ค.
๊ทธ๋์ ์ ํฌ๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ํ์ฉํ ๊ตฌ์กฐ๋ก ์ ํํ์ต๋๋ค.
interface MixpanelEventProperties {
page_viewed: PAGE_VIEWED_PROPERTIES;
button_clicked: BUTTON_CLICKED_PROPERTIES;
// ... ์ถ๊ฐ ์ด๋ฒคํธ ์์ฑ ๋งคํ
}
type MixpanelPropertyMapper<T extends keyof MixpanelEventProperties> = MixpanelEventProperties[T];
์ด ๊ตฌ์กฐ๋ฅผ ํตํด ๊ฐ ์ด๋ฒคํธ ์ด๋ฆ์ ๋ํ ์์ฑ ํ์ ์ด MixpanelEventProperties ์ธํฐํ์ด์ค ๋ด์์ ๋ช ํํ๊ฒ ๋งคํ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ MixpanelPropertyMapper ํ์ ์ ์ด ๋งคํ์ ์ง์ ํ์ฉํ๊ฒ ๋ฉ๋๋ค. ์ด๋ก์จ ๋ณต์กํ ์ผํญ ์ฐ์ฐ์์ ์ค์ฒฉ ์กฐ๊ฑด๋ฌธ์ ๋ฒ์ด๋ ํจ์ฌ ๋ช ํํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์ด ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ถ๊ฒ ๋์์ต๋๋ค.
type MixpanelPropertyMapper<T extends keyof MixpanelEventProperties> = MixpanelEventProperties[T];
์ด ํ์ ๊ตฌ์กฐ์ ๋ํด ์กฐ๊ธ ๋ ์์ธํ ๋์ดํด ๋ณผ๊ฒ์.
MixpanelPropertyMapper๋
์ ๋ค๋ฆญ ํ์
T๋ฅผ ๋ฐ์, ํด๋นํ๋ ์ด๋ฒคํธ์ ์์ฑ ํ์
์ ์ถ๋ก ํฉ๋๋ค. ์ด๋ ์ฝ๋์ ์ ์ง๋ณด์๋ฅผ ์ฉ์ดํ๊ฒ ํ๋ฉฐ, ์๋ก์ด ์ด๋ฒคํธ ํ์
์ด ์ถ๊ฐ๋ ๋๋ง๋ค ์ฝ๊ฒ ํ์ฅํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
๋๋ถ์ด Mapped Type ์ ๊ธฐ์กด์ ๊ฐ์ฒด ํ์ ์ ์ ์งํ๋ฉด์๋ ๊ฐ ์์ฑ์ ํ์ ์ ๋ณํํ๊ธฐ๊ฐ ์๋์ ์ผ๋ก ์ฝ๋ค๊ณ ์๊ฐํ์ด์.
์๋ฅผ ๋ค์ด ๊ธฐ์กด์ ๊ฐ์ฒด ํ์ ์ ์ ์งํ๋ฉด์๋ ๊ฐ ์์ฑ์ ํ์ ์ ๋ณํํ๊ธฐ ์ฌ์.
์๋ฅผ ๋ค์ด BUTTON_CLICKED_PROPERTIES
๊ฐ ์ด๋ฏธ ์์ง๋ง ์ด๋ค ์ด์ ์ button_clicked
๋ผ๋ ์ด๋ฒคํธ๊ฐ ๋ค์ด์๋ค๋ฉด, ๊ธฐ์กด์ BUTTON_CLICKED_PROPERTIES
๋ฅผ ์ฐ๋๊ฒ ์๋ SpecialButtonClickedProperties
๋ผ๋ ๋
๋ฆฝ์ ์ผ๋ก ์ ์ํด ๋ ํ์
์ ์ฌ์ฉํ๊ฒ ํ๋๊ฑฐ์ฃ . ์ด๋ด ๊ฒฝ์ฐ ๋ค๋ฅธ ๊ฑด ๋ณ๊ฒฝ์ ํด๋ ์ด๋ฒคํธ ํ์
๊ณผ ์์ฑ์ ๋ฏธ๋ฆฌ ๋งคํํด๋ MixpanelEventProperties
interface
๋ ๊ฑด๋๋ฆฌ์ง ์์๋ ๋๋ค๋ ์ ์ด ์ ์ง๋ณด์ ๋ฉด์์ ์ข๋ค๊ณ ์๊ฐํ์ด์.
type SpecialButtonClickedProperties= {
"classId":string
}
type SpecialEventPropertiesMap = {
[T in keyof MixpanelEventProperties]: T extends "button_clicked"
? SpecialButtonClickedProperties
: MixpanelEventProperties[T];
};
๋ง์น๋ฉฐ
ํ์ ์คํฌ๋ฆฝํธ์ ์ปจ๋์ ๋ํ์ , ์ ๋ค๋ฆญ, never์ ์กฐํฉ์ ํตํด ์ป์ ์ฑ๊ณผ์ ๋ณํ๋ฅผ ์ ๋ฆฌํด ๋ณด์์ด์.
- ์ ๋ค๋ฆญ๊ณผ extends์ ์กฐํฉ์ผ๋ก ์ด๋ฒคํธ์ ์ฌ์ ์๋ ์์ฑ๊ฐ์ ์ ํํ์ต๋๋ค. ์ด๋ก ์ธํด ์ฌ์ฉํ๋ ๊ฐ๋ฐ์๋ ๋ง์ผํ ํ์์ ์ ์ํ ์ธก์ ์์ ์ธ์ ๋ค๋ฅธ ์๋ชป๋ ์์๋ฅผ ์ ๋ฌํ ์ ์์ผ๋ฏ๋ก ํด๋จผ์๋ฌ๋ฅผ ๋ฐฉ์ง ํ ์ ์์ต๋๋ค.
- ํ์ ์ถ๋ก ์ด ํจ์ฌ ๋ช ํํด์ง๊ณ ์ฌ์์ ธ ๊ฐ๋ฐ์์ ์์ฐ์ฑ์ด ์ฌ๋ผ๊ฐ๋๋ค. ์ฝ๋๋ฅผ ์น๋ฉด์ ํ์ ์ ํ์ด ์ฒ์ฒ ๋์์ฃผ๋ฉด ์ฝ๋์น ๋ง์ด ๋๊ณ ์๋๊ฐ ๋นจ๋ผ์ง๋ ๊ฒฝํ์ ๊ฐ์ ธ๋ค ์ฃผ๊ฑฐ๋ ์!
- single source of truth๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ๋ค๋ฅธ ๋ถ์์์ ํ์ ์์ ํนํ๋ ๊ฐ์ ๋ฆฌ์์ค๋ก ์๋ก์ ์ ๋ฌด๋ฅผ ๋๊ธฐํํ ์ ์๊ฒ ๋์ด, ์ ๋ณด์ ์ผ๊ด์ฑ๊ณผ ์ ํ์ฑ์ด ํฅ์๋์์ต๋๋ค. ์ด๋ ๋ง์ผํ ํ์์ ์งํํ๋ ์ฌ์ฉ์ ํ๋ ๋ถ์๊ณผ ํ๋ก ํธ์๋ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๊ฐ์ ๊ฐ๊ทน์ ์ค์ด๋ ๋ฐ ์ค์ํ ์ญํ ์ ํ์ต๋๋ค.
- ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ์ ์ฅ์์๋ ๋ถ๊ฐ์ ์ธ ํ์ ๊ฐ๋๋ฅผ ํ ํ์๊ฐ ์์ต๋๋ค! (์ฝ๋๋ ๊น๋ํด ์ง๋ ํจ๊ณผ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ์ด์!)
๊ธ์ ๋ณด์๊ณ ๋ ๋์ ๊ฐ์ ๋ฐฉ์์ด๋ ์๊ฐํ์ ์ฝ๋ฉํธ๊ฐ ์๋ค๋ฉด, ์๋ ๋๊ธ๋์ ๋จ๊ฒจ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. ์ฑ์ฅํ๋ ๊ฐ๋ฐ์์ ์์ด ๊ท์คํ ์๋ถ์ด ๋ ๊ฒ์ ๋๋ค. ๐