スポンサーリンク

コードが書ける!数式が書ける!AAが書ける!スタンプが貼れる!

無料の匿名掲示板型SNS「このはちゃんねる

新規会員募集中!

【設計】変換レイヤーを設けたらデータとオブジェクトの相互変換が捗った話し【JavaScript】

193, 2019-09-24

目次

マルチプロセスなアプリ

ユーザーの入力は何やかんやあってデータベースに保存される。そのデータからオブジェクトを生成してバックグラウンドでデーモン的に動作させたい案件が何件かあった。色々苦労したんだけど、一番大変だったのがデータとオブジェクトの相互変換で、オブジェクトはツリー構造を持ち、入力データはツリー構造のオブジェクトに分担され処理されるので、データを各オブジェクトに変換する必要があった。
また、アプリの設計がマルチプロセスになっていて、プロセス間通信でデータをやり取りして、そのデータを再びオブジェクトとして組み立てる必要もあった。

アプリの破綻

最初はオブジェクトにデータの読み込みと書き出しをやらせていたが、プロジェクトが進むと複雑になって破綻した。それで作りなおす時に設計を見直したら、ストレスがかかっている部分はやはりデータとオブジェクトの相互変換処理部分だった。ここが複雑になると把握できなくなり、仕様変更などが起きると開発者がパンクする。

変換レイヤーを設ける

デザイン・パターンに「Factory」パターンがあるのでこれを参考に変換レイヤーを設けてみた。データからオブジェクト、オブジェクトからデータへの変換はこのレイヤーにやらせる。ファイル「conv.js」がそのレイヤーを担当する。

// conv.js

function dataToJob(data) {
    var jobj = new Job();
    // Convert
    return jobj;
}

function jobToData(jobj) {
    var data = {};
    // Convert
    return data;
}

...

データのレコードが仮にこうだとして、

column1, column2, column3

データのレコードは以下のようなオブジェクト・ツリーに変換される。相互変換だから逆も可。

      job
     /   \
   timer  image
    |
   time

実際には以下のようにして使う。

var jdatas = getRecordsFromTableName('jobs');
var jobj = dataToJob(jdatas[0]); // データ -> オブジェクト
var jdata = jobToData(jobj); // オブジェクト -> データ

データとオブジェクトが変換レイヤーをちょっと通りますよ。。。

  input  -> data <-> conv <-> obj (memory-space)
     db <->
process <->

変換レイヤーはフィルターとバリデーターも兼ねるので、オブジェクトのプライベート変数等、保存の必要のないデータは変換時に削ぎ落とされる。また conv.js 内で各データとオブジェクトの相互変換を一覧出来るので修正も容易になった。ただしフィルタリングとバリデートは各オブジェクトにやらせる。conv.js はそれらのメソッドを利用するだけ。これで何とかイベント駆動のマルチプロセス環境でもある程度のデータ検証が出来るようになったが、改善の余地有りで体力が尽きた。

デメリットとしては conv.js が肥大化するということ。これはオブジェクト毎にコンバーターを用意すれば解決するかも知れないけど、その場合はファイル数が増えそう。

<- 依存方向

Job <- JobConvertor
// convertor
var jconv = new JobConvertor();
var jobj = jconv.dataToObject(data);
var jdata = jconv.objectToData(jobj);

一覧性も落ちるので conv.js 単体で運用したほうがメリットが多いのかも知れない。クラスが数十個あってもそれほど肥大化はしないだろう。ただし conv.js は依存関係がクラスと一対多の関係にあるので、クラスを変更したら必ず一緒に更新する手間がある。これは仕方がないというか、デメリットの部分。

おわりに

変換レイヤーを設けてみてわかったのは、複数のオブジェクトを内包するオブジェクトは管理が手間で、設計も複雑だということ。これはやはり依存関係の問題になる。だが、それほど悠長に設計に時間をかけられないので、どうしてもコーディングに時間を割くようになってしまう。よって、コーディング時間の削減が目下の課題だが、そのためにはコーディングの自動化(それも精度高めの)が必要になってくる。

テンプレートを用意してそれを案件ごとに利用してしまうのがいいが、その場合はテンプレートの成熟度を上げる必要がある。テンプレート利用時にテンプレートのバグを見つけてテンプレートのリポジトリにコミットとかしてたら余計に時間がかかってしまう。テンプレートの成熟は一定期間、どうしても時間が必要になるので成熟させようとしたら大変。

だが、テンプレートの粒度が荒い場合は適用可能な範囲に制限がかかるので、これを主体にするのは危険だろう。よって、スニペットの粒度で熟練度を上げる必要が出てくる。スニペットの積極的な活用が時間削減に繋がり、かつ現実的な手段になるのかもしれない。テンプレートまで行くと粒度が荒いのだろう。だが、スニペットもライブラリと違い、ハードコーディングのサポートになるからバグや仕様変更に弱い。

投稿者名です。64字以内で入力してください。

必要な場合はEメールアドレスを入力してください(全体に公開されます)。

投稿する内容です。

スポンサーリンク

スポンサーリンク

スポンサーリンク

スポンサーリンク