Corredor

ウェブ、プログラミングの勉強メモ。

フロントエンドシステムにおけるデータ永続化のためのクラス・ディレクトリ構成を考える

ステートフルJavaScript ―MVCアーキテクチャに基づくWebアプリケーションの状態管理

ステートフルJavaScript ―MVCアーキテクチャに基づくWebアプリケーションの状態管理

MVC アーキテクチャ

古くは Struts からあるような、サーバサイドも含めた MVC アーキテクチャのシステムの場合、大抵は DB アクセスを行う DAO クラスが存在し、それ向けの構成が大体決まっている。

  • View
    • 一番表は HTML。form 要素が Form クラスと対応づいていたりする。
  • Controller
    • Action クラスと呼んだり。
    • Form クラスの値を、ビジネスロジッククラスが扱う DTO (Data Transfer Object) クラスに移し替えたり。
  • Model
    • ビジネスロジッククラス。サービスクラスと呼んだりも。
    • DTO の内容を、DB のテーブル定義と対応づいている Entity クラスに移し替えたりする。
    • DAO (Data Access Object) クラスが Entity クラスを受け取り、DB アクセスに使ったりする。

もしくは、Rails のような場合は、ActiveRecord というアプローチで、Model に相当するクラスが最初から DB のテーブル定義と対になっていて、Model クラス自身が「DTO / Entity 兼 DAO」な作りになっていたりする。

データ永続化のアプローチにはこんなやり方が一般的だ。

MVC のディレクトリ構成

MVC デザインパターンのプロジェクトのディレクトリ構成は、以下の2種類に大別できるであろう。

1. 種類別

ModelViewController という種類のディレクトリを切り、その下にクラスが連なる作り。大規模なシステムをこのやり方で作ると、ディレクトリの往来が大変になる。

MyProject
┣models
┃┣HogeModel
┃┗FugaModel
┣views
┃┣HogeView
┃┗FugaView
┗controllers
  ┣HogeController
  ┗FugaController

2. 機能別

まず機能ごと (hogefuga) にディレクトリを分け、その中で ModelViewController といった種類を分ける。このやり方だと、特定の機能を切り出したりする時にディレクトリごと移動・削除するだけで対応できて分かりやすい。

MyProject
┣hoge
┃┣models
┃┃┗HogeModel
┃┣views
┃┃┗HogeView
┃┗controllers
┃  ┗HogeController
┗fuga
  ┣models
  ┃┗FugaModel
  ┣views
  ┃┗FugaView
  ┗controllers
    ┗FugaController

最近は後者の機能別の構成が多いかな?

フロントエンドシステムにおけるデータ永続化

さて、本題に近付いてきた。

バックエンドシステムを含まない、フロントエンドオンリーのシステムにおいても、フロントエンドの中でデータ保持が必要な場合は存在する。SessionStorage や LocalStorage の他、SQLite を利用してローカル DB を持つ場合などがあり得る。

こんなシステムにおいて、どのようなクラス分けを行い、どのようなディレクトリ構成でクラスを管理すると、データ永続化が綺麗にできるだろうか、というのが今回の課題。

いくつか調べてみた感じだと、React.js や Angular のようなライブラリ・フレームワークだと、それ単体で構成するクラスの種類別にディレクトリを作る話しか出てこない。

これはつまり、データ永続化が必要なパターンが少なく、JavaScript なので型を意識することも少ないので、コンポーネント内に適当に混ぜ込んでおいてなんとかなる、ということなのだろうか。

TypeScript を使う Angular の場合は型に対するアプローチはどうなるだろう、とか、Cordova で作るハイブリッドアプリの場合は永続化が必要だよな、とか、色々気になるので、もう少し調べてみた。

  • GitHub - smithad15/angular2-folder-structure-example: File and Folder Structure Example for an Angular 2 App with Redux
    • Angular2 系のディレクトリ構成のサンプル。
    • そうそう、機能のディレクトリは複数形 (families)、ページコンポーネントは単数形 (family-list・family-details)。
    • app/families/shared/types/ で DTO 的なインターフェースの定義をしている。
    • ユーザ登録はregistration と表現している。
  • Angular Docs
    • Angular4 公式のスタイルガイド。イマイチデータ永続化に関する資料なし。DTO チックな hero は居る。
  • ecmascript 6 - DTO Design in TypeScript/Angular2 - Stack Overflow
    • Angular アプリにおける DTO のデザインに関する話。private プロパティを除いた DTO オブジェクトを返す方法としてデコレータを使ったサンプルなどがある。
    • そもそも Angular アプリに DTO クラスが出て来ること自体は不自然ではない様子。
  • ionic 2 | Tech Blog
    • Ionic-Native の少し古いバージョンを使った、Angular 内にローカル DB サービスを作るサンプル。
    • DB 接続から User 情報の Insert や Select を行う1つの DatabaseProvider クラスが出てくるだけ。User 以外の情報を扱う時もこのクラスが膨れていくだけなのだろうか…?
    • メソッド名は openDatabasecreateUserTableinsertIntoUserfetchFromUserdropDatabaseSELECT ではなく Fetch なのね。
  • Use SQLite In Ionic 2 Instead Of Local Storage
    • コンポーネントから DB サービスを直接叩いているし、SQL 文をコンポーネントクラスに書いている。サンプルだから仕方ないか。
  • Ionic 2 SqlStorage with SQLite and Cordova • techiediaries
    • こちらも同様。サンプルだとディレクトリ構成とか無視してコンポーネントに書いてるものしかない…。
  • How to Use Ionic SQLite Queries & Pre-Populated Database - Devdactic
    • これは DB サービスクラスを作っている。複数のテーブルを管理するようなサンプルがない…。

…ということで、複数のモデルを扱うようなサンプルがイマイチ見当たらず。これといった解が得られなかった。

最近のアプリは API サーバと RESTful にやり取りして、ローカル DB とか要らないんだろうか。いやでもしかし…必要な場合はあるし…そんなロジックを適当に1つの DB クラスに混ぜ込んだりとか…気持ち悪いし…。

誰か良いサンプルがあったら教えてください。