GUIアプリケーションアーキテクチャ総合!みたいなやつ書いてる

最近はずっとJSでGUIを書くっていうお仕事をやっていて、その中で様々な知見が溜まってきてます。

そのときにひしひしと感じたんだけど、世の中にはさまざまなアプリケーション・アーキテクチャの話が溢れかえっていて、結構混乱を産んでいるように思います。

MVVMだけ見ても、「MVVMで実装しています」って主張しているものがMVVMパターンと違うパターンで実装されていたり、「軽量MVVM」なんて言葉が生まれていたりという状況があって、これはだいぶ混乱が極まっているぞ、と感じる状況です。

また「最近はClean Architectureが熱いらしい!MVVMを捨ててやってみよう!」とか言う発言を目にしたりして、「Clean ArchitectureとMVVMは矛盾しないからMVVMを捨てる必要はないんだよ!」って思ったりもするわけです。

そういう混乱の中にあるひと(それは知見を貯めるまえの自分のことでもあります)のために、今自分がきちんと理解している範囲で、様々なアプリケーション・アーキテクチャと、それぞれの関係みたいなものがきちんと説明できたらいいな、と思って、サンプルアプリケーション付きのリポジトリを作りました。

github.com

サンプルアプリ自体はGithubPagesで動いています(再生ボタン押すと音が出るので注意)。

README.mdに解説が書いてあります。

このサンプルアプリのアーキテクチャを解説していく中で、Presentation Domain Separation と MVVM と Layered Architecture と Clean Architecture について、整理された概念を読者が獲得していくことを目指しています。

と、いいつつ、実はこのREADME.md、「執筆中」って部分があるんですけど、まあ、そうです、まだ執筆中なんですよね。

とはいえ、すでに結構な分量が書かれたので、一旦ここで「こういうの書いてるよ!よかったら読んでね!」ってアナウンスしておこうかな、と思った感じです。

読んでいただいて、よかったら「よかったよ!」って言ってもらえると、続きを書くモチベーションにもなるので、心優しいひとは読んでみて、よかったら「良かったよ!」って言ってください……。

また、技術的な誤りなどが含まれている場合はIssueなどでご指摘を歓迎いたします。よろしくおねがいします。

Vue.jsとvuex、Fluxについて

最近立て続けにそのあたりの話をする機会があったので。わたしの意見です。

vuexというかFluxに手を出すタイミング

  • Vue.jsを利用していて、相互に関連のある二つ以上の状態を扱う必要が出てきたら、それはもうすでに「十分に複雑な状態管理」である
    • たとえば、APIとの通信中はインジケータを出したいので「通信中かどうか」を管理し、通信が終わったらその結果を表示するために「通信結果」も管理したい、など。
  • 十分に複雑な状態管理に立ち向かうためには、自分でピュアなDomain側をきちんと作ってそこで状態管理するか、vuex利用するべきだと思う
  • vuexを触ってみたところ、非同期処理含めてかなり筋が良くてわかりやすくて見通しが良く、かなりお勧めできる

vuexで状態管理するか、自分でPDSのDomain側のアーキテクチャ設計からやるか

  • vuexに乗っかると、PDSで言うところのDomain側もvuexが示すレールに乗ることになる
  • 楽だしレールが明確というメリットがある
  • vuexに破壊的な変更が起こった時、PDSのDomain側も破壊的な変更に巻き込まれるというデメリットがある

わたしはフレームワークのアップデートでアプリ全部に手を入れるの嫌なのでプロダクションではvuex使ってない。

自分でDomain側の設計からやるとき今わたしがどうやってるか

  • 状態は全部PDSのDomain側に持つ
  • VMから叩かれる「窓口」は一本化しておき、そこで非同期通信の待ち合わせなどする。いわゆる「usecase」だとか「service」と呼ばれるやつ。
  • usecaseやserviceがデータモデルやドメインモデルやインフラストラクチャを操作する
  • データモデルやドメインモデルに起こった変更はObservableな機構を利用してPresentation側に通知する

このへんの話はYAPC::Kansaiで話したんだけど未だに発表再現ブログ書けてない。明日書けたら書く。

大人と物語ることと混沌について

ぼくは最近、大人になるというのは取りも直さず、自らを物語るということなんじゃないか、と思うことがある。

ぼくたちは、自己だとか内面だとかいったものが先にあって、そいつらがぼくたちの選択や人生を駆動している、とついつい思いがちだ。けど、自己だとか内面だとかなんてほんとうは存在しなくて、それは「物語られる」ことによって遡及的に見出させれるようなものなんじゃないかな、ってぼくは思うことがある。

ぼくたちの精神や自己というものは、なんとなく一本筋の通った物語として理解される形で総合されたものとして普段は認識されている。たとえばぼく自身について語るなら、「文学部で哲学を学んでいたんだけど、御多分に漏れず哲学で就職できるわけもなく、趣味で書いてたプログラムでひとまず仕事を始めてみたら、これが趣味でやってたときよりもずっと奥が深くておもしろくてどハマりした。コミュニティ活動とかしていく中で、技術雑誌の記事の執筆のお話をいただく機会に恵まれ、思わぬ形で商業誌に自分の文章が活字として載ることになり、文学部のころの自分とプログラマとしての自分がなんだか面白い形で統合されていまの自分がある」といったような。

けど、ぼくたちの生というのは、ほんとうはこんなふうに「物語られて」いいようなものではないとも思う。この物語には、たとえば昨日食べたドーナツの味だとか、キャンパスの喫煙所で1人で喫煙してたときに隣でタバコを吸ってる二人組がしていた興味深いフランス思想の議論だとか、B tree indexを初めて理解した時の深い驚きと先人への尊敬だとか、なんとなくダラダラ過ごしてしまった日の夕方に友人から飲みに行かないかと誘われてアパートの部屋を出たときに見た夕暮れの色の後ろめたさとか、息子が「おかたづけ」を「おたかづけ」と発音してしまうこととか、そんな全てがまるっきり排除されてしまっている。

ただまあ、これは当然のことで、そんなすべてを物語に全部盛り込んでしまったら、「なんの話なんだこれは。なにが言いたいんだ貴様は」ということになってしまう。ぼくたちは、「無駄」なことを刈り込み、編集、編纂することで、自分にも他人にも理解可能な自己像や内面を、物語として騙るのだろうと思う。

そうして、ようやくぼくたちは自己を理解可能な形に調整し、他人とコミュニケーションをとり、社会を形作って行くんだと思う。だから、大人になる、ってことはたぶん自己を物語ることから始まるという一面がある。そんなふうにぼくは思う。

それでも、整理されて理解されやすい、遡及的に見出された内面だとか自己なんかより、もっと無指向ででたらめで、筋の通った物語として理解できない、あるいはされないような混沌、物語るときにとりこぼされてしまうような混沌を、ぼくは捨ててしまいたくない。それは物語られず、整合性がなく、だから理解不能で、社会的には「要らん」もので、けど、とても美しい(いや、こうして「美しい」と語ってしまった瞬間にそれは「美しさ」という言葉によって刈り取られ、スポイルされてしまうのだけれど)ものだ。

ぼくは、そんな混沌に混沌のまま触れたいからこそ、音楽を聴き、漫画を読み、小説を読み、お酒を飲み、仕事に関係なく役にも立たないコードを書き、こうした雑文を書くのだろう。いつまでも大人になりきれない、「要らん」ものを捨てられない子供なんだけど、それでもいいかな、と思ってしまうのだった。

リソース指向と操作指向のURLに関する最近の思い

弊社のwebAPIはRESTを捨てて操作指向のURLにすることが多いんだけれど、ここのところwebAPIだと結構そういう判断するところが増えてるように感じる(個人の感想です)。

SoEとSoRという話があったけれど、webブラウザ上でもスマートフォン上でもリッチなユーザ体験がモノを言うようになり、SoEなサービスが増えてきていることと操作指向のURLが増えていることは実は無関係ではないのではないか。

というのも、SoRの場合その性質上リソースに対する意識が高まるのに対して、SoEの場合はどちらかと言うとユーザ体験みたいなところに意識が高まる。で、ユーザがサービスを捉えるときのメンタルモデルって、「リソースの操作」とあまり一致しなかったりすると思うんですよ。そうすると、どうしてもリソース指向のURLでやっていくのに無理が出てきて、「じゃあいっそユースケース指向というか操作指向のURLでAPI作ればええんやないの。HTTPステータスも全部200で返してjson body見てね。」みたいな。

というようなことを最近なんとなく考えていました。

参加してきたぜ #nds50

お世話になっている勉強会であるところの長岡 IT開発者 勉強会(NDS)が第50回を迎えるということで、参加してきました。

第50回勉強会(2016/12/10) - 長岡 IT開発者 勉強会(NDS)

わたしとNDS

今は東京で働いているわたしですが、ちょっと前までは新潟県フリーランスとして働いていました。

フリーになる前は東京で会社員をしていたのですが、その頃よく顔を出させていただいていたHachipji.pmが最高で、新潟でも開発者コミュニティをやりたいなあと思っていました。その時に書いた日記を漁ってみたら、なんと2011年!もう5年も前のことなんですね。

d.hatena.ne.jp

完全に本題から外れるのですが、この頃から @hayajo さんに目をつけていた自分すごいなって思う。

で、Niigata.pmの活動をしていくうちに、「NDSっていう開発者コミュニティがあるらしいよ」ってことを聞いて、Niigata.pmと合同の勉強会も開催させてもらったり、ずっとNDSにはお世話になっています。

東京に引っ越してきてからはなかなか忙しく、あまり顔を出せなかったのですが、今回は記念すべき第50回!いくしかない!と思って行ってきたわけです。

自分の発表

わたしは builderscon2016 の再演をさせていただきました。

詳しい内容は弊社のテックブログの方に書いたのでそちらを参照してください。

techblog.reraku.co.jp

聴衆として

印象に残った発表はFileAPIについての発表とGoで作るLinuxコンテナとLoRaの話ですね。

FileAPIについては今まであまりきちんと追えてなくて、おおまかなところが概観できて参考になりました。

Goで作るLinuxコンテナの発表は、本当に素晴らしかった!

コンテナ技術は様々な技術の組み合わせでできているということが非常によく分かるし、単なる外部コマンド実行するだけのプログラムがだんだんコンテナになっていく様は魔法のようでした。高度に発達した魔法の中身を説得力のあるコードで解説している……みたいな感じで本当によかった。Web+DBとかで特集組んでほしい。

LoRaという通信規格についてわたしは全然知らなかったのですが、あんなに小さいものであんなに遠くまで無免許で電波飛ばせるのやばいという感じで、なにか面白いことができそうという予感がばりばりしました。でも具体的には何も思いつかないな!となったの自分の発想力の貧しさが悲しい……

またNDS参加したいっす。

双剣問題について

双剣問題についてはyatteiki.fmを参照してください。

双剣問題に関しては言いたいことがふたつあって、ひとつは小菅さんも言ってたけど、「別に結婚とかしたからといって楽になったり落ち着いたりするわけじゃない、むしろその分剣を振り続けなきゃならない」ってことで、ひとりだったらサボっちゃうところも、だれかと一緒に生活をする、その生活をやっていき続けるためにはサボることができなくなり、むしろ双剣を握り続けるモチベーションになるということがひとつ。

もうひとつが、双剣を振り続けてると「それが当たり前の環境」になっていって、双剣を握り続けるということが特別なことではなくなるということ。というか、特別なことじゃなくならないと双剣は握り続けられない、ということ。

たとえば、カンファレンスで発表をするということ。じつは、初めてカンファレンスで発表する日、わたしは緊張とストレスでトイレで吐いていた。そんな感じで、持ち慣れていない剣を持つためには腕力と強い気持ちが必要になる。けれど、それを続けていくと、いつの間にか周りの友人も「カンファレンスって発表して情報交換することのほうが大事っていうかそれが普通だよね」みたいな感じのひとが増えたりして、「カンファレンスで発表することなんて別に特別なことではない」みたいになっていく。というかそうじゃないと続けられない。毎回トイレで吐いてたらしんじゃうよ!

あるいは、OSSへのコントリビューション。わたし自身はこのあたりはかなり弱いんだけど、OSSにコントリビューションを続けてる人たちって「OSSで一発当てるぞ!」みたいな感じではなくて、あたりまえのことみたいに淡々とコミットを続けているように見える。

そんな感じで、双剣問題を別の視点から見ると、「双剣を持ち続けることをあたりまえのことに変えられるかどうか」というところが結構大きなポイントなのではないかと思う。そして、これはわたしの基本哲学でもあるんだけど、人生9割運と縁なので、じつはそうなれるかどうかは9割運と縁で決まると思う。残りの1割のところに、強い気持ちが必要なのかなと思う。

やっていく気持ちはとても大切なものだし尊いものだけれど、気持ちが途切れたら終わってしまう、という状況はあまりに脆弱だ。だから、強い気持ちがあるうちに、その気持ちを使って、気持ちに頼らずやっていける状況を作る、というのが双剣問題に対する1つの解決策なのかな、というのが所感です。

RDBMSが強すぎる件

以前、「RDBMSを採用すると、無料で外部キー制約とかチェック制約とかトランザクションが付いてきてオトク!!!」という発言をしたことがあって、その考えは今もあまり変わっていない。

RDBMSは単なる便利な箱じゃなくて、データの整合性を守るための仕組みがたくさん備わっている。もちろん、これらの仕組みは「タダ」で使えるわけではなく、データモデリングを学んだり、データ構造を学んだりという「投資」の結果うまく使えるようになるものだけれど。

ところで問題(?)は、RDBMSは強すぎる、ということです。

たとえば、トランザクションの話。「本質的にはトランザクション整合性である必要がなく、遅延してあとから整合性が取れてればよいような処理(つまり、結果整合性でよいような処理)」というのは、意外と多い。

多くの開発の現場では、トランザクション整合性が必要とされるか結果整合性でよいのかについてあまり考えず、「トランザクションはっとけば整合性が保たれていいよね」という感じでトランザクションが使われていることが多いのではないか。極端なところでは、web appの全てのリクエストの開始時にトランザクションを開始して、レスポンスを返すときにトランザクションをcommit(あるいはabortする)というような「フレームワーク」をオレオレで作っていたりするのではないか。

しかしほんらい、並行性を考えたら、トランザクションのような排他性のある制御は、可能な限り細かい粒度にしておくべきだ。めちゃめちゃでかいメソッドがsyncronizedで囲まれてたらみなさん怒るでしょ。

そう考えると、RDMBSの提供してくれるトランザクションは「ほんらいは」トランザクション整合性が必要なところでのみ用いるべきなのではないか。結果整合性で良いようなところでは、ほんとうのトランザクション境界のみでトランザクション整合性だけを保ち、あとはリトライとかいろいろ頑張って結果整合性を保つほうが良いありかたなのではないか。そうすれば並行性も上がる。

とはいえ、わたしたちの現実はそんなに単純に技術的な正しさ(とは?)だけで決まるわけではない。チームメンバーのスキルだとか、ビジネス上どれだけ堅牢である必要があるかとか、あるいはどれだけソフトウェアの速度が求められるのか、どれくらいのスケーラビリティを求められるのか、そういった諸々の要素によって「このソフトウェアはどのように設計されるべきなのか」は決まる。

なので、結論としては、トランザクション整合性であるべきなのか結果整合性で良いのかちゃんと判断した上で、「今回はほんらいは結果整合性でいいところなんだけど、楽するためにRDBMSトランザクションに頼っちゃおっか」とか「いやーRDBMSトランザクションに頼るほうが楽なんだけど、かなりシビアに更新がかかりまくるところだから、RDBMSにはトランザクション整合性だけ保証してもらって、ほかのところはワーカーに任せて結果整合性を取ろう」とか、そういうことを判断できるようになっておく、というのがわれわれ(誰?)に求められているのではないでしょうか。

正しい意見