isyumi_netブログ

isyumi_netがプログラミングのこととかを書くブログ

好きな技術書ランキング

好きな技術書ランキングを発表するのが流行ってるらしいので便乗します。

もともとは初心者の時に役に立った技術書とかいうトピックだった気がしますが、この際どうでもいいや。

ジョー・セルコ『プログラマのためのSQL

この本に書いてあるのはSQLの事ですが、しかしプログラミング全般に役立ちます。
僕がこの本で学んだのは、プログラムは処理ではなくて宣言だという事です。

まず、どのプログラム言語にもその言語を司っている設計思想があります。
だから、それに合わせたコードを書くべきです。
そして、言語にはセマンティクスが用意されています。
ただ漫然と動くコードを書くのではダメなのです。
その言語のセマンティクスを理解し、それを使って自分の意図をコードで表現することもプログラミングの大事な側面です。

ということをこの本が教えてくれました。

GoFオブジェクト指向における再利用のためのデザインパターン

一般的にデザパタ本と呼ばれている本です。

大体の言語にはinterfaceという機能がります。
これほど使い道がよくわからん機能もなかなかない気がします。

extendsはわかりやすいです。処理を共通化できるから。
それに比べてinterface単体では処理を共通化できず、一体お前は何がしたいのだと思います。

しかし、実際にはextendsを多用するとすぐにコードが汚れてしまいます。
反面intarfaceを(上手に)使ったコードの共通化はあまりコードが汚れないです(上手にやれば)。

初心者の方はぜひこのデザパタ本を写経するといいでしょう。

この本に書いてある内容は古く、現代では通用しないという事で多くの人の意見が一致しているようです。
僕もそう思います。
この本の内容は役に立ちません。

しかし、interfaceを何に使うのかを理解するうえで一番いい本だと思います。
どうしたらコードを汚さずに処理を共通化できるのか、ノックだと思ってやってみるといいと思います。

戸根勤『ネットワークはなぜつながるのか』

ネットワークスペシャリストが自信をもってお勧めできる、
最もわかりやすくネットワークの初歩を教えてくれる本です。
ソフトウェア開発をしていて、ネットワークについてほとんど知らないわけにはいかないと思います。
とはいえWeb系の開発者であればネットワークにめちゃくちゃ詳しい必要もないと思います。

その点この本は粒度が最適だと思います。
この本を読んで興味がわいたらもっと専門的な勉強をしてもいいし、
この本の内容だけでも実際に必要なことはばっちり身に付きます。

トム・デマルコ『デッドライン』

お仕事では、組織運営に対する洞察も重要です。

トム・デマルコさんは「ソフトウェア開発で起こる問題は大体人の問題だ」っていうんですね。

みんな自分たちはハイテクなことをしてるって思いあがってる。
でも本当にハイテクなことしてるのは最先端の発明・発見をしているごく一部の人だ。
それ以外のソフトウェア産業の人はみんな突き詰めれば人間関係ビジネスだ。

だそうです。
で、いかに人間の組織を使ってソフトウェアを作るかという事についてこの本が教えてくれます。

坂田アキラ『坂田アキラの 数列が面白いほどわかる本』

世間のイメージに反して、
プログラミングと数学って実はあんまり関係がないですよね。
Web系のプログラマーが数学を使う機会なんて普通はほぼないと思います。
数学力がない人でも全然問題なくやっていけるわけです。
ところが、数列だけはプログラミングとかかわりが深いので簡単にかじっておくといいかと思います。

ジョン・マコーミック『 世界でもっとも強力な9のアルゴリズム

今までの本の中で、一番知識によっている本です。
この本を読みながら何か練習したりしなくてもいい本です。
圧縮や暗号化についてざっくり知っておくと便利だと思います。

そもそも、この「好きな技術書ランキング」みたいなのが今ネットで流行ってるのって、
この業界には「なぜかみんな知ってるけど、それをどこで教わってるのかわからない」みたいな知識が膨大にあるからだと思います。

という意図を鑑みるとこの本が一番お勧めかもしれません。
「なぜかみんな知ってるけど、教わる機会がない話」集としてはよくできてると思います。

泉水翔吾、 佐藤歩『超速! Webページ速度改善ガイド 』

Web系の開発者ならば、平場でPageSpeed Insights90点くらいは出せるようになってほしいと思います。

この本を読むとページ速度を上げるうえでどこが大事かがわかります。
それがわかっていると、開発の早い段階から速度を上げやすい設計にできます。

それとは別に、ページ速度はわかりやすい点数が出る点がいいと思います。
プログラミングというものはどうしてもゴールがあいまいになりがちです。
その点、この本を参考に特定のページの速度を上げる経験を繰り返すことによって
プログラミングスキルが全体的に向上するものではないかと思います。

ただ、ちょっと内容が古いところもあります。
最新情報は別途追った方がいいと思います。
変化が速い領域なのです。

徳丸 浩『体系的に学ぶ 安全なWebアプリケーションの作り方』

いわゆる徳丸本です。

あまり「読むべき本」などと強い言葉は使いたくないですが、
これは唯一「読むべき本」だと思います。

XSSSQLインジェクションCSRFなどについてわかりやすく書かれています。

リーアンダー ケイニ―『ジョナサン・アイブ 偉大な製品を生み出すアップルの天才デザイナ』

デザインの本も挙げたいなと思いました。

『誰のためのデザイン』『インターフェースデザインの心理学』などの名著と迷いましたが、
最終的にこの本を選びました。

具体的な技術はいろんなところで身に着けるとして、
そもそもIT系の人がちゃんとデザインに興味を持つことが大事だと思いました。

デザイン次第で商品の評価がこれほど変わるのかという事と、
いいデザインにするという事を工程に完全に組み込まなければいけないという事の両方を学べます。

『工程の最後にデザイナーさんに仕上げをお願い』ではないのです。
『いいデザインのものを作るという事がゴールで、プログラミングはそのお手伝い』と考えなければいけないのです。

プログラミング中級者の伸び悩み

流石にもう僕はプログラミング初心者ではないと思う。多分中級者くらいだ。
これまで初心者向けの教材や切磋琢磨の場にたくさんお世話になってきた。ありがとう。

さて、それ以降の人って何をしたら伸びるんだろうね。

Twitterやブログを見ていると、自分より優秀そうな人はたくさん見つかる。
でも、自分とその人の間にどういう差があってどうすれば近づけるのか分からない。
僕はそんなことを5年位悩んでる。

まず、初心者を脱するとどうなるか。

初心者の頃は、とりあえずプログラミングが好きなら勝手に伸びる。
作りたいものを作りたいように作ってるだけでどんどん成長していく。
会社に入らないと身につかないスキルがあるという意見もある。コードを整理整頓する技術などだ。しかし、僕は幸いなことに生まれつき脳のワーキングメモリが極めて乏しかったため、ちょっとでもコードが散らかると頭が爆発するので、その手の技能も趣味開発で身につけることができた。
この段階であれば、自分の足りない知識が何かを自分で検知できる。開発をしていて困ることはたくさんあるからだ。
本屋さんに行けば自分に必要な本が必ず10冊くらい見つかる。
ところが、そのうちただコードを書いているだけでは全然成長しなくなってくる。
だいたいのものは一通り作れるようになってるからだ。
既に持っている知識と適宜のググりで困ることはほとんど無い。
もちろん本当は知らないことがいっぱいあるんだと思う。でも、苦手なことを無意識に回避する方法を覚えてしまっている。だから、自力で自分の苦手分野に気づくことができなくなってくる。

また、初心者のうちは新しい言語を覚えたりフレームワークを使ってみたりする度に成長していく。新しい世界観に出会えるからだ。
でも、徐々に新しい技術を身につける時の負荷が落ちてくる。

初心者を脱した僕が何をしたのか。
まず、本屋さんでいわゆる名著の類を読み始めた。プログラミング原論とか型システム入門とか。
頑張って読んだけど難しすぎて全然アレだった。
多分僕はまだこの次元には達してないようだ。

次に、資格を取り始めた。TOEICと数学検定とAtCoderIPA
ここ数年間は毎月100時間くらい勉強している。
AtCoderと数検は一応それなりに難関と言えるところまで到達した。

他にも、mozaic bootcampに参加させてもらった。
これは大変良かった。
ただ、365日誰かにこうやって教えてもらうわけにも行かなそうである。

何より、会社での仕事を一生懸命やってきた。

そんな僕は、なぜ伸び悩んでいると思うのか。
実は先日いわゆる転職活動というものをした。
その結果、あんまり自分の評価が高くないということを思い知った。
初心者を卒業してから何年間もずっと精進して生きてきた。だから当然それなりの評価があるものだろうと思っていた。ショックだった。

確かに、コーディングテストや知識を問う系のテストは上手く行った。
『○○なアプリを作りたいからどんなインフラにするか考えて』系も大丈夫だった。
でも、その次のステップでほぼ落ちた。

伸び悩みながらも頑張ってやってきたつもりだったが、実は全然伸びていなかったんだろうなと。
自分が技術力だと思っていたものとみんなが技術力だと思っているものは全然違うんだろうなと。
しかも、今僕は何が理由で落ちたのかよくわからないでいる。
これは困った。

今後僕はどうするか。
とにかく自分よりもっとレベルの高い人に色々教えてもらえるようにならないといけない。

二つ目標を決めた。自分よりレベルの高い人がたくさんいる会社で働くこと。もう一つはもっとコミュニティに関わる。

自分よりレベルの高い人がたくさんいる会社で働くというは、かなり難しい目標だ。だって、普通に考えて受からないからね。
これは煽りじゃないんだけど、その会社で一番技術力低い技術者って、どうやって会社に入ったんだろうね。
それってある意味一番難易度が高いハードルを突破した人ってことじゃん。
だれかレベルが高い会社の受かり方教えてください。

もう一つはコミュニティに関わるということ。
そうすれば色んな人が自分にいろんなことを教えてくれるようになると思う。
具体的にはこれをやろうと思っている。QiitaのQ&Aやteratailで質問に答える。みんなの技術ブログにちょっとコメントする(自分も試してみましたとか)。趣味でアプリを作ってる人がいたらちょっと使ってコメントをいう。
なぜそう思ったかというと、昨日中田敦彦Youtube大学でオンラインサロンについて見たからだ。
オンラインサロンには興味がないが、オンラインサロンの活用術でこんなことを言っていた。『一番興味を持たれるのは一番みんなに興味を持ってる人。一番発信力があるのは一番人の話を聞いている人。一番手助けされるのは一番手助けしてる人』
これは確かにと思った。だから、僕はこのIT界隈にもっと貢献しようと思う。

『あのアーティストの代表曲は』の技術詳解

 

こういうWebアプリを作った。
https://famous-song.app/

本人は企画として面白いと思っている。
せっかくなので、どういう技術で作られているかについて解説する。

概要

まず、認証とRPCは全てFirebaseを使っている。
サーバーサイドはFirebase HostingとCloud Functions。
フロントエンドはTypeScript/React/Redux/typescript-fsaあたりを使った。
投票ページはSPAで、それ以外の結果表示ページはSSRしている。

意図

SSR

最近はSSR不要論も多い気がする。
ただ、フロントエンドでSPAと合流するようなSSRならともかく、ペライチのHTMLを生成するだけならSSRしたほうがロードが速いし実装も楽だと思う(そこに反対する人はいないと思う)。
SSRにはReactのtsxを使った。
tsxを使うと、引数にTypeScriptの型をそのまま使えるので簡単である。

SSRのCache-Controlにはこれを指定した。
public, max-age=10, stale-while-revalidate=1000
キャッシュが古くてもとりあえずCDNのキャッシュを返し、その間にCDNからCloud Functionsにアクセスしてキャッシュを入れ替える。
こうした理由はコレだ

  • Cloud Functionsはそこそこ重い
  • リアルタイム性が超重要というわけではない
  • ユーザーも、おかしいなと思えばリロードするくらいのリテラシはあると思う

コマンド化

フロントエンドからRealtime Databaseの公開データを直接書き換えるのではなく、
フロントエンドからサーバーサイドにコマンドを送って、サーバーがそのコマンドを元に公開データを書き換える仕組みにした。
こうした理由は、この方がバリデーションやアクセス制御の点で楽だからだ。

この方式には1個欠点がある。
フロントエンドでサーバーの処理待ちがしづらいことだ。
RESTであれば、POSTを投げてからサーバーで処理が終るまでグルグルを出しておくということが簡単にできる。
しかし、Firebaseでコレをやってしまうとグルグルを消すタイミングがわからないという問題だ。
そこで、サーバーで処理が終わったこともRealtime Database経由でフロントエンドに通知することに指定ある。
その部分を抽象化してあるので、フロントエンドはasync/awaitで簡単に処理の待ち合わせができるようになっている。

フロントエンドでの正規化

それなりに大きいフロントエンドであれば、フロントエンドでも状態を正規化して持つべきだ。
正規化というのはRDB用語かもしれないが、要するに

  • 値段は三桁ごとのコンマを入れずに数値で持つ
  • Dateはタイムゾーンを統一しておく
  • 省略可能なものに関しては必ず省略する
  • RDBと同じように関係で表せるものは関係で表す

というよううなことだ。
タイムゾーンに関しては、YYYY-MM-DDの文字列で持つというのも結構優秀だ。
省略可能なものというのは、例えば誕生日・現在時刻・年齢や直角三角形の3辺など、二つが確定すれば残り一個も確定するようなものに関してはその1個を省略して持つほうが扱いやすい。
関係で表すとは、例えば、商品一覧とユーザー一覧と購買一覧があるなら、無理にオブジェクトで親子関係を作らずに配列を三つ持つということだ。

重要な点は、そのデータがどのように使われるかをあえて意識せず、データとしての完全性を最優先した型で持つことだ。
一見、そのデータがどのように使われるかに応じて型を決めたほうが後の処理を楽に作れる気がする。小さなアリケーションならこういう考え方もあると思う。
しかし、そういう考え方だと早晩コードが散らかってカオスになる。データの使い回しがしづらくなる。
やはり、データは極力完全な形で持つべきだ。

タブレイアウト

僕は、タブレイアウトって素晴らしいと思っている。
昔rebuild.fmでもそういうことを言っている人がいた。
2ch専ブラのJaneStyleやTabtterなど、人気のツールはだいたいタブレイアウトだ。
だから僕もタブレイアウトにした。
Webというものはクモの巣状にリンクが広がっていくモデルなので、ネイティブアプリと違って階層構造で画面遷移を表現しづらい。
それならば全てはタブであるという一般化をしたほうが認知しやすい。

アイキャッチの自動生成

Twitterなどにリンクを投稿する時のOGPのことだ。
実装の詳細はここに書いた。
https://qiita.com/isyumi_net/items/ee94a5e2d963958eb515
頑張ってレイアウトを計算すれば画像処理の延長で生成自動化は可能だが、
今使っている技術の延長で画像を生成できるということで、puppeteerを使った画像生成をした。特にBootstrapを使えるのでデザインが統一できて良い。

あのアーティストの代表曲は

 

序文

あのアーティストの代表曲は何だと思うかについてのアンケートサイトを作った。

https://famous-song.app/

きっかけ

たまたまいろんなアーティストのCD売り上げランキングを調べていた。
このランキングは、僕の主観におけるそのアーティストの代表曲と一致していない場合があり面白いと思った。

例えば、B’zで一番売れた歌は『愛のままにわがままに 僕は君だけを傷つけない』だが、B’zといえば『ultra soul』な気がする。

という話を会社でしてみた。
そこから、あのアーティストの代表曲といえば何だという話になった。
これが大変盛り上がった。

なので、アンケートサイトを作ってみた。

集計方法

とりあえず、CD売上ランキング上位30人を事前に入力しておいた。
その他のアーティストも入力できるようにしてある。
Twitterに放流してみたものの、あまり広まらなかったのでシュフティで50円くらい払ってアンケートに答えてもらった。

結果

B’zはもちろん『ultra soul』だった。
意外だったのはEvery Little Thingの代表曲にfragileを選んだ人が一番多かった。ここは絶対『Time goes by 』だと思ってたのに。
他にも色々おもしろい結果が出たから見てほしい。
https://famous-song.app/

思ったこと

まず、ちょっと古い。そもそもアーティストのCD売上ランキングというものを取ると、2000年前後のアーティストが大半を占める。
今の10代~20代前半の人にはピンとこないのではないか。
ここには二つの理由があると思う。
一つはCDという媒体の問題。
もう一つはポップカルチャーが細分化してしまったという問題。おそらく、未だにCDという媒体が続いていたとしても、アーティストのCD売上ランキングはほとんど変わらなかったと思う。

プログラミング初心者が一歩成長するために身に着けたいものを発見した。

結論

型が言えるようになろう。

概要

必要な知識はちゃんとあるはず。それでも、プログラミングが遅い。バグが多い。
そういう人を何人か見た。

その人たちに型が言えないという共通点があると思った。

まず、型が言えないとはどういう状態か説明し、解決策を提案する。

自己紹介

多分本当に速い人。

業務のプログラミングは速い。
AtCoderで容問を速解きするだけなら相当上位。

本題

型が言えないとはどういう状態か

例えば、極単純な電卓アプリの型を考えてほしい。
二つの数値に四則演算をして計算結果を画面に表示するとする。
この際、値域や未入力の状態やゼロ除算の対応やカーソル位置などは全部置いておこう。
この電卓の型を言うならこんな感じだろう。

{
  input1: number,
  input2: number,
  method: "+" | "-" | "*" | "/",
  output: number,
}

一応、オペランドだとかそいういう用語が存在するがそういうのも置いておこう。
とりあえずこれで十分なはずだ。

当たり前だと思った人はこちら側の人間だ。おめでとう。
どうも、大多数のプログラマーはこれができないらしい。
かなり適当な統計だが、どうも職業プログラマーの半分強の人はそうっぽい。

では、その人たちはどうしているか?
実装を書きながら必要に応じて型定義を書くしか無いのだ。

こういう人がプログラムを書くとどうなるか。

全体の流れを型で見通すということができないので、そこかしこにparseIntが氾濫する。
手戻りが多すぎて時間がかかる。
本来Aという処理とBという処理をどうつなげるか考えて型を書くから静的型付き言語は間違えにくいのに、Aという処理を書くことに集中している時に型を書き換えるから間違いが増える。
そこをどういう値が通過するかは言えるが、どういう値が通過することはないかを言えないので、極力狭い定義をしようとしない。

型が言える人とはどんな感じか。

自分の場合であれば、作るアプリにどういう機能があるかわかっていたら、こういうものはだいたい事前に全部列挙できる。

  • RDBの定義
  • RESTのエンドポイント
  • いろんなオブジェクトの型
  • 各クラスにどんなメソッドがあるか
  • URL設計
  • 何をDIしないといけないか

先に列挙しておいて型と型をつなぐように実装を書いている。
だからあんまり間違えないし、ほぼ何も考えなくても正しいコードになっている。

僕だけの特殊技能ということでもないようだ。できる人はみんなほぼ無意識にできるっぽい。

どうすればいいか

練習するしか無いんじゃないかと思う。
gitの練習サイトのようなものがあるから、似たような練習アプリを作ってあげたらいいんじゃないかな。

僕はプログラミングがとても速いのだ

 

概要

僕がいかにプログラミングが速いかについてAtCoderの成績を元に説明する。
どちらかといえば、AtCoderのことをよく知らない人向けに書いた。ところどころ厳密ではない書き方をしたが、わからない人を混乱させないための言い回しなので、詳しい方はご勘弁願いたい。
正直言って、自分でこんな記事を書くのはダサくて恥ずかしい。
でも、自分で言わないと誰もわかってくれないから書く。
なんでわかってもらう必要があるかと言うとオチンギンガ……

経緯

僕はAtCoderで水色である。
正直、水色というのは凡庸な成績だ。
なぜこのような成績になってしまうかと言うと、僕に難問を解く力がないからだ。
逆に、簡単な問題を速く正確に解くのは得意だ。
なので、AtCoderのレートではなく簡単な問題を解く速さと正確さをアピールしたかった。

前提

AtCoderの難易度について

AtCoder界隈では問題の難しさを色で区分する習慣がある。
これは、主観ではなく解答できた人のレーティングを元に算出した客観的な分類だ。
簡単な順に

  1. 灰色
  2. 茶色
  3. 緑色
  4. 水色
  5. 青色
  6. 黄色
  7. 橙色
  8. 赤色

である。
灰色が一番簡単である。
だいたいどのくらいのレベルかと言うと、灰色の中で一番難しいのがこのくらいの問題である。

X,Y,H,Mが与えられる。
時計の長針と短針の長さがそれぞれXcm,Ycmである。
H時M分の時、2つの針の先の距離は何cmか?

決して難問ではないが、そうそう即答できるわけでもないと思う。
AtCoder未経験者が想像する「一番簡単な問題」よりは難しいと思う。
諸説あるが、大体普通のお仕事でWebアプリケーションを開発する仕事の難度は高くて茶色前後だと思う。
ちなみに、僕はこの問題を10分で解いた。参加者の中央値は50分だ。
(それ以前の問題を解くのにかかった時間を引いた)

調査方法

AtCoder Beginner Contestの中で直近26回のコンテストを対象にする。
これは、これまで僕が出場した全てのAtCoder Beginner Contestだ。

問題は緑問題以下を対象とする。
これはざっくり言って、参加者の上位1/3が正解できる難易度の問題だ。

制限時間以内に正答できなかった人は制限時間である6000秒で正答できたとみなす。

集団の偏りについては、AtCoderの参加者は世間一般のプログラマーよりプログラミングが上手なのか下手なのかは色んな意見があるが、ここではだいたい一緒とみなして話をすすめる。
また、そもそも他の参加者は全力を尽くしているのかという問題があるが、そこは考えないようにする。
例えば、AtCoderのルールでは強豪ユーザーはAtCoder Beginner Contestでいい点を取るメリットは全くないが、彼らも一生懸命問題を解いていると想定する。

解答の速度と正確さを評価することにする。

速さ

解答の速さは

  • 自分が正答するのにかかった時間を他の参加者の中央値と比べる
  • 自分が正答するのにかかった時間が参加者の上位何%か調べる

正確さ

AtCoderでは、解答を提出するとその場で正誤がわかる。
誤答をするとスコアが下がるので、一般的に参加者は極力誤答を提出せずに正答を提出しようとする。
なので、正答するのに要した誤答の数が少ないほど正確なプログラミングが出来ると言える。

結果

解答の速度

問題を解いた時間をグラフにした。

f:id:isyumi-net:20200820174842p:plain

左に行くほど簡単な問題である。
茶色の真ん中あたりからオレンジのグラフが全て6000に張り付いている。そもそも半分の人は解けていないのでこういうグラフになっている。
これを見ると、大体中央値の1/3くらいの速度で正答できていることがわかる。

 

次に、これは解答速度が参加者の内上位何%だったかを表したグラフだ。

f:id:isyumi-net:20200820174901p:plain

大体、上位15%であることがわかる。
計算した所

  • 灰色問題までは平均13%
  • 緑色問題までは平均18%

であった。

解答の正確さ

僕が一度も間違えずに提出できたのは
100回中85回 で、成功率は85% であった。
これは48,990人中3,4662位で、上位7%である。
中央値は50%なので、1.7倍正確にプログラミングができると言える。

結論

簡単な問題(とはいえ、一般的な仕事の基準では十分難問)を解くことについて、僕はこのくらいのスキルだと言える。

  1. 僕のプログラミングの速度は、一般的なプログラマーの中で上位15%くらいである
  2. 僕のプログラミングの速度は、一般的なプログラマーの3倍くらいである
  3. 僕のプログラミングの正確さは、一般的なプログラマーの上位6%くらいである
  4. 僕のプログラミングの正確さは、一般的なプログラマーの1.7倍くらいである

僕が設計だと思うもの

設計について

自分はソフトウェアの設計を担当している。
ところで、会社によって設計という業務の指す範囲が異なると思う。
ただ『設計をしている』というだけでは、自分の持つスキルが伝えられないのではないかと考えた。
そこで、自分が実際にどのような作業をしているのか、そして、どのような考え方をもってその作業に当たっているのかを記そうと思う。
ここで言うソフトウェアの設計とはビジネスの設計やプロジェクトの設計の話ではない。よって、ビジネスモデルや人員配置というような話ではなく、狭い意味のソフトウェアの設計の話だと思ってほしい。

信念

  • 設計通りに作って動かなかったら設計した人が悪い
  • 設計に解釈の余地があったら設計した人が悪い

設計書と称して何を読み取ればいいのかよくわからないポンチ絵を作って満足している人が多いようだ。
しかも、えてしてそのような人は「上流工程」と呼ばれて、その人の仕事の不出来を下位団体に気軽に押し付けられるようだ。
それでは仕事をしたことにならないだろう。
「設計した」というのであれば、そのとおりに作ったら意図したとおりに完璧に動くべきだ。

具体的にやっていること

これを決めている。

  • RDBスキーマ
  • Redisの型
  • サーバーサイドプログラムのモデルの型
  • RESTの型
  • フロントエンドのモデルの型
  • フロントエンドのビューモデルの型
  • フロントエンドのURLと画面の対応
  • IndexedDBの型
  • その他各種DIしなければいけない副作用の型

Redisの型とは、RDBとRESTを見比べて、どんなキャッシュがあれば全てのRESTの処理を現実的な計算量に出来るか考えるということも含む。
RESTの型の中には、各エンドポイントの権限とCDNの設定を含む。
IndexedDBは、WebフロントエンドではなくAndroidアプリやiOSアプリの場合はSQLiteになる。
DIの型というのは、例えば乱数や現在時刻のことだ。

核心の技術

僕は、「ある対象を見ると、その型を正確に言うことが出来る」という特技がある。
例えばこのツイートの型を考える。

f:id:isyumi-net:20200815140256p:plain

まず、アイコンのURLが必要だ。

表示名(日本語の所)とユーザー名(アットマークで始まる所)はそれぞれstringだ。

日付は、「10秒前」「5分前」と言った表記になることがあるので、モデルではDate型だが、ビューモデルではstringである。

また、この日付をクリックするとそのツイートのURLに飛ぶので、TweetIDを整数型で持つ必要がある(言語によってはintに収まらないので注意)。

本文もモデルとビューモデルで異なる。モデルはstringでいい。ビューモデルは改行やハッシュタグやメンションに対応しないといけないので、「通常のテキスト」「ユーザーID」「ハッシュタグ」の代数的データ型の配列の配列が正解のようだ。

その下は画像だ。画像は複数枚上げられるのでimg型のリストである。img型には画像サイズと表示領域から計算したトリミングの情報などを入れておくと画面を作りやすい。

めんどくさくなってきたのでこのくらいにするが、他にもいいね数や引用ツイートや右上のプルダウンメニューの開閉なども型に落とし込んでいける。

僕は複雑なシステムでも短時間で間違えずにこれを全て書き出すことが出来る。
これが僕の核心になる技術だ。
実は結構簡単。

これはなんなのか

要するに、GoF本などで主張されてきた『インターフェースに対してプログラミングする』ということである。
これをシステム全体に適用するということだ。
一つの大きなシステムを各部品に分け、その接合部を事前に全て決めてしまうということだ。

なぜいいのか

こうすることで、各部品が粗結合になり、コードが綺麗になる。
複数人で同時に作業できるようになる。各作業員の仕事は、ある型からある型に変換する純粋関数を書くだけになり、考えることが減る。
何が正解で何が間違いかはっきりするので、テスト駆動開発ができる。
他人の指導もしやすい。

大工さんが家を建てているとしよう。
一人の大工さんが一階を組み立て、もう一人の大工さんが二階を組み立てている。
この時、もし一階の大工さんも二階の大工さんも、それぞれ一階と二階の図面を見ながら作業を進めれば頑丈な家が建つのが理想である。
逆に、一階の大工さんと二階の大工さんが密に設計を相談しながら仕事を進めないといけないなら、手間だし本当に頑丈な家が建ったのか怪しい。
だから、工務に入る前に誰かが設計を確定させておかなければならない。
ソフトウェアの設計も同じである。

何ではないか

例えば、これらは設計の範囲ではないと思う。

もしかしたら一般的にはこういうことの方が設計と呼ばれているかもしれない。
しかし、僕はこういうのは設計とは言わないと思う。
これらは、ベストプラクティスやその会社の慣習が確立していることなので、どちらかといえば設計と言うより日頃の行いの問題だと思う。
また、インターフェースを満たしている限りそこを自由にすげ替えられるということが重要なのであって、そこを決めるのが対して大事な仕事だと思えない。

想定される反論

それはウォーターフォールの考え方だ。我々はアジャイルなのだ

短いサイクルで機能変更を繰り返していくからといって、ある瞬間には実現したい機能要件というのが確定しているはずで、そうであれば設計は出来るはずである。
短いサイクルで設計を更新して、それに合わせて実装も更新すればいいのだ。
短いサイクルで変更されるからと言って設計が出来ないとか設計が不要というのはおかしい話だ。

設計が終わらないと開発できない

それでいいと思う。
熊とワルツをに書いてある。
僕は自分が設計している間、他の人が手空きになることを全く問題だと思っていない。

僕がいるとどうなるか

  • 開発スピードがとても上がる
  • 入出力を整理しやすくなり、セキュリティを高めやすくなる
  • システムを変更したときにおかしくなりにくくなる
  • 少々スキルの低い人が混じっても大丈夫になる

まとめ

だれかお金ください。