Runner in the High

技術のことをかくこころみ

10月のOneTapBUY

 先月書いていたOneTapBUYに関する記事から少し評価額で変化が合ったのでちょろっとだけ記事にしようと思う

f:id:IzumiSy:20171026181216p:plain:w300

 前の段階では3000くらいの利益だったが、とうとう10000を切り始めた。投資額から見てこの伸び幅がすごいのかすごくないのかはわからないが、12万で1万の利益が出るような金融商品はあまり他にはなさそうなので、これはこれでいいパフォーマンスだと思う。とはいえ僕個人は株のプロフェッショナルでもなんでもないので、とりあえず「伸びがありそうな株」と「配当がそこそこでそうな株」の2軸だけに絞ってVISA, XEROX, INTELの3つに投資している。VISAは長期的に見て必ず上がり続ける株のようなので、配当は関係なくとりあえずだらだらと長期的な保有を考えている。

 とはいえ、おそらくOneTapBUYで選べる株式のほとんどどれもが、長期的に持っていればこれくらいのパフォーマンスをだすものなんではないかな、と思う。それは、OTB指数というもののパフォーマンスで分かる。

onetapbuy.hatenablog.com

 余談だが、つい最近クラウドバンクも始めた。いまのところ投資額はOneTapBUYと同じくらいだが、パフォーマンスで言うと年6〜7%といったところらしく、さほどリスキーではなさそうな利幅でよろしいと思う。こちらもどういう風にお金が増えるのか楽しみだ。

SAMパターンの大雑把な理解

 SAMパターンというのを勉強している。

www.infoq.com

 この記事は少しだけはてブでバズったが、実際コレを読んだだけでは例えば実際に実装に落としたときにどういうデータ・フローになるのか、というところまでは若干理解しづらい。この記事の作者のDubrayはsam.js.orgでいろんなサンプルコードを紹介しているので、それらを参照すると若干理解が捗る。

 ちなみに今のところ自分の中で整理しきれた雑なSAMのデータ・フローはこれ。

f:id:IzumiSy:20171014171004j:plain

 パッと見の雰囲気はFluxアーキテクチャと全く違う、という感じではない。SAMはState-Action-Modelのアクロニムで、ベースになるのもその3つの要素だ。それぞれの要素の名前はこれまでのアーキテクチャを知っている人からすると、比較的馴染みやすいものではあるかと思うが、SAMの場合はそれぞれが担う責務が若干異なる。なので、たとえばStateと聞いたときにそれが何を意味するのかというのは、既存のアーキテクチャの考え方からではなく、SAM独自の考え方から理解するのがよい。

 ということで、SAMにおける主要な3つの要素に焦点をあてて、sam.js.orgでの解説を元に、簡単な責務の説明をしてみたいと思う。

Model

 SAMにおけるModelとは、Actionから受け取った計算結果を保持し、それをビューに反映させるトリガを提供するだけの存在だ。すなわち、ここにはドメインロジックなどは一切入り込まない。

The model contains all the application state and (logically) exposes a single method: present(data)

 上のデータ・フロー図ではModelの中にPresentという関数がいるが、これがModelの唯一持つ関数としての責務だ。Presentが行う大きな責務は、フロントエンド・アプリケーションで言うところのレンダリング処理のトリガだ。現在の状態を元に、ビューに状態を反映させるトリガをキックする。また、そこで使われる「現在の状態」は全てModelが持っている。

The model is also solely responsible for the persistence of the application state.

 加えて、この説明が示すように、Modelはデータの保持の責務(Fluxで言うところのストア)も持っている。SAMは単なるアーキテクチャのため「メモリに載せる」「localStorageを使う」などの、どう永続化するかという「方法」の点では一切の言及がない。この責務をどう実装するかという点は自由だ。

Action

 SAMにおけるアクションは、データを受け取り、そのデータをもとに実行したビジネスロジックの結果をModelへPresentを介して送りこむ関数だ。Actionのトリガはビューと、後述するNAPによって行われる。

Actions are responsible for implementing context specific logic.

 SAMパターンにおいて、Actionとはドメインモデルに対する操作を行う場所だが、実際にここをどう実装するかに対する方針はSAMでは言及されていない。再利用可能なドメインモデルに具体的な操作は委譲し、ここではそれらのビジネスルールを用いて得られる結果のみをモデルに対して送るというのがおそらく良いかと思われる。

In the context of SAM, actions play another important role with respect to invoking 3rd party APIs.

 加えて、ActionはAPIコールなどを行う場所でもある。

State

the State does not hold any “state”, it is a pure function which computes the view and the next-action predicate, both from the model property values.

 SAMにおけるStateはFluxアーキテクチャのそれとは異なる。Reduxを使っている人なら、Stateと聞くとストアの中にあるデータ構造のことをイメージするかもしれないが、SAMの場合にはStateの具体的な責務は、Modelが保持しているデータ構造と、ビューで必要とされるデータ構造間のインピーダンス・ミスマッチの解消に近い。StateはModelから受け取ったデータを元にビューで必要となるデータに変換を行う関数でしかない。

the State is responsible for invoking the next-action predicate (nap)

 NAPはNext-Action-Predicateのアクロニムで、Stateが持つもう一つの責務を指すもの。これは、見方を変えればStateの副作用だ。NAPは現在のModelの状態から、次にトリガされる必要のあるActionを呼び出す。sam.js.orgのStateセクションでは、ロケット発射台のプログラムが例になっている。ロケットのカウントダウン・カウンタを減算していくActionがあり、そのアクションによってカウンタが0になったとき、Modelの状態を見て自動的にロケット発射のActionをトリガする。

 NAPの利点は、ビューを単なるStateの写像にするために、特定条件下でトリガされるアクションの条件分岐という責務をビューから取り払うことができるという点だ。Fluxアーキテクチャにおいて、Actionの発火元は常にビューだったため、例えばswitch文で記述される状態に関連したアクションの発火(たとえば状態を見てナビゲーターによって遷移を起こさせるなどのロジック)をビューに記述していく必要があった。これは場合によってはビューの肥大化につながることもあるが、SAMはNAPによってビューからそのような責務を分離している。

まとめ

 SAMパターンが最も意図しているところは簡単で、ビューがアプリケーション全体に影響を及ぼすことがないようにしよう! というだけのことだ。そのために様々なMVCやらMVVMやらが考案されてきたが、SAMはより関数型のアプローチをしようとしているアーキテクチャだということが分かる。ほとんど日本語の資料がないので、少しづつSAMの公式ページを読んでいくしか今のところ学ぶ手段はないが、それでも充分読んで見る価値がある。

 また、大事なことはSAMというフレームワークやライブラリがある、ということではないということだ。つまり、SAMというアーキテクチャに関して、どう実装するかは十人十色だ。実装にReactを使うのか、それともChooかVanillaJSか、という点はSAMにおいてはまったく重要ではない。大事なのはアーキテクチャとしての考え方だ。

 とはいえ、InfoQで掲載された記事についているぶコメは、記事を読んでそうに見えて、いくつかはあんまり関係のないものがあった。「サンプルコードでXSSできるから微妙なのでRedux使っとこう」「ナマのJSで良いという主張だということが分かった」「htmlを文字列連結で書くなんて」というあたりのコメントだが、これはおそらくアーキテクチャ自体ではなく、それを実現するために使う言語やツール、すなわち「手段」に関して興味が寄りすぎている。

 手段それ自体への興味はとても良いが、あまりにそこへ指向の比重が寄りすぎてしまうと、どうしても手段が設計に影響を及ぼしかねない。アプリケーションを作るにあたって、手段がなにかを規定してしまうのは大抵の場合よくない。技術をやっていると、どうしてもそこが面白くなってしまうことが多いが、一歩身を引いて設計という観点からものを見直すというのは、いつでも重要なのではないかと思う。

Yeomanに代わるNode.jsのスキャフォルディングツール4選

 ハッカソンや個人開発でよく使う自分でこしらえたアプリケーションのスケルトン・コードをGithubに置いて、それを気軽にスキャフォルディングしたい。こんな欲求はだれしもあると思う。スキャフォルディング・ツールの王道といえばYeomanだが、ちょっとYeomanは...という人は少なくない。ということで、今回の記事では、Yeomanの代替になるような、Node.js製のスキャフォルディング・ツールを紹介しよう。

khaos

f:id:IzumiSy:20171012230404p:plain:w500

GitHub - segmentio/khaos: A super-simple way to scaffold new projects.

  • segment.ioが作っていたシンプルなGithubレポジトリベースのスキャフォルディングツール
  • 機能が小さく纏まっており、マスタッシュ記法をサポートするスキャフォルディングができる
  • テンプレート中のマスタッシュから、CLIが勝手に入力項目を指示してくれるので、設定ファイルなどが不要。
  • ほぼメンテされてないっぽいのが気になる

slush

f:id:IzumiSy:20171012230712p:plain:w150

GitHub - slushjs/slush: The streaming scaffolding system - Gulp as a replacement for Yeoman

  • gulpを内部で使っているYeomanの代替を目指した大型スキャフォルディングツール
  • http://slushjs.github.io/generatorsに使えるテンプレートがリスティングされている
  • テンプレートになるslush-xxxというnpmをグローバルにインストールしないといけないのがちょっとイヤ
  • プロジェクト生成時に新しいディレクトリを作ってくれないという罠がある(これはいいのか?)
  • 使い勝手は(おそらく)Yeomanと近い。

pollinate

f:id:IzumiSy:20171012231207p:plain:w400

GitHub - howardroark/pollinate: Template your base files and generate new projects from Git(Hub).

  • この中でもわりとイチオシのGithubレポジトリベースのスキャフォルディングツール
  • 機能的にはsegment.ioのkhaosと近いが、こちらのほうが高機能
  • template.jsonというファイルをテンプレートのレポジトリに配置することで、スキャフォルディング時に無視するファイルや、ファイルのリネームなどができる
  • シンプルながら、汎用性が高くてよい◎

degit

GitHub - Rich-Harris/degit: Straightforward project scaffolding

  • マスタッシュ記法によるテンプレート化などを一切サポートしないGithubベースのスキャフォルディングツール
  • クローンせず、ただレポジトリをダウンロードするだけなので非常に高速
  • 作者「git clone --depth 1でもいいけど.gitディレクトリがついてきたりするから、こっちのが良いぜ」
  • テンプレート化とかとにかく考えないでリポジトリをスケルトンとしてつかうんや!みたいな用途には最適っぽい

(番外編) cooking

f:id:IzumiSy:20171012231647p:plain:w170

cooking - 更易上手的前端构建工具

  • 毛色が違うがslushのテンプレートを探していて見つけたので最後に紹介
  • webpackを使うフロントエンド・アプリケーションの開発に特化したスキャフォルディングツール
  • slushのテンプレートを検索していると、slush-cooking-xxxというのがでてくるが、それがcookingのテンプレート
  • cooking initを実行するとデフォルトでslush-cooking-vueが指定されたり、ナチュラルに中国語が出てきたりするので挙動がよくわからないときがあるが、そのあたりさえ割り切れればわりと使いやすそうな雰囲気がある

まとめ

  • おそらくこの中で使うならdegitとpollinate
  • 特にpollinateは機能面ですごく申し分ないし、それにロゴも緑のエコロジーな感じで○
  • プライベート・リポジトリ対応などは調べていないが、どのツールもあまり望めないと思われる

Reactの優位性は関数っぽいアプローチができるところなのではないかと思う

 何が言いたいのかというと、Vue.js, React, Angularなどここ最近のフロントエンド界隈を賑わせているフレームワークはたくさんあるけれども、その中でビューレイヤという責務に対して最も薄いアプローチをしているのがReactで、もっとも関数らしい副作用のないアプローチができるんではないかなと思ったということだ。僕自身、よっぽどPerformance-consiousなウェブ・アプリケーションを作るのでもない限り、フロントエンド・フレームワーク最強論議はすごくナンセンスだと思っていたけれどアーキテクチャの観点から考えるのであればフロントエンド・フレームワークの良し悪しが出てくるのは比較的意味のあるものではないかと感じる。

 僕はフロントエンド・アプリケーションにおけるビューをV=Component(State)のように考えている。この数式臭いものが表すのは、コンポーネントはステートを食ってビューを返すだけの純粋な関数だというところだ。アプリケーションにはFlux実装のようなビューレイヤ以外の責務*1が常に存在することを前提にしているが、よっぽどペライチのウェブサイトを作るでもない限り、とりわけSPAであればアプリケーションにおけるデータ管理の責務はもはやビューに置くには適さないと考えているからだ。

 つまり、ステートはすべてFluxアーキテクチャの上で管理し、コンポーネントはビューを作るだけに専念させたい。ビューとは純粋な関数だ。ステートを受け取り、HTML(JSX)を返す。このアプローチができる最近のナウいフレームワークはReactなのではないかと思う。たとえば、ReactではReact.SFCというのがTypeScriptで使える。うれしい。

interface Greeter {
  name: string;
}

const GreeterComponent: React.SFC<Greeter> = ({ name }) => {
  return (
    <div>Hello! {name}</div>
  )
}

React Stateless Functional Component with TypeScript

 このような関数っぽいアプローチを優れた点は、まず副作用が少なく安全だったり、テストしやすいということだ。そして、コンポーネントがステートを持つことができるというReact.Component継承クラスのコンポーネント定義をやめることで、常にステートはコンポーネントと別責務として考えることができる。「ここのコンポーネントのステートは他のコンポーネントで使っていないのでローカルにします」「いやいや...」みたいな議論をするのをやめて、ステートは常に決まった場所で管理しようという方針立てにつながる。つまり、コンポーネントはステート管理の場所ではなくなり、あくまで「ステートの写像*2でしかなくなる。

 「コンポーネント・ライフサイクル・ハンドラが無いんだけど、それが絡む処理はどう書けばええねん??」という話もでてくるだろう。けれど、コンポーネント・ライフサイクルに頼るべき処理が必要になるということは、おそらくコンポーネントのなかでステート管理をしようとしている可能性が高い。コンポーネント・ライフサイクルは見方を変えればコンポーネント内にあるローカル・ステートの変更検知だ。これはコンポーネントの中でステート管理をしているということと限りなく近い。純粋な関数としてDOMのレンダリングのみにフォーカスするコンポーネントはこうしたステート管理とは切り離して考える必要がある。

 さて、これをやるだけなら実際jsrenderyo-yoHandlbars.jsとかでええやんけ、という話もありそうだが、確かによいと思う。ただ、パフォーマンスの観点ではきっとReactのが優れているような気がしなくもない。そういう意味で、Reactに優位性があるのではないかと思う。

*1:Fluxのデータフローの責務が、果たしてビューにあるかないかはここでは話さない

*2:http://mizchi.hatenablog.com/entry/2017/10/02/074916

Unihertz Jelly Pro が届いた

 IndieGoGoでBackしていたJelly Proというめちゃくちゃ小さいスマホがとうとう届いた。

f:id:IzumiSy:20171001234830j:plain:w400

 つい最近GPD Pocketが届いたばかりな気がするのに、また性懲りもなくこういうガジェットを買ってしまったわけだけれど、これもまたほんとに買って正解なシロモノだった。そもそもスマートフォンが小さくて困るのは、キーボードの打ちにくさだと思う。ディスプレイが小さければ小さくなるほど、キーボードの割合も小さくなるからだ。けれど、実物を触ってみるとそんな心配はほとんど杞憂だったなと思わせた。

 Jellyがクラウドファンディングで募集される前にも、ElephoneQという小さいスマホがあったのだが(僕は持ってない)、それは画面のサイズが小さすぎるが故に、キーボードを出すと画面のほぼ半分以上を埋め尽くしてしまうというレベルの小ささのようだった。その記事を見て「Jellyもこんなだとイヤだな。とりあえず音楽プレーヤー的に使うか。」という風に一旦心を落ち着けていた。もちろん音楽プレーヤーとして使えれば充分御の字だし、小さければ邪魔にもならないと踏んでいたということもある。

 だが、実際に届いてみると、そのモノ自体の可愛さもさることながら、実際に実用にも充分耐えるのではないか、と思わせんばかりの使い心地で驚いた。僕自身は目が割と良いほうなので、ディスプレイの文字サイズを最小にして使っているというのもあるが、それにしても全然Twitterやらその他のアプリが普通に使えるのではないかと思う。キーボードも一見タッチしにくそうに見えるが、Sensitivityを調整するとまったく普通のスマホと遜色ない間隔で入力ができるようになる。

 まさに極小スマホ恐るべし。すごい。

 僕は手が比較的小さく、それだけにJellyを握ったときの異常なまでのフィット感に驚く。いま現役で使っている7インチディスプレイのSO-04Fでも、片手ではときおり操作しきれないことがあるが、Jellyにそんな心配をする必要はない。いつでもどこでも片手でらくらく何でも操作ができる。Playストアもわりといい感じで表示される。

f:id:IzumiSy:20171001235056j:plain:w400

バッテリの持ち

 スマートフォンを選ぶにつけ、必ず気にする項目がある。それはバッテリの持ち。単純に考えて、小さいスマホほどバッテリの持ちが悪い。Jellyもまた、バッテリ容量が950mAHと、さほど多いわけではない。というわけで、とりあえずどんなもんかとチェックする意味も込めて、100%充電から2日間ほど、どれくらい充電が持つのかを確かめることにした。この間はWifiオンで、たまにGPSを使う程度。Bluetoothは使っていない。

 結果から言うと、僕の端末の使い方やインストールしているアプリが関係しているということもあるのだろうが、フル充電で2日間程度は持つということが分かった。下は2日目の夜頃に撮ったスクリーンショット

f:id:IzumiSy:20171001235435p:plain:w300

 他のレビュー記事や2ちゃんねるのスレなどを見ると、あまりバッテリの持ちがよくないというようなことを書かれていたので、あまり期待はしていなかったが、おもったよりも持つな、という印象。僕の今使っている端末が1日使うとほぼ20%くらいというレベルの摩耗っぷりだが、僕の使い方では1日持てばもう充分。それに、IndieGoGoでVoltermanもBackしているので、それが届けばいつでもモバイル・バッテリを持ち歩けるということになる。Jellyは今の端末を完全に置き換えることのできるポテンシャルがあるのかもしれない。

入門ROM.rb 第1回: イントロダクション

f:id:IzumiSy:20170924181906p:plain

 RubyといえばRailsRailsといえばActiveRecordというくらいに、事実上ActiveRecordRuby界隈におけるORマッパのデファクトスタンダードだ。しかしながら、Piotr Solnicaというソフトウェア・エンジニアは、ActiveRecordパターンが常にスケーラブルなアプリケーションにとっての最適解ではないという思想から、ROM.rbというRubyアプリケーションにおけるレイヤ分割を強力にサポートするためのORマッパー*1を開発している。

ROM.rbの何がよいのか?

 長期間にわたってRailsアプリケーションの中でActiveRecordを使ってきた経験があれば、ActiveRecordにおいてモデルの中にロジックがてんこもりになり、コードベースが肥大化してきてしまうのに悩んだ経験があるのではないかと思う。ActiveRecordには、データベースの構造とドメインモデルの構造を密結合なものにすることによって開発者がアプリケーション/データベース間におけるデータ構造のインピーダンス・ミスマッチを意識する必要がなくなるという強力な利点がある。しかしながら、同パターンにおいて、モデルはドメインモデルとデータアクセスの責務を同時に担っており、モデルの中にデータベースの操作に関するロジックと、アプリケーション固有のドメインに関するロジックが入り混じってしまいがちだ。こうした困りごとに関して、Rails界隈では様々なリファクタリング・パターンが考案され、駆使されてきた。たとえば、GitLabやMastodonなどはActiveRecordとそれに関する責務分割のテクニックを駆使して、巨大だがメンテナブルなアプリケーションをRailsで構築してきた、いい例ではないかと思う。

 一方で、ROM.rbはこうしたARにまつわる問題点を考慮し、データマッパーパターン*2でアプリケーションを開発するために作られた永続化周りのモジュールになっている。ROM.rbを使うことによって、アプリケーションにおけるモデルを、データアクセスの責務を持たない純粋なドメイン・モデルないしアプリケーション・モデルとして扱い、データの永続化に関する処理をレポジトリレイヤに抽象化しながら、実装をアダプタレイヤに任せることによって、強力かつ明確な責務の分離をすることができる。

ROM.rbの思想

 ROMの思想を理解するにあたっては、いわゆるレイヤード・アーキテクチャと呼ばれる、アプリケーションをいくつかのレイヤに責務分割することで変化に強いアプリケーションを作る手法に言及する価値がある。

レイヤード・アーキテクチャ

 たとえば、下はボブおじさん(Robert C Martin)と呼ばれるアプリケーション設計界隈(?)の有名人によって考案されたクリーン・アーキテクチャの図だ。

f:id:IzumiSy:20170924185339p:plain:w500

クリーンアーキテクチャ(The Clean Architecture翻訳) | blog.tai2.net

 この図は、アプリケーションがいくつもの階層(レイヤ)によって分割されて作られているということを示している。アプリケーションをこのようなレイヤに分割する大きな利点は、アプリケーションに対する変化を柔軟にするということだ。開発者がアプリケーションを作るとき、そのアプリケーションには、ほぼ必ず固有の処理がある。固有の処理は、一般にビジネス・ロジック(ドメイン・ロジック)と呼ばれ、最もアプリケーションの中で重要なものとして扱われる。一方で、開発者である私達がアプリケーションを開発する際に使われる言語、フレームワークミドルウェア、インフラストラクチャなどは、一般的にはビジネス自体とは強い関連を持たない。なぜなら、それらの事象はビジネスをアプリケーションで表現するためのツールでしかないからだ。

 単なるツールであるものたちがアプリケーションのコアであるビジネス・ロジックと密接に関連してしまうと、アプリケーションは柔軟性を失うことになる。たとえば、PostgreSQLを使っていたアプリケーションが、のちにパフォーマンス改善のために新たなBetterSQLと呼ばれるミドルウェアを使うことになったとする。もしも、そうなった際に、アプリケーションのビジネス・ロジックがPostgreSQLに強く依存した設計になっていれば、アプリケーション全体の設計を見なおさなければならない。これが大規模なアプリケーションになればなるほど、この移行作業はキツイものになる。アプリケーションの設計とスケーラビリティの関係はこうした依存をいかに減らしていくかというところに関わる。アプリケーションのレイヤ分割の意義とは、できるだけ粗結合なレイヤをアプリケーションの中に仕切りのように設けることで、来たる未来に備えるということだ。

永続化レイヤのプラガビリティ

 さて、永続化レイヤのモジュールであるROMが主要な関心事とするのは、上で触れた図における青(External Interface)と緑(Gateway)のあたりだ。ROMは、永続化レイヤをアプリケーションのためだけのものとして扱わない。例えば、RedisやMemcacheのようなオンメモリ・データベースだったり、サードパーティのWebAPIもまた、データベースと同等な永続化レイヤの一部として扱うことができる。これを実現しているのは、ROMがアプリケーションから外部への入出力をリポジトリと呼ばれる責務でカプセル化し、具体的な実装をリポジトリに差し込まれたアダプタに任せるからだ。開発者はROMのアダプタを使ったり、必要な場合には自分で作ることで、アプリケーションとそれに対する外部入出力を永続化レイヤの責務としてとりまとめることができる。このようなアダプタによるプラガビリティの利点は、アプリケーション自体がその外側の具体的な実装を気にしなくて良くなるという点にある。

 より具体的にROMの思想を知るには、ヘキサゴナル・アーキテクチャの図を見るのが良い。

f:id:IzumiSy:20170924203016g:plain

ヘキサゴナルアーキテクチャ(Hexagonal architecture翻訳) | blog.tai2.net

 簡単に言うと、ヘキサゴナル・アーキテクチャは、アプリケーションとその外部の間にアダプタをおくことによって、アプリケーションを粗結合にするというものだ。たとえば、それまでアプリケーションでStripeを使っていたが、とある事情でそれをPayJPに乗り換える必要が出てきたとする。この場合、アプリケーションの中で決済処理を行う箇所の具体的なAPIの操作がアダプタによって綿密にラップされていれば、アダプタをStripeのものからPayJPに差し替えるだけでよくなる。とりわけ、サードパーティAPIなどに依存しているアプリケーションであれば、WebPayのサービス終了などの事例を顧みるに、アプリケーションを出来る限り外の世界と粗結合にしておくことにこしたことはないだろう。

FP + OO

 これ以外にも、ROM.rbは関数型プログラミングとしてのアプローチや、オブジェクト指向性を強く意識しているらしいが、さほど今回のイントロダクションでは重要ではないのでここでサラッと触れる程度に留める。

さあ使ってみよう!

 残念ながら書くのにとても疲れたので、ROM.rbの具体的な使い方については、次の記事にしようと思う*3。自分で試しにアプリケーションを書いてみても良いが、ネット上にはROM.rbに関する記事が恐ろしく少ない。公式のドキュメントもはっきり言ってとても少ない。だが、英語の記事はググるとわりとでてくるので、それらを試しに読んでみると良いだろう。

 また、ROM.rbの作者はオーストラリアにあるicelabと呼ばれる企業のエンジニアだが、現地で開催されたRubyConfAU 2017でのROM.rbに関する講演がこのモジュールの思想や具体的な使い方を知る手助けになるだろう。このためだけに英語をしっかりと学ぶ価値さえあるのではないか、というくらいだ。

追記

第2回書きました izumisy-tech.hatenablog.com 第3回も書きました izumisy-tech.hatenablog.com

*1:厳密には、作者はROM.rbを単なるORマッパーではないと述べているが、この記事では一旦ORマッパーとして理解を統一する

*2:ActiveRecordのように永続化レイヤとモデルの構造を一致させず、間にマッピング・オブジェクトを挟むことで責務の分離を行うパターン(http://bliki-ja.github.io/pofeaa/DataMapper/

*3:「イントロダクション」などと記事の名前をつけた手前、詳しくROM.rbの使い方を解説していく予定ではあるが、いつになるかは分からない

OneTapBUYというのをやっている

 つい最近OneTapBUYのCMをテレビで観たので、ふと思い出したので書く。

f:id:IzumiSy:20170919100836p:plain:w300
つい最近のホーム画面

 今年(2017年)の5月くらいから始めて、ここまででだいたい10万くらい投資にまわした。画像の投資元本がぴったり10万じゃないのは、OneTapBUYの中に「利益分だけ売却」という機能があってそれを試したりしたから。

 僕自身がただの一般家庭出身の中堅大学文学部の学生でしかないので、ほとんどまわりに投資信託株式投資をしてます! という知り合いがいなかった。これがもっとリテラシや情報感度の高いコミュニティだとそういう人がいるんだろうな、とは思うものの、僕の周りには音楽をやってる奴かプログラミングをしている奴しかいないので、「お金」という観点では自分で勉強していくしかないなと思う。

 家が金持ちだとか、バイトで月30万くらい稼げる! みたいな人間であれば、もっと大きいお金を運用して経験を積めるのではないかと思うけれど、ただの大学生だと頑張って月2万くらいが積立の限界じゃないかなと思う。そういう意味では、もともとお金を持っている人間は、それだけプールの中から遊ばせられる割合が多く、結果的に金融リテラシが身につくのかもしれない(?)。一億持っていれば、そこから数百万運用するくらいなら、なんでもないはずだ。一方で、僕にとっての10万円は本当に大きなお金で、もしもそれを明日すべて失うのかもしれないと思うと、それはそれで損をした気持ちになるし、怖いなと思う。でも何かを怖いと思って挑戦をしないよりかは、損をしても「ああこういうものなんだな」と思うほうが僕には価値があると思った。ただ、見方によっては損をしたことからバイアスのある見方しかできなくなってしまうこともあるし、そこはできるだけフラットな見方のできる経験をしていきたい。

 ところで、そもそもOneTapBUYを始めたきっかけは、リンダ・グラットンの「LIFE SHIFT」を読んだからだ。著者が本の中で、これからの未来は金融リテラシの有無が貧富の差を大きく分けると言っていて、それがなぜかという詳しい理由は忘れたものの、ああたしかになとすごく納得してしまった。加えて、卒業論文に関する調べものをしていて、日本は若者があまり金融投資に関して積極的ではないというデータを見て、それがなぜなのか個人的にすごく気になったのだ。金融投資と一口に言われて僕自身が思い浮かべる率直なアイデアはFX破産や借金取り、元本棄損のような「怖い」ワードばかりだった。それは、ネットの影響やバイト先の先輩がFXでウン百万単位の借金を背負ったという話を聞いてきたからではないかと思う。これは僕だけではなく、僕の周囲の人間も軒並みそうなのではないかと思う。大学の知り合いに「OneTapBUYというのをやっているんだ」というはなしをすると、「なにそれ、なんか怪しくない?」「なんかマトモじゃなさそう」というようなことを口々に言った。僕自身も、たしかになんか胡散臭い名前のアプリではあるなと思う。普通に考えて株式投資なんてものがワンタップでやれていいはずはない。世間一般の若者からすれば、株というのはもっと難しくて、危ないものだからだ。そんなものには積極的にならない。

LIFE SHIFT(ライフ・シフト)

LIFE SHIFT(ライフ・シフト)

 OneTapBUYに関してググってみると、銘柄数が少ない、手数料が高い、などのデメリットを書き連ねているブログ記事がいくつも散見される。おそらく、そのような記事を書いている人たちの殆どが株で「儲けたい」「大勝したい」という気持ちをモチベーションにして金融投資をしているのだと思う。たしかにその観点は間違ってないし、僕も大金持ちになりたいという気持ちはある。とはいえ、それでもいきなり初めての人間がいくつもある証券会社を選び、そしてさらにそこから星の数ほどもある株式銘柄を選ぶというのはとても大変だ。誰でも、なにか初めてのことをするときその対象が複雑すぎると、どうしても足踏みしてしまうものだ。そういう意味でも、OneTapBUYは僕のような金融リテラシの低い若者の、最初のハードルをさげようとしている。UI/UXとして株取引というもののコアとなるエッセンスである「安く買って高く売る」という体験をいかに低いハードルで提供できるかというものが考えられていると思う。

 ちなみに、僕はあまりOneTapBUY自体は胡散臭いと思っていない。なぜならTechCrunchのスタートアップ・バトル2015で賞を受賞しているし、スタートアップとして比較的安心のできるベンチャーキャピタルから出資を受けているからだ。これが確実にお金を預ける先として安心かどうかという点に関しては人によって賛否両論あるかもしれないが、僕自身はさほど危惧していない。

f:id:IzumiSy:20170919112214p:plain:w300
はじめてちょっと利益が出始めたとき

validatable-recordについて

www.npmjs.com

 validatable-recordというモジュールをすこし前に作った。Twitterでは軽く流したが、実際にはこれを作ろうと思ったモチベーションが少なからずあったので、自分自身の学びやのちのちの振り返りのためにも、そのモチベーションについてここに書き残しておきたい。

背景

 このモジュールを作っていたとき、僕はチームでVue.jsを用いたSPAの開発をしていて、アプリケーション・フォームのバリデーション・ロジックの実装にとりかかろうとしていた。Vue.jsのバリデーション・モジュールの有名なものにはvue-validatorというものがあるらしく、検索すると上位にヒットし、スターも多い。

 作者もVue.js界隈ではよく知られているkazuponさんである。このモジュールのいいところは、モジュール自体の出来もさることながら、バリデーション・ロジックの実装自体を全てビューレイヤで完結させることができ、とてもシンプルに使いやすいところだ。Vue.jsというフレームワークの持つ小さなラーニング・コスト同様に、このモジュールもとても手に馴染みやすい。しかしながら、アプリケーションのアーキテクチャによっては、バリデーションという役割が、このモジュールによって果たされることがよくない場合もある。

バリデーション・ロジックという責務

 バリデーションをどこで行うか? という事柄には「常にこれ」という答えがない。ビューでバリデーションをすることもあるし、そうでない場合もある。Railsではビジネスロジックの一部としてモデルレイヤがバリデーションを扱う。このような「バリデーションがビジネスロジックの一部である」という観点はとても興味深い。というのは、例えばフォームのバリデーションには多くの場合ビジネスロジックが関わることが多いからだ。

 もちろん、インフラストラクチャ・レイヤの事情によって、ユーザ名を制限したり、文字数制限を課したりする場合もあり、こうしたバリデーションはどちらかと言えばインフラストラクチャ・レイヤの一部だ。だが、別の例としてECアプリケーションにおける特定の商品の注文数の制限などは、限りなくビジネスロジックに近い。なぜなら、これはこのアプリケーションのビジネス固有の事情によって生まれるバリデーションだからだ。

モデル・レイヤ

 アプリケーション開発において意識する必要があることは、そのアプリケーションがこれからもスケールする可能性があるということだ。個人で作っていたり、フレームワークの練習で作るアプリケーションはその限りではないが、一般的なアプリケーションは毎日のように変更が施され、複数人の開発者がコードに手を加える。とりわけ、フロントエンド・アプリケーションはビューに大きな変更が加わるケースが多く、その過程でコード内のロジックがビューやビューモデルに偏りがちになることが多い。

 レイヤード・アーキテクチャからフロントエンド・アプリケーションを考えると、ビュー/ビューモデルはプレゼンテーション・レイヤの一部であり、そこが多くを知っていることが良い方向に向かうケースは少ない。そのため、アプリケーションから、固有のビジネス・ルールを切り離したドメイン・レイヤがフロントエンド・アプリケーションにも存在しているというのはなんらおかしなことではないと言える。

 巷では、様々なエンジニアがFluxアーキテクチャにおいてドメイン・レイヤをどこに置くか、という話題について記事を書いているが、僕のケースでは、Immutable.jsのRecordを用いてストアの一部としてドメイン・レイヤを置いている(僕のアプリケーションは、React+Reduxの技術スタックではないが、以下のスライドの図は参考になる)。

f:id:IzumiSy:20170905193818p:plain
改善React道

 もし、ビュー・レイヤの中にバリデーション・ロジックを置くとしても、それはドメインに固有でないもののほうがよい。ドメインに固有のバリデーション・ロジックは必ずしもビュー・レイヤからの入力だけに使われるとは言い切れないからだ。APIサーバやデータベースなどのインフラストラクチャ・レイヤからのデータの取得もまた、アプリケーションにとっては「入力」となる。

 それらがビジネス・ルールに対して適切であるかをチェックするのはドメイン・レイヤにおけるバリデーションの責務だと言える。このような意味でも、フロントエンド・アプリケーションにおけるバリデーションはドメイン・レイヤに置かれるモデルの一部として扱われるのが適切であることが多い。

validatable-record

 Immutable.jsのRecordでモデルを定義する際には、最終的にはバリデーション・ロジックは自前で書かねばならない。npmで検索すれば、様々なバリデーション・モジュールがひっかかるので、そこから自前で作ることができる。しかしながら、validatable-recordを使えば、validate.jsのバリデーション定義を組み込んだイミュータブルなRecordを定義することができる。

const ManRecord = ValidatableRecord({
  name: null,
  age: null
}, {
  name: {
    presence: true
  },
  age: {
    presence: {
      message: "is invalid"
    }
  }
});

// Immtable.jsのRecordと同じように使える
const man = new Man({
  name: "Justine";
  age: 25
});
 
// もちろんRecordのメソッド群も使える
man.size        // 2
man.get('name') // "Justine"
man.get('age')  // 25

// バリデーション
man.validate() // == true

 設計の指針として、バリデーション・ロジックをどこに置くか、という点を考えておくことは、決して無駄骨になることはないし、息の長いアプリケーションを開発する際には、すこしでも時間をとって考えておきたい。validatable-recordはその中でドメイン・レイヤにおけるバリデーションを実装するとしたらこんな感じかな、という小さなアプローチを提案するものだった。僕らのところではこうしてるよ、こういうものを使ってるよ、などの話もいつかどこかの勉強会で聞けたらいいな、と思う。