Vue.js設計地図 〜設計概念の依存関係からフロントエンド設計を見つめ直す〜

こんにちは。PLAID Software Engineer, tai-hey ( @Victoria_Peak_ ) です。

まえがき

私はプレイドに入社して1年ほどとなりますが、業務で Vue.js の開発を経験し、自身がフロントの実装にメインで携わり、サービス設計から実装まで取り組む中で設計について思慮することが多くなりました。

プレイドは SPA を実現可能な Vue.js を採用しているのですが、設計をしていく中で、設計のヒントをネット上で検索をしてみても、チュートリアルや部分的な設計の話はでてくるものの、設計概念の依存関係を表すものが無いことに気づきました。

そこで、今回のブログはフロントエンドに関連する設計概念を整理し、それぞれの依存関係を可視化することで今後のスムーズな開発に役立てるべく考察したいと思います。

プレイドでは、会社として開発プロセスを具体的に定義しているわけではなく、開発やプロジェクトの都度で、ゼロベースで最適な方法を個々で考えて採用しております。今回は私の直近のフロントエンド開発の実体験をベースに、個人的にしっくりきたスキームとして整理したいと思います。

なぜ設計が必要か

今回携わった案件では、サービスの設計からシステムの開発までを一気通貫で実施したため、ビジネスサイド、デザイナー、エンジニアのチームで議論していく必要がありました。それにはチームとして一機能を作り込むのに共通認識を作らなければいけない状況となります。ビジネスならどのようなユースケースか、デザイナーならどのようなデザインにするか、エンジニアならデータベースやコンポーネントの設計はどうするか、設計はそれぞれのアウトプットに帰結します。ただ作るだけでなく、考えきってからしっかり作るという設計の重要性を体感したため、設計の全体像から見直すことにしました。



0.本ブログについて

対象読者

■Engineer
コードでSPA設計や開発しているけれども、何を直したらどこに影響があるか、経験や感覚でやっていて、ベースの考え方がほしい方。新規で開発する際に、どのような順序で設計を考えればよいかわからない方。

■Business / Designer
ビジネス側でデザインやシステム開発の活動の立ち位置を把握したい方(1章を見る)
ビジネス側やデザイナーで、成果物となる、システム要件・設計した画面・デザインがシステムに具体的にどのように落とし込まれているかを知りたい方(2章を見る)

スコープ

バックエンドまで含めるとちょっとボリュームが出すぎてしまうので、スコープはサービス設計〜SPAとしてのフロント実装までとします。

題材

題材としてはエッセンスだけを表現したいので、あるジョブのスケジュール実行のシンプルな一覧・詳細画面を例に考察していきます。

本テーマの利用シーン

今後の開発にあたって、機能を一から設計する際に、本ブログにて整理したスキームをベースに開発しようと思います。あくまで一つの手法考え方となりますので、一例として整理し、今後はさらにパターンを増やしていきたいと思います。

章の構成

下記の2章構成で展開します。
1.において開発プロセススキームとなる概念図で全体像を表現します。理論として設計概念を図式化します。
2.は、1で表現した理論を実際にサンプルに落とし込んで考えていきます。

        1.全体の開発プロセス概念を整理する(理論編)
        2.設計概念をベースにした設計例(実践編)
用語:設計概念について

設計概念はあまり一般では使われませんので、このブログでは下記の開発プロセス図にあるような、考える要素の総称(ex:サービス設計、機能設計、モデリング、ディレクトリ設計etc...)を設計概念と定義することとします。



1.全体の開発プロセス概念を整理する(理論編)

1章では、設計をする際の工程と必要な要素を書き出します。下記の図をベースに、まずは設計概念の各要素を説明していきます。

図:開発プロセス概念図
----------2019-09-02-10.36.31

1-1.サービス設計〜デザインの設計概念の整理

図:開発プロセス概念図
----------2019-09-02-10.37.38


Why/What(concept)・サービス設計

サービスコンセプトの設計です。どのようなサービスで、ビジネス的にどのようなインパクトがあるか、作ることでどのような付加価値があるのか、等をビジネスサイドのメンバーと協議しながら決定していきます。

What(function)・機能設計

コンセプトを元に、どのような機能でアウトプットを具体的に表現するのか定義します。
ex) CRUD機能、権限設定、リトライ機能有無etc...

What(model)・モデリング

機能の設計を受けて、データ構造として何を扱うのかを定義します。
DB設計と画面デザインに直接関連するため、エンジニアとデザイナーを中心に詳細を詰めていきます。

What(design)・デザイン

デザイナーメインの成果物となります。モデリングの内容を基に画面遷移も含め、
画面デザインを設計します。

1-2.システム構造の設計概念の整理

How(system)

最後にエンジニアメインの成果物です。システムの構造を決めていきます。
デザイン設計まで決まったものをコードに落としていきますが、SPA 的なフロントエンド開発では下図の赤枠の設計概念を考慮に入れて実装します。

システム上でのメインのインプットはデザイン(画面の遷移含む)とモデリングとなります。
この2つまで決まればフロントエンドで表現するシステムとしては作りの大枠が決まります。

前工程までで何を作るかの What をだいぶ定義できているので、この後はどのように作るかの How をエンジニアとして考えていきます。

この章では下図の後半の範囲を整理していきます。

図:開発プロセス概念図
----------2019-09-02-13.28.25

ディレクトリ構成

ファイルディレクトリ設計思想はモデリングをベースに作成します。
基本はCRUDがメインになるかと思いますので、モデルに沿ってディレクトリ設計をします。ディレクトリ内にコンポーネントを配置します。

ルーティング設計

ルーティングは特定のURLアクセスがあった場合に、URLに記載されたパスに応じてどのコンポーネントを表示するかを指定します。

コンポーネント設計

Vue.js は .vue ファイルの組み合わせで画面構成を構築していきます。
コンポーネントの中にコンポーネントが更に分割されており、ツリー構造で構成されています。

ストア設計

Vue.js の データの状態管理を行います。こちらもモデリングベースでデータを定義します。

ストアは RPC でサーバーサイドから取得したデータなどをフロントでリアルタイムに管理するものです。
ストアの詳細な 説明はこちらを参照。


1-3.設計概念の依存関係について

設計概念の依存関係に気づく

1-1,1-2の整理の中で、私はこれらの設計概念はそれぞれ依存関係があることに気づきました。
全体の整理から発展し、2章につながるので、依存関係について少し立ち止まって考察していきます。
このようにメインの依存関係は左側から右側の順序で流れていきますが、右側を修正したことにより左側にも影響があることがあります。

モデリング ⇔ ディレクトリ構成 ⇔ ルーティング設計 ⇔ コンポーネント設計

----------2019-08-28-15.22.35

上記は私が設計時に参考にしている基本の依存関係です。
モデリングを最初のインプットとしてディレクトリ構成の大枠を決め、モデル毎にディレクトリを分割して、それに同期させるようにルーティング設計を行います。
ルーティングされるコンポーネントが決まったら、それ以下の細かいコンポーネント分割を考えます。
実際のサンプルは2章で紹介します。

基本的には私は上記の依存関係の考え方をベースに設計を進めており、設計順序は記載すると下記のとおりになります。

        モデリングを行う(1章で実施済)
        → ディレクトリ構成を設計
        → ルーティングの決定(ほぼディレクトリと同期する)
        → デザインをベースに各画面毎のコンポーネント設計を決める
モデリング ⇔ ストア設計

----------2019-08-28-15.21.17

2つ目は、上記の設計時の依存関係となります。
モデリングはデータ構造そのものになりますので、それをフロントエンドで表示する際にはストア設計に直結します。


システム設計はモデリング起点だと気づく

さらに、この2つの共通点に気づきます。
モデリングを起点に system である How が影響を受けるということです。
この設計手法では、システム設計はモデリングが重要な位置を占めるようです。
モデリング起点の考え方も2章での実践編の考察に取り込むようにしようと思います。

----------2019-09-04-14.14.22


1章まとめ

1章では各概念の要素の紹介をしてきました。
これで今回整理した理論編の全体像がわかってきたと思います。

設計途中で違和感があれば関連する工程に戻り、やり直すことが前提で、いろんな工程を行き来しながら、関係者の中で成果物を基に議論し、設計をブラッシュアップする方向で問題ありません。

それでは次に進みましょう。2章ではこの概念を元に実際の設計例について説明します。

2.設計概念の依存関係をベースにした、モデリング起点で行う設計例(実践編)

1章で概念的に整理したものを実際に設計してみます。
この例は私が開発していた機能をデフォルメ化したものとなります。

題材のシステム概要

今回のシステム概要は、ざっくりいうとメール配信ジョブのスケジュール管理と、コンテンツ管理のシステムとなります。
モデルデータは実行ジョブの一覧と詳細、メールの配信コンテンツの一覧と詳細の管理です。
この画面でジョブ実行した履歴と、それに紐づくメール文面などのコンテンツを確認することができます。

1章で把握した理論を実践に適用する

1-3で述べたように、設計概念を整理する中で、設計概念には依存関係があることがわかりました。
その依存関係の法則をベースに実際の例として適用していきます。

それでは始めましょう。

2-1. モデリング

まずはモデリングです。

図はシンプルに説明に必要な箇所だけにしていますが、構築するデータ構造によってはもう少し複雑なものになるかもしれません。本例は、ジョブの schedules (いろいろなスケジュールの集まり)、各スケジュールを指す schedule があります。

また、配信するメールコンテンツ(メールの配信文面など)の一覧 mailContents と詳細 mailContent があります。

上記2つのモデルの関連ですが、schedule 毎に一つの mailContent が紐づくので、schedule : mailContent は N:1 となります。

----------2019-09-02-11.32.00


2-2. ディレクトリ設計

次はディレクトリ設計です。

ディレクトリ設計思想はモデリングをベースにschedulesであればそれ用の階層、そのひとつ下の階層に _scheduleId というディレクトリを設けて、schedule 詳細の表示用のコンポーネントを集めます。

また、ディレクトリとルーティングを読み替えて考えるオーバーヘッドをなくすため、ルーティングのパスと同期するように設計しました。

----------2019-08-27-10.18.59


2-3. ルーティング設計

上記の通り、ルーティングをほぼディレクトリに合わせています。
今回の開発では当初同じディレクトリに配下にしてパラメータで切り替えるとか、モデリングとずらした設計にしていたりしたのですが、ルーティングとモデルの切り替えの頭をかなり使うので苦労しました。
この形式にしてからはその切り替えがほぼ必要なくなってリーディングもコーディングも楽になりました。

----------2019-08-27-10.20.07


2-4. コンポーネント設計

スケジュールジョブの画面設計は図の通りです。
ここまで来るとディレクトリ設計にあるように各階層でコンポーネントを設計していけばよいです。
デザインをインプットに、どの枠をどの範囲をコンポーネントファイル一つ一つに割り当てていくかを決定していきます。

※scheduleのみ表現します。mailContentsと似たようなものになるので。

----------2019-08-27-11.11.24

こちらはジョブスケジュールの一覧画面です。(以下.vue省略)
左に Navi (システムcommonから呼び出し),右に App を定義して App 内でApp 内は Header と List に分けます。List 内ではジョブの項目名を表現する ListHeader と ジョブの実態となる Item に分けます。

----------2019-08-27-11.12.47

こちらは詳細画面です。
スケジュール画面と似たような形でHeaderとジョブ情報のDetailで分けていきます。

----------2019-08-27-11.13.09-1


2-5. ストア設計

ストア設計はモデリングに倣っているので、ほぼ考える必要はありません。
下記のようにディレクトリ設計のようにIDを挟んで表現しておきます。

----------2019-09-04-14.26.22


2-6.依存関係をベースに、モデリングベースで設計したことの評価・所感

実践を通して感じた設計手法の評価、所感は下記のとおりです。

・新規観点:新規で実装する際に、思考スキームが設計概念として可視化されていることで、自分の立ち位置を把握しながら、順序を追って進捗させることができました。
設計の手探り感がなくなり、以前よりも手戻りも少なくスムーズに設計開発することができました。
モデル起点とするため、モデリングさえしっかりしてしまえば、システムの構成としてはあまり悩むことなく
開発できたと思います。

・修正観点:一度コードを書いたあと、ディレクトリ構成を若干変える必要があったりしたのですが、元の考え方が明確になっているため、比較的構成の若干の変更はしやすかったと思います。

まとめ

以上のように理論編と実践編で Vue.js での設計について紹介してきました。

設計スキームとして今回のやり方は私にはしっくりきていて、一つの設計手法として、武器が一つ増えたように感じています。

この設計手法はコミュニケーションとしても効用がありました。
頭の中を図にして深く理解することで、チーム内コミュニケーションにおいても認識齟齬を生まれにくくしたり、
自分の中でも矛盾のある箇所を発見しやすい、という効果も期待できました。

ただし、毎回同じようなやり方になってしまうと、やりやすいやり方に流れてしまい、より最適な方法を見つけなくなってしまうことがあるかと思います。
それについてはプレイドの思想らしく、今回のやり方に固執しすぎずに、常にゼロベースで考え、他の概念を作り出してみたり、設計パターンを変えてみたりすることでバリエーションを増やすことにトライしていきたいと思います。

最後に

CX(顧客体験)プラットフォーム「KARTE」を運営するプレイドでは、KARTEを使ってこんなアプリケーションが作りたい! KARTE自体の開発に興味がある!というエンジニア(インターンも!)を募集しています。
詳しくは弊社採用ページまたはWantedlyをご覧ください。 もしくはお気軽に、下記の「話を聞きに行きたい」ボタンを押してください!