TypeScript๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋ ฅํ๊ณ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ํ์ ์์ ํ ๋ชจ๋น๋ฆฌํฐ ์์คํ ์ ์ค๊ณ ๋ฐ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ฌ์ธต ๋ถ์. ๋ฌผ๋ฅ, MaaS ๋ฐ ๋์ ๊ณํ ๊ธฐ์ ์ ์ ํฉํฉ๋๋ค.
TypeScript ์ด์ก ์ต์ ํ: ๋ชจ๋น๋ฆฌํฐ ์ ํ ๊ตฌํ์ ๋ํ ๊ธ๋ก๋ฒ ๊ฐ์ด๋
๋ฒ์กํ๊ณ ์ํธ ์ฐ๊ฒฐ๋ ํ๋ ์์ ๋ฐ ๋์ ์ํ์์ ์ฌ๋๊ณผ ์ํ์ ํจ์จ์ ์ธ ์ด๋์ ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ๋นฝ๋นฝํ ๋์ ํ๊ฒฝ์ ํ์ํ๋ ๋ผ์คํธ๋ง์ผ ๋ฐฐ์ก ๋๋ก ๋ถํฐ ๋๋ฅ์ ํก๋จํ๋ ์ฅ๊ฑฐ๋ฆฌ ํ๋ฌผ ํธ๋ญ์ ์ด๋ฅด๊ธฐ๊น์ง ์ด์ก ๋ฐฉ๋ฒ์ ๋ค์์ฑ์ด ํญ๋ฐ์ ์ผ๋ก ์ฆ๊ฐํ์ต๋๋ค. ์ด๋ฌํ ๋ณต์ก์ฑ์ ์ค์ํ ์ํํธ์จ์ด ์์ง๋์ด๋ง ๊ณผ์ ๋ฅผ ์ ์ํฉ๋๋ค. ์ด๋ป๊ฒ ๊ทธ๋ ๊ฒ ๊ด๋ฒ์ํ ๋ชจ๋น๋ฆฌํฐ ์ต์ ์ ์ง๋ฅ์ ์ผ๋ก ๊ด๋ฆฌ, ๋ผ์ฐํ ๋ฐ ์ต์ ํํ ์ ์๋ ์์คํ ์ ๊ตฌ์ถํ ์ ์์๊น์? ๊ทธ ๋ต์ ์๋ฆฌํ ์๊ณ ๋ฆฌ์ฆ๋ฟ๋ง ์๋๋ผ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ์ํํธ์จ์ด ์ํคํ ์ฒ์ ์์ต๋๋ค. ์ด๊ฒ์ด TypeScript๊ฐ ๋น์ ๋ฐํ๋ ๊ณณ์ ๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ ๋ฌผ๋ฅ, ์๋น์คํ ๋ชจ๋น๋ฆฌํฐ(MaaS) ๋ฐ ์ด์ก ๋ถ๋ฌธ์์ ์ผํ๋ ์ํํธ์จ์ด ์ํคํ ํธ, ์์ง๋์ด ๋ฐ ๊ธฐ์ ๋ฆฌ๋๋ฅผ ์ํ ๊ฒ์ ๋๋ค. TypeScript๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ์ด์ก ๋ชจ๋๋ฅผ ๋ชจ๋ธ๋งํ๋ ๊ฐ๋ ฅํ๊ณ ํ์ ์์ ํ ์ ๊ทผ ๋ฐฉ์(์ฐ๋ฆฌ๊ฐ '๋ชจ๋น๋ฆฌํฐ ์ ํ'์ด๋ผ๊ณ ๋ถ๋ฅผ ๊ฒ)์ ์ดํด๋ณผ ๊ฒ์ ๋๋ค. TypeScript์ ๊ณ ๊ธ ์ ํ ์์คํ ์ ํ์ฉํ์ฌ ๊ฐ๋ ฅํ ๋ฟ๋ง ์๋๋ผ ํ์ฅ ๊ฐ๋ฅํ๊ณ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ๋ฉฐ ์ค๋ฅ๊ฐ ํจ์ฌ ์ ์ ์๋ฃจ์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ๊ธฐ๋ณธ ๊ฐ๋ ์์ ์ค์ ๊ตฌํ์ผ๋ก ์ด๋ํ์ฌ ์ฐจ์ธ๋ ์ด์ก ํ๋ซํผ ๊ตฌ์ถ์ ์ํ ์ฒญ์ฌ์ง์ ์ ๊ณตํฉ๋๋ค.
๋ณต์กํ ์ด์ก ๋ก์ง์ TypeScript๋ฅผ ์ ํํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๊ตฌํ์ ๋ฐ์ด๋ค๊ธฐ ์ ์ ์ TypeScript๊ฐ ์ด ๋๋ฉ์ธ์ ๋งค์ฐ ๋งค๋ ฅ์ ์ธ ์ ํ์ธ์ง ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด์ก ๋ก์ง์ ๊ท์น, ์ ์ฝ ์กฐ๊ฑด ๋ฐ ์์ง ์ผ์ด์ค๋ก ๊ฐ๋ ์ฐจ ์์ต๋๋ค. ํ๋ฌผ ๋ฐฐ์ก์ ์์ ๊ฑฐ์ ํ ๋นํ๊ฑฐ๋ ๋ฎ์ ๋ค๋ฆฌ ์๋๋ก ์ด์ธต ๋ฒ์ค๋ฅผ ๋ผ์ฐํ ํ๋ ๊ฒ๊ณผ ๊ฐ์ ๊ฐ๋จํ ์ค๋ฅ๋ ์ฌ๊ฐํ ์ค์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค. TypeScript๋ ๊ธฐ์กด JavaScript์ ์๋ ์์ ๋ง์ ์ ๊ณตํฉ๋๋ค.
- ๋๊ท๋ชจ ํ์ ์์ ์ฑ: ์ฃผ์ ์ด์ ์ ํ๋ก๋์ ํ๊ฒฝ์ด ์๋ ๊ฐ๋ฐ ์ค์ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๋ ๊ฒ์ ๋๋ค. '์ฐจ๋', '๋ณดํ์' ๋๋ '๋์ค๊ตํต ๊ตฌ๊ฐ'์ด ๋ฌด์์ธ์ง์ ๋ํ ์๊ฒฉํ ๊ณ์ฝ์ ์ ์ํ์ฌ ์ฝ๋ ์์ค์์ ๋น๋ ผ๋ฆฌ์ ์ธ ์์ ์ ๋ฐฉ์งํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ปดํ์ผ๋ฌ๋ ์ฌ๋์ด ๊ฑท๋ ๊ฒ์ ๋ํ๋ด๋ ๋ชจ๋น๋ฆฌํฐ ์ ํ์์ fuel_capacity ์์ฑ์ ์ก์ธ์คํ์ง ๋ชปํ๋๋ก ํ ์ ์์ต๋๋ค.
- ํฅ์๋ ๊ฐ๋ฐ์ ๊ฒฝํ ๋ฐ ํ์ : ํฌ๊ณ ์ ์ธ๊ณ์ ๋ถ์ฐ๋ ํ์์๋ ๋ช ํํ๊ณ ์์ฒด ๋ฌธ์ํ๋ ์ฝ๋๋ฒ ์ด์ค๊ฐ ํ์์ ์ ๋๋ค. TypeScript์ ์ธํฐํ์ด์ค์ ์ ํ์ ์ด์์๋ ๋ฌธ์ ์ญํ ์ ํฉ๋๋ค. TypeScript๋ฅผ ์ง์ํ๋ ํธ์ง๊ธฐ๋ ์ง๋ฅ์ ์ธ ์๋ ์์ฑ ๋ฐ ๋ฆฌํฉํ ๋ง ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์ ์์ฐ์ฑ์ ํฌ๊ฒ ํฅ์์ํค๊ณ ์๋ก์ด ํ ๊ตฌ์ฑ์์ด ๋ณต์กํ ๋๋ฉ์ธ ๋ก์ง์ ๋ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ํฉ๋๋ค.
- ํ์ฅ์ฑ ๋ฐ ์ ์ง ๊ด๋ฆฌ ์ฉ์ด์ฑ: ์ด์ก ์์คํ ์ ์งํํฉ๋๋ค. ์ค๋๋ ์๋ ์๋์ฐจ์ ๋ฐด์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๋ด์ผ์ ์ ๊ธฐ ์ค์ฟ ํฐ, ๋ฐฐ๋ฌ ๋๋ก ๋ฐ ์์จ ํฌ๋๊ฐ ๋ ์ ์์ต๋๋ค. ์ ์ค๊ณ๋ TypeScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ๋ฉด ์์ ์๊ฒ ์๋ก์ด ๋ชจ๋น๋ฆฌํฐ ์ ํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์ปดํ์ผ๋ฌ๋ ์์คํ ์ ๋ชจ๋ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ฉฐ ์๋ก์ด ์ ํ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ ๋ฐ์ดํธํด์ผ ํฉ๋๋ค. ์ด๋ ํ๋ก๋์ ๋ฒ๊ทธ๋ฅผ ํตํด ์ํ์ง `if-else` ๋ธ๋ก์ ๋ฐ๊ฒฌํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ์ฐ์ํฉ๋๋ค.
- ๋ณต์กํ ๋น์ฆ๋์ค ๊ท์น ๋ชจ๋ธ๋ง: ์ด์ก์ ์๋์ ๊ฑฐ๋ฆฌ๋ง์ ๋ฌธ์ ๊ฐ ์๋๋๋ค. ์ฐจ๋ ์น์, ์ค๋ ์ ํ, ๋๋ก ์ ํ, ์ด์ ์ ์๊ฐ, ํตํ๋ฃ ๋ฐ ํ๊ฒฝ ๊ตฌ์ญ์ด ํฌํจ๋ฉ๋๋ค. TypeScript์ ์ ํ ์์คํ , ํนํ ํ๋ณ๋ ์ ๋์จ ๋ฐ ์ธํฐํ์ด์ค์ ๊ฐ์ ๊ธฐ๋ฅ์ ์ด๋ฌํ ๋ค๋ฉด์ ์ธ ๊ท์น์ ์ฝ๋์์ ์ง์ ๋ชจ๋ธ๋งํ๋ ํํ๋ ฅ ์๊ณ ์ฐ์ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
ํต์ฌ ๊ฐ๋ : ๋ฒ์ฉ ๋ชจ๋น๋ฆฌํฐ ์ ํ ์ ์
์์คํ ๊ตฌ์ถ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ๊ณตํต ์ธ์ด๋ฅผ ์ค์ ํ๋ ๊ฒ์ ๋๋ค. '๋ชจ๋น๋ฆฌํฐ ์ ํ'์ด๋ ๋ฌด์์ผ๊น์? ์ด์ก ๋คํธ์ํฌ์์ ๊ฒฝ๋ก๋ฅผ ํต๊ณผํ ์ ์๋ ๋ชจ๋ ์ํฐํฐ์ ์ถ์์ ํํ์ ๋๋ค. ๋จ์ํ ์ฐจ๋ ๊ทธ ์ด์์ ๋๋ค. ๋ผ์ฐํ , ์ค์ผ์ค๋ง ๋ฐ ์ต์ ํ์ ํ์ํ ๋ชจ๋ ์์ฑ์ ํฌํจํ๋ ํฌ๊ด์ ์ธ ํ๋กํ์ ๋๋ค.
๋๋ถ๋ถ์ ๋ชจ๋น๋ฆฌํฐ ์ ํ์ ๊ณตํต์ ์ธ ํต์ฌ ์์ฑ์ ์ ์ํ๋ ๊ฒ์ผ๋ก ์์ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์์ฑ์ ๋ณดํธ์ ์ธ ๋ชจ๋ธ์ ๊ธฐ์ด๋ฅผ ํ์ฑํฉ๋๋ค.
๋ชจ๋น๋ฆฌํฐ ์ ํ์ ์ฃผ์ ์์ฑ
๊ฐ๋ ฅํ ๋ชจ๋น๋ฆฌํฐ ์ ํ์ ๋ค์ ์ ๋ณด ๋ฒ์ฃผ๋ฅผ ์บก์ํํด์ผ ํฉ๋๋ค.
- ์์ด๋ดํฐํฐ ๋ฐ ๋ถ๋ฅ:
- `id`: ๊ณ ์ ํ ๋ฌธ์์ด ์๋ณ์(์: 'CARGO_VAN_XL', 'CITY_BICYCLE').
- `type`: ๊ด๋ฒ์ํ ๋ถ๋ฅ๋ฅผ ์ํ ๋ถ๋ฅ์(์: 'VEHICLE', 'MICROMOBILITY', 'PEDESTRIAN'). ํ์ ์์ ์ ํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- `name`: ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ด๋ฆ(์: "Extra Large Cargo Van").
- ์ฑ๋ฅ ํ๋กํ:
- `speedProfile`: ์ด๋ ๊ฐ๋จํ ํ๊ท ์๋(์: ๊ฑท๊ธฐ์ ๊ฒฝ์ฐ 5km/h) ๋๋ ๋๋ก ์ ํ, ๊ฒฝ์ฌ ๋ฐ ๊ตํต ์ํฉ์ ๊ณ ๋ คํ๋ ๋ณต์กํ ํจ์์ผ ์ ์์ต๋๋ค. ์ฐจ๋์ ๊ฒฝ์ฐ ๊ฐ์ ๋ฐ ๊ฐ์ ๋ชจ๋ธ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
- `energyProfile`: ์๋์ง ์๋น๋ฅผ ์ ์ํฉ๋๋ค. ์ฐ๋ฃ ํจ์จ์ฑ(๋ฆฌํฐ/100km ๋๋ MPG), ๋ฐฐํฐ๋ฆฌ ์ฉ๋ ๋ฐ ์๋น๋(kWh/km) ๋๋ ๊ฑท๊ธฐ ๋ฐ ์์ ๊ฑฐ ํ๊ธฐ์ ๊ฒฝ์ฐ ์ธ์ฒด์ ์นผ๋ก๋ฆฌ ์๋ชจ๋์ ๋ชจ๋ธ๋งํ ์ ์์ต๋๋ค.
- ๋ฌผ๋ฆฌ์ ์ ์ฝ ์กฐ๊ฑด:
- `dimensions`: ๋ฏธํฐ์ ๊ฐ์ ํ์ค ๋จ์๋ก `height`, `width` ๋ฐ `length`๋ฅผ ํฌํจํ๋ ๊ฐ์ฒด์ ๋๋ค. ๋ค๋ฆฌ, ํฐ๋ ๋ฐ ์ข์ ๊ฑฐ๋ฆฌ์ ๊ฐ๊ทน์ ํ์ธํ๋ ๋ฐ ์ค์ํฉ๋๋ค.
- `weight`: ํฌ๋ก๊ทธ๋จ ๋จ์์ `grossWeight` ๋ฐ `axleWeight` ๊ฐ์ฒด์ ๋๋ค. ์ค๋ ์ ํ์ด ์๋ ๋ค๋ฆฌ ๋ฐ ๋๋ก์ ํ์์ ์ ๋๋ค.
- ์ด์ ๋ฐ ๋ฒ์ ์ ์ฝ ์กฐ๊ฑด:
- `accessPermissions`: ์ฌ์ฉํ ์ ์๋ ์ธํ๋ผ ์ ํ์ ์ ์ํ๋ ํ๊ทธ ๋ฐฐ์ด ๋๋ ์ธํธ(์: ['HIGHWAY', 'URBAN_ROAD', 'BIKE_LANE']).
- `prohibitedFeatures`: ํผํด์ผ ํ ๊ฒ๋ค์ ๋ชฉ๋ก(์: ['TOLL_ROADS', 'FERRIES', 'STAIRS']).
- `specialDesignations`: ์์ฒด ๋ผ์ฐํ ๊ท์น์ด ์๋ ์ ํด ๋ฌผ์ง์ ๊ฒฝ์ฐ 'HAZMAT' ๋๋ ์จ๋ ์ ์ด ํ๋ฌผ์ ๊ฒฝ์ฐ 'REFRIGERATED'์ ๊ฐ์ ํน๋ณ ๋ถ๋ฅ์ ๋ํ ํ๊ทธ์ ๋๋ค.
- ๊ฒฝ์ ๋ชจ๋ธ:
- `costModel`: `costPerKilometer`, `costPerHour`(์ด์ ์ ๊ธ์ฌ ๋๋ ์ฐจ๋ ๋ง๋ชจ์ฉ) ๋ฐ `fixedCost`(๋จ์ผ ์ฌํ์ฉ)์ ๊ฐ์ ๋น์ฉ์ ์ ์ํ๋ ๊ตฌ์กฐ์ ๋๋ค.
- ํ๊ฒฝ ์ํฅ:
- `emissionsProfile`: ์นํ๊ฒฝ ๋ผ์ฐํ ์ต์ ํ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด `co2GramsPerKilometer`์ ๊ฐ์ ๋ฐฐ์ถ๋์ ์์ธํ ์ค๋ช ํ๋ ๊ฐ์ฒด์ ๋๋ค.
TypeScript์ ์ค์ ๊ตฌํ ์ ๋ต
์ด์ ์ด๋ฌํ ๊ฐ๋ ์ ๊น๋ํ๊ณ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ TypeScript ์ฝ๋๋ก ๋ณํํด ๋ณด๊ฒ ์ต๋๋ค. ์ธํฐํ์ด์ค, ์ ํ ๋ฐ ์ด๋ฌํ ์ข ๋ฅ์ ๋ชจ๋ธ๋ง์ ์ํ TypeScript์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋์ธ ํ๋ณ๋ ์ ๋์จ์ ์กฐํฉ์ ์ฌ์ฉํฉ๋๋ค.
1๋จ๊ณ: ๊ธฐ๋ณธ ์ธํฐํ์ด์ค ์ ์
๋จผ์ ์์์ ์ ์ํ ๊ตฌ์กฐํ๋ ์์ฑ์ ๋ํ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค. ๋ด๋ถ์ ์ผ๋ก ํ์ค ๋จ์ ์์คํ (์: ๋ฏธํฐ๋ฒ)์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ณํ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํ ๊ธ๋ก๋ฒ ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค.
์: ๊ธฐ๋ณธ ์์ฑ ์ธํฐํ์ด์ค
// ๋ชจ๋ ๋จ์๋ ๋ด๋ถ์ ์ผ๋ก ํ์คํ๋์ด ์์ต๋๋ค(์: ๋ฏธํฐ, kg, km/h)
interface IDimensions {
height: number;
width: number;
length: number;
}
interface IWeight {
gross: number; // ์ด ์ค๋
axleLoad?: number; // ์ ํ ์ฌํญ, ํน์ ๋๋ก ์ ํ์ฉ
}
interface ICostModel {
perKilometer: number; // ๊ฑฐ๋ฆฌ ๋จ์๋น ๋น์ฉ
perHour: number; // ์๊ฐ ๋จ์๋น ๋น์ฉ
fixed: number; // ์ฌํ๋น ๊ณ ์ ๋น์ฉ
}
interface IEmissionsProfile {
co2GramsPerKilometer: number;
}
๋ค์์ผ๋ก ๋ชจ๋ ๋ชจ๋น๋ฆฌํฐ ์ ํ์ด ๊ณต์ ํ ๊ธฐ๋ณธ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค. ๋ณดํ์๋ ์น์๋ ์ฐ๋ฃ๋น๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋ง์ ์์ฑ์ด ์ ํ ์ฌํญ์ ๋๋ค.
์: ํต์ฌ `IMobilityType` ์ธํฐํ์ด์ค
interface IMobilityType {
id: string;
name: string;
averageSpeedKph: number;
accessPermissions: string[]; // ์: ['PEDESTRIAN_PATH']
prohibitedFeatures?: string[]; // ์: ['HIGHWAY']
costModel?: ICostModel;
emissionsProfile?: IEmissionsProfile;
dimensions?: IDimensions;
weight?: IWeight;
}
2๋จ๊ณ: ์ ํ๋ณ ๋ก์ง์ ์ํ ํ๋ณ๋ ์ ๋์จ ํ์ฉ
ํ๋ณ๋ ์ ๋์จ์ TypeScript๊ฐ ์์ ์ค์ธ ํน์ ์ ํ์ ์ขํ ์ ์๋๋ก ์ ๋์จ ๋ด์ ๊ฐ ์ ํ์ ๋ฆฌํฐ๋ด ์์ฑ('ํ๋ณ์')์ ์ฌ์ฉํ๋ ํจํด์ ๋๋ค. ์ด๋ ์ฐ๋ฆฌ์ ์ฌ์ฉ ์ฌ๋ก์ ์๋ฒฝํฉ๋๋ค. `mobilityClass` ์์ฑ์ ์ถ๊ฐํ์ฌ ํ๋ณ์ ์ญํ ์ ํฉ๋๋ค.
๋ค๋ฅธ ํด๋์ค์ ๋ชจ๋น๋ฆฌํฐ์ ๋ํ ํน์ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ๊ฐ์ ๊ธฐ๋ณธ `IMobilityType`์ ํ์ฅํ๊ณ ๋ชจ๋ ์ค์ํ `mobilityClass` ํ๋ณ์์ ํจ๊ป ์์ฒด ๊ณ ์ ํ ์์ฑ์ ์ถ๊ฐํฉ๋๋ค.
์: ํน์ ๋ชจ๋น๋ฆฌํฐ ์ธํฐํ์ด์ค ์ ์
interface IPedestrianProfile extends IMobilityType {
mobilityClass: 'PEDESTRIAN';
avoidsTraffic: boolean; // ๊ณต์ ๋ฑ์ ํตํด ๋ฐ๋ก ๊ฐ๊ธฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
}
interface IBicycleProfile extends IMobilityType {
mobilityClass: 'BICYCLE';
requiresBikeParking: boolean;
}
// ์ ๋ ์ฐจ๋์ ์ํ ๋ ๋ณต์กํ ์ ํ
interface IVehicleProfile extends IMobilityType {
mobilityClass: 'VEHICLE';
fuelType: 'GASOLINE' | 'DIESEL' | 'ELECTRIC' | 'HYBRID';
fuelCapacity?: number; // ๋ฆฌํฐ ๋๋ kWh ๋จ์
// ์ฐจ๋์ ํ์ํ ์น์ ๋ฐ ๋ฌด๊ฒ ๋ง๋ค๊ธฐ
dimensions: IDimensions;
weight: IWeight;
}
interface IPublicTransitProfile extends IMobilityType {
mobilityClass: 'PUBLIC_TRANSIT';
agencyName: string; // ์: "TfL", "MTA"
mode: 'BUS' | 'TRAIN' | 'SUBWAY' | 'TRAM';
}
์ด์ ๋จ์ผ ์ ๋์จ ์ ํ์ผ๋ก ๊ฒฐํฉํฉ๋๋ค. ์ด `MobilityProfile` ์ ํ์ ์์คํ ์ ์ด์์ ๋๋ค. ๋ผ์ฐํ ๋๋ ์ต์ ํ๋ฅผ ์ํํ๋ ๋ชจ๋ ํจ์๋ ์ด ์ ํ์ ์ธ์๋ฅผ ํ์ฉํฉ๋๋ค.
์: ์ต์ข ์ ๋์จ ์ ํ
type MobilityProfile = IPedestrianProfile | IBicycleProfile | IVehicleProfile | IPublicTransitProfile;
3๋จ๊ณ: ๊ตฌ์ฒด์ ์ธ ๋ชจ๋น๋ฆฌํฐ ์ ํ ์ธ์คํด์ค ์์ฑ
์ ํ ๋ฐ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ์ผ๋ฏ๋ก ๊ตฌ์ฒด์ ์ธ ๋ชจ๋น๋ฆฌํฐ ํ๋กํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ ์ ์๋ ๋ชจ์์ ์ค์ํ๋ ์ผ๋ฐ ๊ฐ์ฒด์ผ ๋ฟ์ ๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋๋ ๊ตฌ์ฑ ํ์ผ์ ์ ์ฅํ๊ณ ๋ฐํ์์ ๋ก๋ํ ์ ์์ต๋๋ค.
์: ๊ตฌ์ฒด์ ์ธ ์ธ์คํด์ค
const WALKING_PROFILE: IPedestrianProfile = {
id: 'pedestrian_standard',
name: 'Walking',
mobilityClass: 'PEDESTRIAN',
averageSpeedKph: 5,
accessPermissions: ['PEDESTRIAN_PATH', 'SIDEWALK', 'PARK_TRAIL'],
prohibitedFeatures: ['HIGHWAY', 'TUNNEL_VEHICLE_ONLY'],
avoidsTraffic: true,
emissionsProfile: { co2GramsPerKilometer: 0 },
};
const CARGO_VAN_PROFILE: IVehicleProfile = {
id: 'van_cargo_large_diesel',
name: 'Large Diesel Cargo Van',
mobilityClass: 'VEHICLE',
averageSpeedKph: 60,
accessPermissions: ['HIGHWAY', 'URBAN_ROAD'],
fuelType: 'DIESEL',
dimensions: { height: 2.7, width: 2.2, length: 6.0 },
weight: { gross: 3500 },
costModel: { perKilometer: 0.3, perHour: 25, fixed: 10 },
emissionsProfile: { co2GramsPerKilometer: 250 },
};
๋ผ์ฐํ ์์ง์์ ๋ชจ๋น๋ฆฌํฐ ์ ํ ์ ์ฉ
์ด ์ํคํ ์ฒ์ ์ง์ ํ ํ์ ๋ผ์ฐํ ์์ง๊ณผ ๊ฐ์ ํต์ฌ ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง์์ ์ด๋ฌํ ์ ํํ๋ ํ๋กํ์ ์ฌ์ฉํ ๋ ๋ถ๋ช ํด์ง๋๋ค. ํ๋ณ๋ ์ ๋์จ์ ์ฌ์ฉํ๋ฉด ๋ค์ํ ๋ชจ๋น๋ฆฌํฐ ๊ท์น์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊น๋ํ๊ณ ์์ ํ๋ฉฐ ํ์ ์์ ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๋ชจ๋น๋ฆฌํฐ ์ ํ์ด ๋๋ก๋ง์ ํน์ ์ธ๊ทธ๋จผํธ(๊ทธ๋ํ ์ด๋ก ์ฉ์ด๋ก '์์ง')๋ฅผ ํต๊ณผํ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํด์ผ ํ๋ ํจ์๊ฐ ์๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ์ด ์์ง์๋ `maxHeight`, `maxWeight`, `allowedAccessTags` ๋ฑ๊ณผ ๊ฐ์ ์์ฑ์ด ์์ต๋๋ค.
์์ ํ `switch` ๋ฌธ์ ์ฌ์ฉํ ํ์ ์์ ๋ก์ง
`MobilityProfile` ์ ํ์ ์ฌ์ฉํ๋ ํจ์๋ `mobilityClass` ์์ฑ์ `switch` ๋ฌธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. TypeScript๋ ์ด๋ฅผ ์ดํดํ๊ณ ๊ฐ `case` ๋ธ๋ก ๋ด์์ `profile`์ ์ ํ์ ์ง๋ฅ์ ์ผ๋ก ์ขํ๋๋ค. ์ฆ, `'VEHICLE'` case ๋ด์์ ์ปดํ์ผ๋ฌ๊ฐ ๋ถํํ์ง ์๊ณ `profile.dimensions.height`์ ์์ ํ๊ฒ ์ก์ธ์คํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ์ปดํ์ผ๋ฌ๋ `IVehicleProfile`๋ง ๋ ์ ์๋ค๋ ๊ฒ์ ์๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ํ tsconfig์์ `"strictNullChecks": true`๋ฅผ ํ์ฑํํ ๊ฒฝ์ฐ TypeScript ์ปดํ์ผ๋ฌ๋ `switch` ๋ฌธ์ด ์์ ํ์ง ํ์ธํฉ๋๋ค. `MobilityProfile` ์ ๋์จ์ ์ ์ ํ(`IDroneProfile` ๋ฑ)์ ์ถ๊ฐํ์ง๋ง ํด๋น `case`๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ์์ด๋ฒ๋ฆฐ ๊ฒฝ์ฐ ์ปดํ์ผ๋ฌ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ์ด๋ ์ ์ง ๊ด๋ฆฌ๋ฅผ ์ํ ๋งค์ฐ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค.
์: ํ์ ์์ ์ ๊ทผ์ฑ ํ์ธ ํจ์
// RoadSegment๊ฐ ๋๋ก ์กฐ๊ฐ์ ๋ํด ์ ์๋ ์ ํ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค.
interface RoadSegment {
id: number;
allowedAccess: string[]; // ์: ['HIGHWAY', 'VEHICLE']
maxHeight?: number;
maxWeight?: number;
}
function canTraverse(profile: MobilityProfile, segment: RoadSegment): boolean {
// ๊ธฐ๋ณธ ํ์ธ: ์ธ๊ทธ๋จผํธ๊ฐ ์ด ์ผ๋ฐ์ ์ธ ์ ํ์ ์ก์ธ์ค๋ฅผ ํ์ฉํฉ๋๊น?
const hasAccessPermission = profile.accessPermissions.some(perm => segment.allowedAccess.includes(perm));
if (!hasAccessPermission) {
return false;
}
// ์ด์ ํ๋ณ๋ ์ ๋์จ์ ์ฌ์ฉํ์ฌ ํน์ ๊ฒ์ฌ๋ฅผ ์ํํฉ๋๋ค.
switch (profile.mobilityClass) {
case 'PEDESTRIAN':
// ๋ณดํ์๋ ๋ฌผ๋ฆฌ์ ์ ์ฝ ์กฐ๊ฑด์ด ๊ฑฐ์ ์์ต๋๋ค.
return true;
case 'BICYCLE':
// ์์ ๊ฑฐ๋ ๋ช ๊ฐ์ง ํน์ ์ ์ฝ ์กฐ๊ฑด์ด ์์ ์ ์์ง๋ง ์ฌ๊ธฐ์๋ ๊ฐ๋จํฉ๋๋ค.
return true;
case 'VEHICLE':
// TypeScript๋ `profile`์ด ์ฌ๊ธฐ์์ IVehicleProfile์ด๋ผ๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค!
// ์น์์ ๋ฌด๊ฒ์ ์์ ํ๊ฒ ์ก์ธ์คํ ์ ์์ต๋๋ค.
if (segment.maxHeight && profile.dimensions.height > segment.maxHeight) {
return false; // ์ด ๋ค๋ฆฌ/ํฐ๋์ ๋๋ฌด ๋์ต๋๋ค.
}
if (segment.maxWeight && profile.weight.gross > segment.maxWeight) {
return false; // ์ด ๋ค๋ฆฌ์ ๋๋ฌด ๋ฌด๊ฒ์ต๋๋ค.
}
return true;
case 'PUBLIC_TRANSIT':
// ๋์ค๊ตํต์ ๊ณ ์ ๋ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ฅด๋ฏ๋ก ์ด ๊ฒ์ฌ๋ ๋ค๋ฅผ ์ ์์ต๋๋ค.
// ์ง๊ธ์ ๊ธฐ๋ณธ ์ก์ธ์ค ๊ถํ์ด ์๋ ๊ฒฝ์ฐ ์ ํจํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
return true;
default:
// ์ด ๊ธฐ๋ณธ ์ผ์ด์ค๋ ์์ ์ฑ์ ์ฒ๋ฆฌํฉ๋๋ค.
const _exhaustiveCheck: never = profile;
return _exhaustiveCheck;
}
}
๊ธ๋ก๋ฒ ๊ณ ๋ ค ์ฌํญ ๋ฐ ํ์ฅ์ฑ
์ ์ธ๊ณ์ ์ผ๋ก ์ฌ์ฉํ๋๋ก ์ค๊ณ๋ ์์คํ ์ ์ ์ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค. ๊ท์ , ๋จ์ ๋ฐ ์ฌ์ฉ ๊ฐ๋ฅํ ์ด์ก ๋ชจ๋๋ ๋๋ฅ, ๊ตญ๊ฐ, ์ฌ์ง์ด ๋์๋ง๋ค ํฌ๊ฒ ๋ค๋ฆ ๋๋ค. ์ฐ๋ฆฌ์ ์ํคํ ์ฒ๋ ์ด๋ฌํ ๋ณต์ก์ฑ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ ํฉํฉ๋๋ค.
์ง์ญ์ ์ฐจ์ด ์ฒ๋ฆฌ
- ์ธก์ ๋จ์: ๊ธ๋ก๋ฒ ์์คํ ์์ ์ค๋ฅ์ ์ผ๋ฐ์ ์ธ ์์ธ์ ๋ฏธํฐ๋ฒ(ํฌ๋ก๋ฏธํฐ, ํฌ๋ก๊ทธ๋จ)๊ณผ ์๊ตญ์(๋ง์ผ, ํ์ด๋) ๋จ์ ๊ฐ์ ํผ๋์ ๋๋ค. ๋ชจ๋ฒ ์ฌ๋ก: ์ ์ฒด ๋ฐฑ์๋ ์์คํ ์ ๋จ์ผ ๋จ์ ์์คํ (๋ฏธํฐ๋ฒ์ ๊ณผํ์ ๋ฐ ๊ธ๋ก๋ฒ ํ์ค์)์ผ๋ก ํ์คํํฉ๋๋ค. `MobilityProfile`์๋ ๋ฏธํฐ๋ฒ ๊ฐ๋ง ํฌํจ๋์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ์๊ตญ์ ๋จ์๋ก์ ๋ณํ์ ์ฌ์ฉ์์ ๋ก์ผ์ผ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ์ ํ ์ด์ ๊ณ์ธต(API ์๋ต ๋๋ ํ๋ฐํธ์๋ UI)์์ ์ํ๋์ด์ผ ํฉ๋๋ค.
- ์ง์ญ ๊ท์ : ๋ฐ๋ ์ค์ฌ๋ถ์์ ์ด์ ๋ฐฐ์ถ ๊ตฌ์ญ(ULEZ)์ด ์๋ ํ๋ฌผ ๋ฐด์ ๋ผ์ฐํ ์ ํ ์ฌ์ค ์๊ณจ์์์ ๋ผ์ฐํ ๊ณผ ๋งค์ฐ ๋ค๋ฆ ๋๋ค. ์ด๋ ์ ์ฝ ์กฐ๊ฑด์ ๋์ ์ผ๋ก ๋ง๋ค์ด ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. `accessPermissions`๋ฅผ ํ๋ ์ฝ๋ฉํ๋ ๋์ ๋ผ์ฐํ ์์ฒญ์ ์ง๋ฆฌ์ ์ปจํ ์คํธ(`context: 'london_city_center'` ๋ฑ)๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด ์์ง์ ์ฐจ๋์ `fuelType` ๋๋ `emissionsProfile`์ ULEZ ์๊ตฌ ์ฌํญ์ ๋ํด ํ์ธํ๋ ๊ฒ๊ณผ ๊ฐ์ด ํด๋น ์ปจํ ์คํธ์ ๊ณ ์ ํ ๊ท์น ์ธํธ๋ฅผ ์ ์ฉํฉ๋๋ค.
- ๋์ ๋ฐ์ดํฐ: ๊ธฐ๋ณธ ํ๋กํ๊ณผ ์ค์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํ์ฌ '์ํ๋' ํ๋กํ์ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ๊ธฐ๋ณธ `CAR_PROFILE`์ ์ค์๊ฐ ๊ตํต ๋ฐ์ดํฐ์ ๊ฒฐํฉํ์ฌ ํน์ ์๊ฐ๋์ ํน์ ๊ฒฝ๋ก์ ๋ํ ๋์ `speedProfile`์ ๋ง๋ค ์ ์์ต๋๋ค.
์๋ก์ด ๋ชจ๋น๋ฆฌํฐ ์ ํ์ผ๋ก ๋ชจ๋ธ ํ์ฅ
ํ์ฌ๊ฐ ๋ฐฐ๋ฌ ๋๋ก ์๋น์ค๋ฅผ ์์ํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์ด ์ํคํ ์ฒ๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ก์ธ์ค๊ฐ ๊ตฌ์กฐํ๋๊ณ ์์ ํฉ๋๋ค.
- ์ธํฐํ์ด์ค ์ ์: `IMobilityType`์ ํ์ฅํ๊ณ `maxFlightAltitude`, `batteryLifeMinutes` ๋ฐ `payloadCapacityKg`์ ๊ฐ์ ๋๋ก ๊ด๋ จ ์์ฑ์ ํฌํจํ๋ ์ `IDroneProfile` ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค. ํ๋ณ์๋ฅผ ์์ง ๋ง์ญ์์ค: `mobilityClass: 'DRONE';`
- ์ ๋์จ ์ ๋ฐ์ดํธ: `IDroneProfile`์ `MobilityProfile` ์ ๋์จ ์ ํ์ ์ถ๊ฐํฉ๋๋ค: `type MobilityProfile = ... | IDroneProfile;`
- ์ปดํ์ผ๋ฌ ์ค๋ฅ ๋ฐ๋ฅด๊ธฐ: ์ด๊ฒ์ด ๋ง๋ฒ์ ๋จ๊ณ์ ๋๋ค. ์ด์ TypeScript ์ปดํ์ผ๋ฌ๋ ๋ ์ด์ ์์ ํ์ง ์์ ๋ชจ๋ `switch` ๋ฌธ์์ ์ค๋ฅ๋ฅผ ์์ฑํฉ๋๋ค. `canTraverse`์ ๊ฐ์ ๋ชจ๋ ํจ์๋ฅผ ๊ฐ๋ฆฌํค๊ณ 'DRONE' ์ผ์ด์ค์ ๋ํ ๋ก์ง์ ๊ตฌํํ๋๋ก ๊ฐ์ํฉ๋๋ค. ์ด ์ฒด๊ณ์ ์ธ ํ๋ก์ธ์ค๋ ์ค์ํ ๋ก์ง์ ๋์น์ง ์๋๋ก ๋ณด์ฅํ์ฌ ์๋ก์ด ๊ธฐ๋ฅ์ ๋์ ํ ๋ ๋ฒ๊ทธ ์ํ์ ํฌ๊ฒ ์ค์ ๋๋ค.
- ๋ก์ง ๊ตฌํ: ๋ผ์ฐํ ์์ง์์ ๋๋ก ์ ๋ํ ๋ก์ง์ ์ถ๊ฐํฉ๋๋ค. ์ด๋ ์ง์ ์ฐจ๋๊ณผ ์์ ํ ๋ค๋ฆ ๋๋ค. ๋๋ก๋ง ์์ฑ ๋์ ๋นํ ๊ธ์ง ๊ตฌ์ญ, ๊ธฐ์ ์กฐ๊ฑด(ํ์) ๋ฐ ์ฐฉ๋ฅ์ฅ ๊ฐ์ฉ์ฑ์ ํ์ธํ๋ ๊ฒ์ด ํฌํจ๋ ์ ์์ต๋๋ค.
๊ฒฐ๋ก : ๋ฏธ๋ ๋ชจ๋น๋ฆฌํฐ๋ฅผ ์ํ ๊ธฐ๋ฐ ๊ตฌ์ถ
์ด์ก ์ต์ ํ๋ ํ๋ ์ํํธ์จ์ด ์์ง๋์ด๋ง์์ ๊ฐ์ฅ ๋ณต์กํ๊ณ ์ํฅ๋ ฅ ์๋ ๊ณผ์ ์ค ํ๋์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ตฌ์ถํ๋ ์์คํ ์ ์ ํํ๊ณ ์์ ์ ์ด์ด์ผ ํ๋ฉฐ ๋น ๋ฅด๊ฒ ์งํํ๋ ๋ชจ๋น๋ฆฌํฐ ์ต์ ํ๊ฒฝ์ ์ ์ํ ์ ์์ด์ผ ํฉ๋๋ค. TypeScript์ ๊ฐ๋ ฅํ ์ ํ ์ง์ , ํนํ ํ๋ณ๋ ์ ๋์จ๊ณผ ๊ฐ์ ํจํด์ ์์ฉํจ์ผ๋ก์จ ์ด๋ฌํ ๋ณต์ก์ฑ์ ์ํ ๊ฒฌ๊ณ ํ ๊ธฐ๋ฐ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
๊ฐ๋ต์ ์ผ๋ก ์ค๋ช ํ ๋ชจ๋น๋ฆฌํฐ ์ ํ ๊ตฌํ์ ๋จ์ํ ์ฝ๋ ๊ตฌ์กฐ ๊ทธ ์ด์์ ์ ๊ณตํฉ๋๋ค. ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๊ณ ๊ฐ๋ฐ์ ์์ฐ์ฑ์ ํฅ์์ํค๋ฉฐ ํ๋ซํผ์ด ์์ ์๊ฒ ์ฑ์ฅํ ์ ์๋๋ก ํด์ฃผ๋ ๋ช ํํ๊ณ ์ ์ง ๊ด๋ฆฌ ๊ฐ๋ฅํ๋ฉฐ ํ์ฅ ๊ฐ๋ฅํ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ๊ธ๋ก๋ฒ ๋ฌผ๋ฅ ํ์ฌ๋ฅผ ์ํ ๋ผ์ฐํ ์์ง, ์ฃผ์ ๋์๋ฅผ ์ํ ๋ค์ค ๋ชจ๋ ์ฌํ ๊ณํ, ๋๋ ์์จ ํจ๋ ๊ด๋ฆฌ ์์คํ ์ ๊ตฌ์ถํ๋ , ์ ์ค๊ณ๋ ์ ํ ์์คํ ์ ์ฌ์น๊ฐ ์๋๋ผ ์ฑ๊ณต์ ์ํ ํ์ ์ฒญ์ฌ์ง์ ๋๋ค.