この記事は検索エンジンプロダクトを一緒に開発してた同窓会 Advent Calendar 2023の4日目の記事です!
退職してからも、同窓会としてアドベントカレンダーできて嬉しいです
書いてる人
私は、フルサイクルエンジニアです。
出典
※ フロントのみが専門ではないので、内容へのツッコミ大歓迎です!!
書くこと
- フレームワークについて
- フロントでドメインモデルを使わない事に対する課題感
- 例を見よう
- まとめ
1. フレームワークについて
Vue + TypeScript
2. フロントでドメインモデルを使わない事に対する課題感
Vueを描いてると、コンポーネントにどんどん切り出したいですよね!
コンポーネントに切り出すと、可読性が上がる一方で、他コンポーネントで定義した諸々を、戦略的選択により他コンポーネントに再度定義したくなることもありますね。
すると、メンテが大変になります。できません!
しかもコンポーネントは、そもそもそのロジックを知らなくていいんです。
ロジックを持つべきじゃない人がロジックを持ち、同じロジックが散らばってしまう危険性があります。
3. 例を見よう
※ コードは、雰囲気です
ドメインモデルなし
userTable.vue
<template>
<table>
<thead>
<tr>
<th>名前</th>
<th>年齢</th>
<th>成人に達している</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<td>{{ isAdult(user) }}</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: 'userTable',
data () {
const dummyData: User[] = [
{ 'KOKONA', 17 },
{ 'RINO', 20 },
{ 'MOMONA', 20 },
{ 'NAGOMI', 16 },
{ 'RIN', 17 },
{ 'KEIKO', 18 },
];
return {
users: { type: Array as PropType<User[]>, default: dummyData },
}
},
methods: {
// userTableコンポーネントの興味の範囲外のロジック
isAdult(user: User): boolean {
return user.age >= 18;
}
},
}
</script>
User.ts
// 最低限の情報のみ
export interface User {
name: string;
age: number;
}
ドメインモデルあり
userTable.vue
<template>
<table>
<thead>
<tr>
<th>名前</th>
<th>年齢</th>
<th>成人に達している</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
<!-- 呼ぶ側はロジックを気にしなくても良くなる -->
<td>{{ user.isAdult() }}</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: 'userTable',
data () {
const dummyData: User[] = [
{ 'KOKONA', 17 },
{ 'RINO', 20 },
{ 'MOMONA', 20 },
{ 'NAGOMI', 16 },
{ 'RIN', 17 },
{ 'KEIKO', 18 },
];
return {
users: { type: Array as PropType<User[]>, default: dummyData },
}
}
}
</script>
User.ts
export class User {
constructor(
readonly name: string,
readonly age: number,
) {}
// 成人かどうかのロジックは、Userクラスのみが知っていれば良くなった
get isAdult(): boolean {
return this.age >= 18;
}
}
4. まとめ
フロントで、ドメインモデル導入するのはいいぞ!!