7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は検索エンジンプロダクトを一緒に開発してた同窓会 Advent Calendar 2023の4日目の記事です!
退職してからも、同窓会としてアドベントカレンダーできて嬉しいです :blush:

書いてる人

私は、フルサイクルエンジニアです。
image.png
出典
※ フロントのみが専門ではないので、内容へのツッコミ大歓迎です!!

書くこと

  1. フレームワークについて
  2. フロントでドメインモデルを使わない事に対する課題感
  3. 例を見よう
  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. まとめ

フロントで、ドメインモデル導入するのはいいぞ!!

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?