@ledsun blog

無味の味は佳境に入らざればすなわち知れず

テキストより複雑な構造のデータを扱うWikipediaを作る

モチベーション

専門性を持った不特定多数のユーザに協力してもらい、個人では作り得ない大規模なデータベースを作りたいことがあります。

例えば、Wikipediaは、(記述の正確性や公平性における問題は抱えているかもしれませんが)規模の点で成功しています。

Wikipediaのエディタはオンライン百科事典のエディタとして特化しています。百科事典ではないデータを扱うデータベースの場合、Wikipediaのエディタは機能が合いません。

必要なもの

複雑な構造のデータを扱うたデータベースを作るには何が必要でしょうか?

ブラウザ上で動くビジュアルエディタが必要です。

なぜでしょうか?

インストール不要

インストール不要なため、編集環境を構築するコストが低いです。 編集用のアプリケーションをダウンロードして、個人のPCにインストールするのはボランティアで参加してもらうにはコストが高いです。

エディタの学習コストが低い

編集内容をビジュアルで表現すれば、エディタの操作が直感的になり、操作方法の学習コストが下がります。

データを直接編集する学習コストは高いです。 例えばDBPediaの情報を編集するには、DBPediaのデータフォーマットに関する専門知識が必要です。

つまり

ブラウザで動作するビジュアルエディタを提供することで、不特定多数のユーザーが編集に参加しやすくなります。

先行例

一般消費者向けのアプリケーションも作られるようになりました。

どうやって作ればいいのか?

技術要素は、2005年に公開された、Google Map変わっていません。

ただし、10年間で各要素はそれぞれ高度化しました。 一つのビジュアルエディタのJavaScriptファイルが数千行に達することは珍しくありません。

難しさ

複雑なソフトウェアを、要件に合わせて適切に設計・実装できる、ソフトウェア開発技術者が必要です。

ビジュアルエディタの場合は、次に挙げる難しさがあります。

  • わかりやすい操作方法の設計
  • 選択状態の管理
  • 編集途中状態の管理
  • UNDO/REDO機能
  • データの依存関係に応じた編集
  • パフォーマンス
  • テスト

わかりやすい操作方法の設計

わかりやすい操作方法は、編集したいデータ形式や、想定するユーザーによって変わります。

一般的な指針はあります。例えば、

  1. 編集の敷居を下げるには、ヘルプを参照せずに、マウスまたはタップ操作のみで編集を完了できると良い
  2. PCに慣れたユーザーはキーボードショートカットがあると便利に感じる
  3. ショートカットは世の中の既存のエディタと共通の方が良い

しかし、独自のデータを扱うアプリケーションを作る場合は、アプリケーション毎に試行錯誤が必要な部分は残ります。

選択状態の管理

「マウスまたはタップ操作のみで編集が完了」するには、編集対象のオブジェクトを選択する必要があります。 選択できない場合は、idや座標で編集対象のオブジェクトを指定して編集します。

オブジェクトが選択できると

  • 選択している時だけ編集可能にする(切り取りボタンを有効にするなど)
  • 編集機能やエディタの状態によって選択可能/不可能を切り替える

必要があります。

複数のオブジェクトが選択可能な場合は

  • 複数選択の操作方法の設計(例えばCtrl押しながら、Shiftを押しながら)
  • 編集機能やエディタの状態によって複数選択可能/不可能を切り替える
  • 異なる種類のオブジェクトを選択した場合の動作の設計

が必要です。

オブジェクト生成時に自動選択

オブジェクトの生成後に自動選択したい場合があります。その場合、

  1. データ上のオブジェクト作成
  2. DOM上のオブジェクト作成
  3. データ上のオブジェクト選択
  4. DOM上のオブジェクト選択

の順序を制御する必要があります。 VIrtualDOMで表現できないビューを扱う場合は、モデルの操作とビューの操作が交互に行うため、原始的なMVCでは監視コントローラーパターンが使えません。 監視コントローラーパターンを使うには、MVPパターンを導入し、選択状態の管理をコントローラーから分離します。

編集途中状態の管理

エディタでは編集途中状態を扱います。

たとえば、テキストエディタは編集した文章を保存せずに終了することができます。 エディタを閉じる際に次の動作をしたいことがあります。

  • 未保存データがある旨の警告表示
  • 自動保存
  • 下書き状態として保存

ブラウザのonbeforeunloadを使って、これらの動作を実装します。

UNDO/REDO機能

エディタはUNDO/REDO機能があると便利になります。

VirtualDOMを使っている場合など、ビューがデータの射影として表現できれば、データのスナップショットをとっておくことで実現できます。

次の要件がある場合

  • メモリの消費を減らしたい
  • ビューの更新ロジックが複雑

データ操作を一度コマンドオブジェクトとして生成し、履歴として保存しておく必要があります。 各コマンドで

  • UNDOの実行
  • REDOコマンドの生成

ができれば、UNDO/REDOは実装可能です。

データの依存関係に応じた編集

データ構造によってはデータの依存関係があります。

例えば、ツリー構造の場合は親データを削除した時には子データも削除します。 ビューをDOMのツリー構造として構築していれば、データの親オブジェクトとDOMの親要素を消すことを対応付けることができます。

UNDOがある場合は、親オブジェクトが削除する時は、削除前に持っていた子を保存する必要があります。 UNDO時には保存情報から親オブジェクトと子オブジェクトを両方復元します。

パフォーマンス

DOM操作のパフォーマンスを出すには独特のテクニックが必要です。

DOMへの要素追加のタイミングを気をつける他に、リフローと呼ばれる現象を防ぐ必要があります。

DOM要素の「幅、高さ、位置」を取る場合、ブラウザは描画内容を再計算します。 DOM要素の「幅、高さ、位置」取得と、「幅、高さ、位置」設定を個別に繰り返すと、ブラウザの再描画計算が大量に実行されパフォーマンス低下を招きます。 これとリフローと呼びます。

参照したい全DOM要素の「幅、高さ、位置」取得をまとめて行い。 「幅、高さ、位置」設定をまとめて行うと、リフローが防げます。

テスト

ビジュアルエディタの機能では見た目が重要です。 テストをする際にも見た目の確認が大きなウェイトを占めます。 機能を満たしても、使いにくかったり、使い方が直感的にわからなかったりすれば、要求は満たせません。

一般的な、業務アプリケーションの業務ロジックのテストとは異なるアプローチが必要です。 人間が手と目を使って繰り返しテストすることが、非常に有効です。 テストケースの作成とテスト実施には、忍者式テストというテスト手法が有効です。

実績

作成したビジュアルエディタです。