読者です 読者をやめる 読者になる 読者になる

@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

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

JavaScript

モチベーション

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

例えば、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要素の「幅、高さ、位置」取得をまとめて行い。 「幅、高さ、位置」設定をまとめて行うと、リフローが防げます。

テスト

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

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

実績

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

1on1ミーティングのやり方

1on1ミーティングに備えるアンケート - しるろぐ を読みました。 大変参考になりました。お礼の代わりに、弊社のやり方を書きます。

前提条件

弊社は20人以下のSIerです。 受託開発や技術支援がメインです、プロダクトを中心とした面談ではありません。

インタビュワーとインタビュイーの組み合わせはプロジェクトに閉じていません。 総当たりで組み合わせています。

面談をはじめたのは退職者対策としてでした*1。 インタビュワーの負担が個人に偏らないように、ベテランエンジニアが全員インタビュワーになります。

やり方

人数

インタビュワーは6人います。ベテランエンジニア5人と営業1人です。

インタビュイーは8人います。 1年目は毎月、それ以外のエンジニアは2ヶ月に一回実施指定います。

組み合わせ

もっとも長い期間面談をしていない組み合わせで実施します。

組み合わせは、モンテカルロ法で抽出します。 そのために GitHub - ledsun/interview-lottery: The lottery for interview を作りました。

その他

弊社には遠隔地の拠点があります。 Skype等のビデオ会議で面接を行います。

面談の議事録はインタビュワー間で共有します。

質問内容

面談を円滑に進めるために聞く内容のテンプレートを作ってあります。

  1. 最近うまくいっていること(やっていること)
  2. うまくいっていないこと
  3. (仕事をやりやすくするために)ほしいもの
  4. 個人のビジョン(どうなりたいか?)

KPTを元にしています。

「うまくいっていること」は言いづらいことが多いようです。その場合は、「やっていること」を聞いています。

「ほしいもの」はTeam Geekからパクリました。

「個人のビジョン」は「時々、(自分の)中長期的な将来のことも考えてみてね」ぐらいのノリで聞いています*2

実施方法

各インタビュワーに任せています。統一した方法等はありません*3

個人的には、ほぼKPTです。 インタビュイーに聞いた内容をホワイトボードに書きながら、質問を掘ったり、各項目を関連付けたりして進めます。

若手のエンジニアはメタ認知*4が苦手なので、KPTを一緒にやるとそれなりに効果があると思います。

お互いの負担を減らすために30分という時間制限を設けています。 個人的にはインタビュイーに話したいことがある限り延長しています。 最大で2時間半ぐらいでした*5

やってよかったこと

会社ハックのきっかけに

個人的に一番面白いのは、会社の仕組みをハックするきっかけが得られる点です。 社内の制度に関する質問をもらえると、仕組みを整理するきっかけになります。

ビジョンの時間変化

「個人のビジョン(どうなりたいか?)」に対する答えが、時間とともにに変わることがわかりました。 こまめに面談をしていないと、一年前に聞いたビジョンに今でも同じように興味があると考えてしまいがちです。 経験を重ねるにつれて興味のある分野が変わるのは、ふつうのことだと思います。

若手の成長を実感

ビジョンの変化と一緒です。 課題と思うことや、興味のあることが変化しているのを通して、若手の成長が実感できるのはうれしいです。

やってわるかったこと

エースエンジニアの時間が取られることです。 人によって得意不得意があります。面談が不得意なエンジニアがインタビューするのは負担が大きいようです。

*1:面談やってても辞める人は辞めますね・・・

*2:ビジョンをダシに「もっと頑張らないとダメだ」みたいな話をすると、お互い面倒臭いですよね。

*3:インタビュワーの面談技術向上は課題です

*4:ここでは「自分が知っていることと、自分が知らないことを切り分けて整理すること」の意

*5:経験則ですが、人間には「3時間話を聞いてくれた人を信頼してしまう」習性があるように思えます。