人生がRPGだったら

ふと思いついたのでメモしておく。

  • パラメータ
    • 体力(HP)
      • 体力の原資。時間経過・行動・外部からの刺激などにより変動する。0になると死ぬ。上限は体質改善で可能だが通常の肉体は年齢の影響を大きく受ける。
    • 精神力(MP)
      • 精神的な原資。時間経過・行動・外部からの刺激などにより変動する。0になると行動不能になる。上限は変化せず。*1
    • 信頼(TST)
      • 相手が自分をどれだけ信頼しているか。相手(個人や組織)が個別に自分に対して持つパラメータなので、自分と相手の組み合わせによって値が決定する。
    • 技術(SKILL)
      • 自分の持つ技術。
    • 才能(GIFT)
      • 天性の資質。ゲーム内の隠しパラメータとして多くに影響を与えるが、値として確認することができず、値は固定。*2
  • パラメータに関するルール
    • 時間経過や行動は多くの場合HPとMPを消費するが、睡眠のように回復を伴う行動もある。
    • 時間経過・行動・外部からの刺激などに伴うHPおよびMPの変動量は様々な要因によって変化する。
      • 個人の嗜好:『快』と『不快』の感情により消費量が変わる。*3
      • 自己の状態:自己の状態が『快』と『不快』の感情に大きく影響し、結果としてMP/HP消費量が変わる。*4
      • 外部環境:何らかの行動をする場合、周囲からの期待、監視の目、強制力、などがHP/MPの消費量に影響を与える。*5
  • エス
    • 他人や組織からの依頼や任務。クエストの大きさは TST に大きな影響を受ける。クエストの達成は独力でも人からの協力を得てもよい。*6
    • エストの達成は TST 向上に大きく貢献する。

*1:上限が変化しないという点が重要。これは、精神力という漠然とした1つの力の存在を否定している。どれだけきつい修行に耐えられる格闘家でもピーマンが食べられないとか、どれだけ仕事ができるビジネスマンでも自分の部屋が片付けられないとか普通にあり得る。心理学的にもほぼ定説と言える(あがり症や高所恐怖症などの神経症は漠然とした精神力というものでは説明できない)。

*2:特別な理由がない限り、GIFTの影響が強いと思われるものを変更するのは避けたほうが無難。例えば性格を変えようとか、どれだけ努力しても人並程度すら程遠い運動競技への固執とか。

*3:『快』と感じることを増やし『不快』と感じることを減らすのがHP/MPの消費量を下げることにつながる。

*4:例えば、歩くという行為は、足を怪我している時は痛みなどにより不快感が増しMP消費量が増加するし、傷口が開いたり出血すればHP消費量も増加する。

*5:例えば締切り前の漫画家の場合、一人で原稿を上げるだけのMPが無くても、編集からの催促やホテルへの缶詰めなどによるMP消費低減策により原稿の上がる可能性が増す。アシスタントを増やすという方法は、自身の行動量を減らした結果として自身のMP消費が減るだけであり、行動に対するMP消費の低減とは異なる。

*6:自分個人で自分に対してクエストを発行することはできない。

java や kotlin でもポインタを扱いたい件

多角的に検証してないけどとりあえず思い付きをメモしてみた。

状態を持つ Session オブジェクトを UI から操作する場合を考えてみる。

Session が単一の interface を持つ場合は、特定状態では実行不可能なメソッドを叩くと実行時例外がスローされるように作ることが多い。

しかし、そもそも実行不可能なメソッドを叩けなくするというアプローチもある。状態遷移を起こすメソッドの戻り値を状態遷移イベントにして、その中に次の状態用のインタフェースを入れておくとか。

この場合、状態用のインタフェースの参照を UI が保持してしまうと、Session 側で破棄されても UI 側で使えてしまう。もしそれがポインタであれば、Session 側で ポインタの値を null にするなり新しい値にしておけば、古い参照を使用することが不可能になる。

実際問題として正しいコードを書く分にはポインタがあろうがなかろうが関係ないのだが、assertion のコストが全然違う。UI側が古い参照を叩いてしまうというバグについては、ポインタが使える場合はヌルポで落ちるだけなので何もしなくてもよいということもある。しかしポインタが使えない場合は古いものを叩いた時に実行時例外をスローするような仕組みが必要となり、それを入れないとエラーと気づかないまま間違った動作をしてしまう可能性がある。

現状だと開発者に対するルールで縛るしかなさそうな気がする、、、。

Database Answers

Database Answers というサイトがあった。

50以上の業界と1500以上のデータモデルが含まれているらしい。

特定業界向けのシステム開発をする際のデータ構造や命名の参考になるかもですね。

interface 仕様をコードで記述する

とりあえず絵の餅を描いてみるw

interface 上に定義されている関数について、document に仕様を記述し、実装クラスに実装するというのは結構普通に行われるが、その仕様がほぼ純粋に複雑なロジックだった場合、以下のような問題がある。

  • ドキュメント中に書かれた自然言語によるロジック説明が非常にわかりづらい上に曖昧。
  • ドキュメント中のロジックが正しい保証が得られない。
  • 複雑なロジックであればあるほど、ドキュメントとコードが乖離する可能性が高まる。また、乖離したかどうかを確認する機械的な手法が無い。
  • 疑似コード方式でロジックを検討するにしても、疑似コードは実装フェーズの成果物である実装クラス上で行うものなので、要求開発時には行えない。要求開発時に行うためにモジュールの外部インタフェースのドキュメントとして記述するとしても、実装との乖離が無いように保守する必要があり、また、どれだけコストをかけても実装との乖離が無いことを証明する方法がない。*1

上記のような問題を扱う工数をかけるより、kotlin であれば interface 上にソースコードを書いてしまうほうがラクチンな気がする。以下案:

  • 仕様レベルに属する interface のロジック仕様を記述する抽象クラスを作成する。
  • 仕様インタフェースレベルのドキュメントには概要を記述するが、ロジックは一切記述せず、抽象クラスへのリンクを見せるだけにする。*2
  • 抽象クラスは Xxx を implements して XxxBase という命名で統一。(Xxx は仕様レベルに属する interface の名前)
  • 抽象クラスに疑似コードを記述するという作業を全てのモジュールインタフェースに対して行い、その後、仕様レベルのロジックのみ実コードに置き換えていく。*3
  • 仕様レベルで決定する必要が無いロジックは TemplateMethod として実装クラスに丸投げする。*4
  • 切り出したいロジックがある場合は、必要に応じて別関数として切り出す。*5

上記の成果物までを要求開発フェーズの後半に含めることにより、低コストかつ高精度で要求開発の精度が上がるんじゃないだろうか。予想可能な一定の工数を支払う代わりに予想不可能な実装フェーズでの手戻りを減らせるという効果が期待できるかも。特に、開発後期に大人数を投入してリードタイムを削減する場合、設計への手戻りコストが非常に高くつくので、この方法は有効な気がする。

絵に描いた餅おしまいw

*1:そもそも、このような保守は、進捗と品質のトレードオフという概念が存在する組織では成り立たない。品質の全責任を負い、品質以外の一切の責任を持たず、開発部門の全権限を上回る権限を持つ品質管理部門が無い限り無理。

*2:意味的に結合しているので依存しても問題ない。っていうか依存させるべき。

*3:疑似コード作成者はその疑似コードに対する実コードを書いてはいけないというルールがあるといいかもですね。同一の人物やペアが実装することが常態化すると疑似コードの品質維持が難しい気がする。もしくは、レビュー参加者からランダムで実装者を選ぶということにすれば、全レビュー参加者が気を抜けなくなる気がするw

*4:例えばソートする必要がある場合など、ソートアルゴリズムは非機能要件さえ満たせれば何でもいいので仕様記述に含める必要が無い。っていうか含めちゃいけない。

*5:構文的かつ意味的にも重複しているコードの切り出しは必要だが、それ以外のコードの切り出しは細かく切り出し過ぎないように注意する。メソッドは短いほうが良いというのは過去のプラクティスであり、別メソッドに切り出す理由がメソッドの長さだけであるならすべきではない。選択や反復のブロックも、目視するのに困難なレベルの複雑さ以外の時は切り出すべきではない。

疑似コード(pseudocode)について

ふと思ったのでメモ。

疑似コードをプロジェクトで正式に採用したことはないんだけど、要求開発のツールとしてドメインモデリングを採用する際に、インタフェース設計の後に一段階入れても面白いかも。予想されるメリットは以下:

  • インタフェース設計のみより多くのフィードバックが期待でき、コストもそれほど大きくない。*1
  • リリース後の保守コストがゼロ。*2
  • 工数の見積もりが高精度で立てられ、かつ、この活動によって、工数の読みづらい実装時の手戻りを削減できる。*3
  • ソースコードシンタックスエラーを気にして不必要に細かいところまで考えてしまうことが無くなる。
  • 実装時にソースコード上のコメントを考えることや、実装後に後付けすることが無くなる。結果として、実装に準じるようにうまくコメントを書くという本来と逆の思考により不適切なコメントを書くことを避けられる。
  • レビュー時に、実装技術の細かい話の話になったり、レビュー者が実装技術の細かい点につい意識を持って行かれるようなことが無い。*4
  • ダメな案を抱えてしまうリスクの排除。*5

要検討な点:

  • 疑似コードを利用するかどうかの判断が必要になる。*6
  • 書式をある程度一般化する必要がある。*7
  • 複雑だが本質的なロジックの場合、ソースコードを直接書いたほうが厳密かつ分かりやすいよね。そういう場合にどうするか。*8
  • どこまで疑似コードで掘り下げるかの判断基準が必要。*9

*1:インタフェース設計フェーズを拡張するだけで行けると思われ。

*2:リリース時には疑似コードはすべて実際のコードに置き換わっているため。

*3:固定金利と変動金利スワップのようなもので、リスク管理手法としてはかなりおいしいと思われる。

*4:設計レベルのレビュー時にインデントのスタイルとかスペースの入れ方とかfor/while/forEach等のどれを使うべきかとかを話しても意味がない

*5:コーディングまで完了させてしまうと、心理的にそのコードを捨てづらくなる。数行の疑似コードであれば捨てやすい。

*6:setter/getterなどに作っても意味が無いので。しかし、setterにバリデーションがあったらどうなの?とか考えだすと、かなり明確な判断基準がないと運用が難しそう。っていうか、全部疑似コードを書くと決めてしまったほうが早いかもですね。単純なgetterならお決まりの文を1行入れるだけなのでコストはかからんし、後でバリデーションロジックなどが入るかもしれんし。そもそも疑似コードを書くという行為によって『バリデーションいるんじゃね?』的な気付きを得られる可能性が増すという考えもあるよね。

*7:順次・選択・反復系をどう表すかなど。たぶん、いくつかのパターンの例を示しておく程度でもいい気がする。形式化しすぎると本末転倒だし。

*8:例えば、独自サービスのポイント付与ロジックとか、大半はプログラミング言語の syntax で記述したほうがわかりやすいと思われる。

*9:インタフェースからほぼ自明な処理は疑似コードは書かず、そうでないものはすべて機械的に実装に書き換えられるレベルの粒度まで掘り下げてもいいかも。しかし、ドメインモデルのインタフェース直下ではなく派生したルーチンとかクラスが必要になる場合は要検討だけど、直観的にはそこまではやらんほうがいいと思われる。そこまでやったらもう要求設計フェーズじゃないよねwww。ドメインモデル以外については、臨機応変にやるのがたぶん正解。作業者のレベルや経験値やコード資産の流用などによる影響が大きすぎるので。

英語勉強法について

思ったことをとりあえずメモするプレイスホルダー。思い付きやネイティブのESL教師に聞いた方法など。

  • あらゆる学習法に共通する学習効果の法則。
    • 最も効果が高いのは、学習前にできなかったことが学習後にできるようなるという学習。*1
    • 感覚的に腑に落ちているかどうかが学習効果に比例する。*2
    • 最も効果が無いのは、意識が受動的になっている学習。*3
  • 感情の高さと学習効率は比例する*4
  • 学習意欲の維持が重要。*5
  • 学習方法による学習効率の違いは大きい。自分の現在の能力に合った学習法を随時選択するのが重要。*6
  • 文法の雰囲気読みは厳禁。単語の雰囲気読みはアリ。*7
  • 英語に慣れる訓練1
    • 方法
      1. 自分なりに流暢に発音できる長さの文章(節や1文でも良い)を選ぶ。(英会話のフレーズでもニュース記事でもなんでもOK)
      2. 文章の先頭から精読する。その際、日本語に翻訳しないように注意する。単語レベルでどうしても日本語が思い浮かんでしまう人はなるべくそれを抑制することを意識しながら進める。しかし、語順を変えて理解するのは厳禁。精読できなかったらその文章はスキップして次の文章に進む。
      3. 目の前に話し相手やプレゼンの聴衆がいるのを想像しながら、身振り手振りを行い表情や声の抑揚を意識しながら実際に声に出して読む。声とボディランゲージに自分の意思が乗ったと感じたら次の文章に進む。5分やってみてもうまく行かなかった場合も次の文章に進む。
    • ポイント
      • 脳内活動も筋肉の活動も神経活動であり、思考、表情、口周辺の筋肉、発音、声の抑揚、ボディランゲージ等が正しく連動している状況を神経に記憶させるのが狙い。そのため、感覚レベルで理解できている文章のみを扱い、そうでない文章はスキップするのが重要。
  • 英文を順番に理解する訓練1
    • 方法
      1. 自分の興味のある文章(書籍や新聞記事など)を選ぶ。
      2. 声を出さずに文章中の1単語を見る。
      3. 『その単語の意味』と『その単語までの一連の意味』が
        • 『その単語まででは意味として成立しない』と思ったら、次の単語に
        • 『感覚的』に理解できたら、その単語を『声に出して』発音し、その単語までを隠す。
        • 『感覚的』に理解できなかったら、『精読』して理解し、隠していた文章を戻して再度挑戦する。
      4. 1つの文の意味が理解できたら次の文に進む。
    • ポイント
      • 自分の実力で辞書を使って1分以内に『精読』できない文が1ページ平均で最大2文以内のものを選ぶ。そのような文章が見つからない場合は文法学習をしましょう。
      • 『精読』は厳守。単語から推測する雰囲気読みをしてしまうとこの学習は全く意味がなくなる。自分でも雰囲気読みかどうかわからない場合は、料理のレシピを読みながら頭の中で調理をシミュレートするのがおすすめ。*8
      • 文章中の1単語を見て、単語を認識し、文脈から意味を推測し、意味を感覚的に理解する、という一連の行為に時間設定をしないようにする。
      • 精読は数分程度の制限時間内に行い、精読できなかったら頭を切り替えて次に進む。ネイティブでも感覚的に理解できるが『精読』できない英文は多い。ここでこだわって停滞してしまう人は人生という制限時間内に英語が使えるようにはなれない。
      • 次の単語のみを表示してそれ以外全てを隠すという方法は逆効果。科学的な裏付けはないが、おそらく人間は、一瞬で文全体の構造の先読みと、直近の数単語の先読みを行い、推測の精度を上げていると思われる。
  • 英文を順番に理解する訓練2
    • 方法
      • 訓練1を行いつつ、句や節や文の単位で空で発音する。*9
    • ポイント
      • 訓練1では自分でも気づかないうちに雰囲気読みをしてしまうことがあるが、この方法では雰囲気読みが通用しづらい。
      • 部分的に単語が変わっていたとしても意味が同じで文法的に正しい文章であればOKと割り切るのが重要。*10
  • リスニング訓練1
    • 方法
      • 繰り返し聞くことが可能な英語のセンテンス発音を用意する。アメリカ英語ならCNNやイギリス英語ならBBCのようなクリアな発音がおすすめ。
      • 精読して意味を取る。一般的な構造の文なら普通に精読し、言い回しなどは丸暗記でも構わない。和訳はしないように注意する。
      • 音を聞きながらある程度流暢に発音できるまで練習する。自分の声を聴きながらオーバーラッピングできるようにする。
      • 音を録音して自分の声と教材の音声の違いを確認しながら、違いが感じられなくなるまで繰り返す。
    • 備考
      • 学習内容は完全に発音訓練だが、これがリスニングの訓練になる。
      • リスニング能力の向上のためには、おそらく純粋に音を聞き分ける訓練をする必要はほとんどない。マイ・フェア・レディに出てくるヒギンズ教授のような形で言語学を研究したい人は別だが。
      • 純粋に音を聞き分ける訓練が必要ない理由は、第一に、音を聞き分けられたかを確認する学習教材を十分な量調達するのは現実的ではないということ。音を聞き分けられたかをチェックするためには、教材は完全な使い捨てになる。繰り返し使ったら、それは聞き取れたのか前に学習した記憶が残っているのかを判断できない。第二に、リスニング能力と音を聞き分ける能力にはほとんど相関が無いと思われるため。例えば、ネイティブであれば、なまりがあっても、騒音の中でも、音が微妙に途切れる電話回線で通話しても、食べ物をほおばりながら会話をしても、大抵は聞き取れる。また、早口になると音が替わったり抜けたりするケースも多い。つまり、正しい英語発音と大きくかけ離れていても英語として把握が可能と言える。*11重要なのは、リズムと音節と抑揚と状況からの推測。推測をするためには状況に合った文を自分で作り出す作文能力が重要となるのだが、これはこの訓練で鍛えることができる。また、リズムと音節と抑揚もこの訓練で鍛えることができる。
      • この訓練の成果がある程度実ってきたら、リスニングに特化した訓練をあえて設ける必要は無い気がしますね。これ以上の英語能力は恐らくノンネイティブとして通常の範囲を超えているので。CNNなどを当たり前のように精読レベルで聞き取れてシャドーイングやリピーティングでノンネイティブとしては完璧なレベルで発音できるのだから、これ以上リスニングの訓練をする必要性は考えづらい。
  • リスニング訓練2
    • 前提条件
      • 英語ニュースに出てくるレベルの文章を精読可能な英語力。*12
    • 方法
      • 繰り返し聞くことが可能な音源(ニュースやドラマなど)を用意して、とにかく聴きまくる。
      • 明らかに先頭から最後までを順番に自然に理解できたと直感できた場合はその英文はOK。それ以外の場合は紙に書き出すなどしながら厳密に意味を調査し、聞き取りにくかった部分を感覚的に聞き取れるように感じるまで何度も繰り返して聞く。

*1:知らなかったことを知る、できなかったことができるようになる、という類のもの。忘れたりできなくなったりすることについては全く気にする必要は無い。なぜなら、忘れたりできなくなったらまた学習するというのを繰り返すのが王道だから。

*2:たとえば、初心者が映画のセリフを学習する場合、自分のレベルに合わない難しいセリフをどれだけ学習しても意味がない。全く無意味とは言わないが、正しい順序の学習の1%以下の効率であると考えたうえでやったほうがいい。

*3:たとえば、聞くだけで英語が喋れるようになるというような教材は、学習中の意識の在り方により学習効果が全く異なる。ダメなケースは、ながらで聞く場合。学習効果はほぼ0と思ってよい。ダメでないケースは、意識的に、文法の調査、文章を頭から理解する努力、シャドーイング、リピーティング、オーバーラッピングなどを行っている場合。

*4:英語が通じて嬉しかったり、英語がうまく話せなくて恥ずかしい思いや悔しい思いをしたりするのが劇的に有効。英語に限らず学習全般において、人間の脳はおそらくそういうようにできている。

*5:嫌な勉強法で英語が嫌いになるよりも好きな勉強法のほうが良い。

*6:英語初心者なら、CNNを毎日10時間1年聞くより初心者用の本を1冊読んだほうが確実に上達する。仮に本1冊5時間で読めるとすると、その最初の5時間に限れば、前者と後者では学習効率に730倍以上の差があることになる。

*7:そもそも単語に関してはネイティブでも雰囲気読みをしているし、厳密な意味など存在しない。単語自体が抽象化の産物なので、発言者本人の意図するものを正確に表現することは本質的に不可能。日本人が日本語を読む時も、人によって単語の捉え方は異なるし、間違って覚えていることもある。単語の厳密な意味という幻想はネイティブ並みの英語力になって英語教授法が必要とされる職業などに就いた場合にのみ考えればよく、そうでない人は、単語の意味を現状より正しくもしくは詳しく知りたくなった時に英英辞書で調べるのが正解。しかし、文法の雰囲気読みは不可で、これをやると英語的な感覚から逆に離れていってしまうこともある。単語は読み飛ばしていても何度もいろんな文脈で同じ単語を見ていれば感覚的に体に染み込んでいくが、文法は精読して理解しないと学習効果が得られない(パターンを自然に学習するという手もあるが、既に英語以外を母語としている人は日本の中学レベルの英文法ですら一生かかっても無理だと思われる)。

*8:料理のレシピは日本の受験英語で習わない単語や言い回しが多いので最低でもTOEICのRで425程度は取れる実力じゃないと難しいのだが、、、。

*9:15-20単語程度が理想。区切りが悪く20単語を超えるものは無理にやらなくてもOK。

*10:この方法ではリーディングにより20単語程度の暗記が必要。20単語程度となると、意味の理解と文章を組み立てる能力が必要。機械的な丸暗記では人間はせいぜい7±2程度の個数しか暗記できず、20単語の暗記となると、『意味の理解』と『使われた単語群の大雑把なうろ覚え』と『文章作成能力』を駆使する必要がある。『意味』と『うろ覚えの単語群』を元に『文章作成能力』により元の文章を再構成するため、元の文章と意味は同じだが異なる文章になることがあり得る。

*11:日本語の場合の極端な例としては、笑っていいとも!という番組のコーナーで、鼻音だけで何て言っているかを当てるコーナーがあり、『んんんん、んんんん、んんんん、んんん、んんんん』で、『タモさん、タモさん、僕にも、メロン、ください』と通じたというようなものがある。

*12:和訳が存在しない英文を聞いて厳密に意味を精査する必要があるので、ニュースレベルの英文法力は必須。単語については辞書を引けばいいので特に問わない。

validation と sanitization

ふと思ったのでメモ。

validation/sanitization 済みであることを示す interface が結構便利。*1

1か所でも validation/sanitization を行う個所があるならオブジェクトとして扱う方向を考えたほうがいいかも。なぜなら validation/sanitization のロジックをカプセル化する場所になるので。

*1:基本的には validation/sanitization 対象が不変かつ対象のデータに閉じて判断可能な場合のみ可能だが、全てを静的に判断できない場合でも静的に判断可能なチェックのみ完了したこと(例えば住所文字列フォーマット準拠とか)を表す interface を用意するのは有用。