IT業界で気づいたことをこっそり書くブログ

くすぶってるアプリエンジニアが、日々気づいたことを適当に綴っていきます(受託→ベンチャー→フリー→大企業→ベンチャー→起業)

連番のボタン名がなぜ良くないかを言語化する

これ

b.hatena.ne.jp

元:

https://twitter.com/ohbashunsuke/status/1495900842389610498

 

何か凄い燃えそうだし斧投げすぎるの良くないかなと思ったんですが、テーマとして面白そうだったのでブログ書きます。

とりあえずコメントを見るに「どうやら皆良くないと思っているらしい」というのはわかるんですが、「なぜ良くないか」を言語化しようとすると難しいですよね。
案外きちんと反論できない人も多いのでは?

 

問題・テーマの一般化

問題の一般化からちょっと手こずるんですが。トライしてみます。

仕様変更に強い命名は大事だ。ボタンを「OKボタン」や「Noボタン」と名付けていたらヤバいかも。ゲーム開発に仕様変更はつきもの。開発中盤「OKボタンの色を使ってキャンセルボタンを作りたい」というケースもある。結論、用途ではなく機械的な名前をオススメ。後の参画メンバーの混乱は避けるべき。

「OKボタン」などの用途名はやめよう、「ボタン1」とかにしよう。という話です。
動機は仕様変更であり、「後で変わるかもしれないから」です。

 

あと、おそらくこれは共有パーツの話だと思います。
流石に特定画面内の1パーツを連番にしようという話ではないと思うんです。合ってるかな・・・?

 

なのでテーマとしては

テーマ:共通クラス名は、ある初期仕様における用途名で作るべきであなく、連番のような機械的な名前にするべき。は正しいか?

で合ってると思います。

 

具体的に課題に感じているのは

例えば「OKButton」と名付けたのに後々別の用途でも使う事になった。
名前変更がコストかつリスクである。

だと思います。

 

ちなみに前提として「最近のゲーム開発である」があります。

 

たぶん誤解されているテーマ

誤解というか、似た別の例として捉えている方が多い印象です。

・特定画面のパーツの名前を用途名にするか、機械的にするか?

・そもそも命名機械的であるべきか?

・データ側の命名規則機械的であるべきか?

・OK/Cancelを混同していいかという問題

 

これは汎用性の話

エンジニアという生き物は少ないルールで多くのことを表現したがります。
昨今の仕様が動くことを前提にした開発においては、たしかに汎用的に作った方が楽なように思えます。
さもないと、代わりに例外が増えます。例外が増加すると状態数が増えて訳がわからなくなります。

 

ボタンを汎用的に作りたいという要求→機械的な名前

例えば序盤の仕様では緑のOKボタンがあったとします。
それをOKButtonとしたら、次の仕様では「次へボタン」も同じ緑のボタンでした。
そこでOKButtonをPositiveButtonとリネームしました。
すると次の使用では「戻るボタン」も緑でした。
そこでPositiveButtonをGreenButtonとリネームしました。
すると「戻るボタン」は特定条件でオレンジに変化することがわかりました。

 

というようなことがあって、「じゃあ最初からButton_1でいいじゃん」という主張担ったんだと思います。
こういうの、皆さんはどうしていますか?

 

Button_1の致命的な問題

何のボタンかがわかりません。
これは本当に致命的です。
こうなると、いつどのボタンがButton_1になるのか、Button_1の正しい仕様は何で、正しくない動きは何かなどが分からなくなっていきます。
凝集度とかそういうレベルじゃなく、スパゲティコード(神クラス)になっていきます。

 

凝集度 - Wikipedia

God object - Wikipedia

 

後任者はButton_1を「どのように使われているか」でしか判断できなくなります。
(きちんとした外部ドキュメントがあれば別ですけど、まあ大体ないですよね)

 

※神クラスの厳密な定義からすると私の意図しているものとちょっとずれるかもしれません。支配的なクラスと言うより、何でも詰め込まれたFatなクラスというイメージで使っています。

 

どのように使われているかしか判断できない可読性最悪なクソClassが神クラスになる

これって何か名前ついてないんですかね?
私は過去十数年でこういうClassに何度も何度も何度も何度も出会ってきました。こいつに出会うと数日、下手したら数週間苦しみます。
今回の例では「青いボタン」のような共通した見た目のデザインがあるからいいですが、そうではない場合は本当にわかりません。

例えば、OKボタン、進むボタン、戻るボタン、で使用されていたButton_1があったとして、「同意するボタン」にはButton_1を適用するべきでしょうか?例えば、「同意するボタン」にButton_1を適用する場合、Button_1を少しカスタマイズしなければならないとしたらどうでしょうか?Button_1をカスタマイズしますか?ほら、神クラスの誕生です。

 

汎用的な名前をつけるとFatな神クラスができる

例えばiOSの界隈では数年前に「BaseViewController作るのやめよう」って流れあったんですが、あれです。
全ViewControllerがBaseViewControllerを継承しているという神クラス状態なのがまずいのと、あとは「Base」という汎用的な名前が危険というのが一点。

もっと端的に言うなら「単一責任の原則の逸脱を誘発する」からダメだと思います。

 

抽象度を上げると可読性が下がる

そもそもなんですけど、プログラミング全般において汎用性を上げるということは抽象度を上げるということであり、結果的に可読性は下がります。汎用性というのは色んなパターンに対応するということであり、読み手はそのクラスが取りうる全空間を理解しなければきちんと使いこなしたり改修することができません。

どういうわけか、最近周囲では抽象度を上げることに躍起になっており、可読性がかなり犠牲になっているんですが何故なんでしょうか?
すいません脇道でした。

機械的な名前というのは「抽象度を最大限取った」ということですよね。可読性は死にます。後任者はこちらの方が混乱すると思います。というか地獄。

 

結論

テーマ:共通クラス名は、ある初期仕様における用途名で作るべきであなく、連番のような機械的な名前にするべき。は正しいか?

正しくない。

・スパゲティコード化(神クラス化)を誘発するからよくない

・可読性がゼロだからよくない

 

対策

結論では具体的な課題は解決されていません。

 

例えば「OKButton」と名付けたのに後々別の用途でも使う事になった。
名前変更がコストかつリスクである。

 

これについて、ブコメでは命名の工夫などが挙げられました。
私も概ね賛成というか、ハードウェアレベルのコストでないのであれば随時名前変更した方が良いと思います。また、積極的に「似た異なるクラス」を作ってもいいと思います。1個で全てまかなおうとしないでください。

それ以前に、Mixinの仕組みが備わっているのであればClassを作成せずそれを活用するのが良いと思います。iOSで言えばextensionやprotocolです。

Mixin - Wikipedia
Swiftのprotocol extensionでmixin的なものを実現する - Qiita

 

それでも連番のような抽象的な名前が発生するケース

門外漢ですが。

例えばそもそも汎用的なハードウェアであれば、ボタン1、ボタン2、ボタン3、のような命名は致し方ないシーンがあると思います。
あとは公開APIのパラメータやデータベースのような、後で命名変更するコストが甚大なケースはしょうがないのかもしれません。
ただその場合もできるだけ具体名にすることを諦めるべきではないと思いますし、そもそもアジャイルな開発手法は向いていないと思います。

今回は「最近のゲーム開発」という文脈ですので、おそらく仕様変更に対応しやすい仕組みが導入されているのではないかと思いました。知らんけど。

 

おわりに

でも少し昔は普通にそういう実装多かったし今でもありますよね。
たぶん今回はみんなのトラウマを呼び起こしたんだと思います。
もうコードリーディングしたくない・・・

Delivery(納期)とQuality(品質)を柔軟に入れ替えられる人は少ない

QCDはトレードオフする。という話があります。
Quality、Cost、Deliveryは一つ上げると他が下がるみたいな話。
エンジニアにとって特に重要な要素としてはQとDなわけですが、世の中に案外QとDを調節できる人は少ないです。
私もぶっちゃけ得意じゃないです。

 

なぜかと言うとどこらへんまでQを重視/軽視していいのか、どこらへんまでDを重視/軽視していいのかという温度感を学ぶのが非常に難しいからです。
一番良いのは新規立ち上げのベンチャー企業でバグだらけでも構わないシステムを最速で出す経験と、大企業で人名に関わるようなクリティカルなシステムを開発したり、その中間のいくつかのパターンのプロジェクトを経験しないとわからないからです。

 

例えばそういったQとDの組み合わせパターンがナレッジとしてまとめられていたとしても、各々が受けいれること自体が非常に難しいのです。
なぜならある組織においては固定のQとDの組み合わせさえあれば十分だからです。ベンチャーならベンチャーのQとD、大企業なら大企業のQとDさえあればよく、それ以外を唱える者を異端者として糾弾したほうが手っ取り早いのです。

 

特定のQとDがあり、それを元に「どのようにそれ(より重視する方)を実現するか」という点に重きをおいてキャリア構築をするとなると、別パターンのQとDの存在は否定したくなります。ひょっとしたら自分のやり方は間違っているのではないか?と思いなから仕事するのは精神的にかなりきついです。

 

自分の中の相場(品質はこのくらい、速度はこのくらいが普通)というのを信じて、それ以上もそれ以下も「おかしい」と糾弾するのは、その組織で生きるために戦略として間違ってはいないと思います。

 

気をつけなければならないのは採用者です。
今の事業にとって、どのQとDの相場感覚を持った人が必要なのかよく考えなければなりません。間違うと非常に厄介なことになります。

 

特に品質過剰においてそれが顕著ですから、採用者のやるべきことは「納期に対するモチベーション」だと思います。

 

あるいはフリーランスであれば複数のQとDの組み合わせを駆使しないと行けないシーンが有るのかもしれません。
とはいえそんな器用に組み合わせて仕事をしている人なんてほとんど見たことがないですけどね。
私はそうなりたいですが、やはり億劫なので、「自分がベンチャー寄りに偏っている」というあたりを認識する程度に留めています。
しかしそれだけでも採用者には非常に喜ばれる事が多いです(そして仕事につながる)

 

 

もっと基礎を疎かにしろ!

プログラマーに数学が必要かどうかの論争って定期的におこりますよね。
Twitterでバズってましたね。

note.com

 

私は「大学を出たような人が改めて数学を勉強し直すほどのことは必要ないんじゃない?」と思ってます。さすがにセンター試験レベルの数学は理解できていてほしいですし、嫌いだからって逃げてたらいつか痛い目見るとは思いますけど。

こういう論争でよくあるのは「若手プログラマーは今のうちに数学を沢山勉強しておけ」という論に対するカウンターですよね。私もこういう論調にはイラッとします。そういうので語られる数学って実務で出てきませんし。

もちろん数学が必要になる分野の人も居ますけど、その人が別の分野で必要になる知識を基礎から覚える必要は必ずしもないわけです。

いわゆる「教養は必要かどうか」という話ですね。

 

教養は必要かどうか、というテーマに終止するのであれば多分世の中は平和なんです。
「実務では使わないけど、教養として知っておくと良いことあるかもしれない」くらいの論調であれば波風は立ちません。
問題なのはプチインフルエンサーみたいな技術者が新人に対して「実務で使うからこれらの数学の基礎を叩き込んでおくように」と言うと炎上するわけです。
まあそういう数学の知識をフルで使うのはかなり特殊な人でしょう。これはWeb系だの組み込み系だのSIだの全部ひっくるめてもそうです。疑うなら情報処理試験の内容を見てほしいです、ほぼ数学は出てきません。

 

面倒くさいのは、かなり特殊な人に限ってインフルエンサーなんですよね。彼らも人間なので、自分の状況が世間の状況とイコールであると信じてしまうんですよね。バカですよね。
あとは新人って「これ勉強しとけ!!」って言われると信じちゃいますから、そうやってバズらせるのを狙ってる人も居ますよね。あるいは天然で勉強家な人が「俺が勉強してよかった本」とかまとめちゃって、それが新人に拡散されまくった結果バズって、「バズってるからこれらは必要な知識なんだろう」と誤解されるケース。バカですよね。

 

ところで私は基礎勉強に対する過剰な信仰が嫌いです。
勉強する=良いことみたいな。こういうの真面目な人ほど学生時代に叩き込まれますよね。知識の積み重ねみたいなやつです。
これと対象的な考え方に「研究」があると思います。テーマを探し、課題化し、解いて目的を達するみたいな。
両者は似ていますが、勉強は誰かが作って体系化したものを頭の中にコピーする作業です。研究はまず目的や課題があって、それを満たすために色々行動するみたいな感じです。必要ならば勉強もするみたいな。
私はプログラミングにおいては研究の力の方が重要だと信じています。

 

ITの業界は過去の天才たちが非常にうまいことやっていて、基礎知識がなくても、途中から始められるようにできています。途中から階段を登り始めて目的を達することができる。よく「巨人の肩に乗る」って言いますよね。
基礎部分が隠蔽されている場合は、時には基礎を知らないほうがノイズがなく思考がうまく進むケースもあります。
もちろん基礎を知っていたら、巨人の肩が揺らいだ時にそこを補強することもできます。しかし巨人の足元から肩まで勉強するとなると相当な秀才でもない限り難しいと思います。更に悪いことに巨人自体が毎年更新されていくので追いつくのが大変です。

 

ちなみに数学の基礎というのはその巨人で言ったら脚くらいの位置にあたるんじゃないでしょうか?

 

その巨人の部分をどうにかするというのは世の極一部の天才プログラマーに任せて、世の大多数のプログラマーは肩に乗ったあとの応用研究に勤しむべきです。
目的や課題を探し、プログラムが動くように考え、必要になったらより低レベルの基礎を学んでいくという、下から積み上げるのではなく必要に応じて上から順に探査していく方が効率的ですしプログラマー的な思考だと思っています。

 

というか積み上げ式の勉強を信仰してる人を見ると大丈夫だろうかと不安になります。
本を10冊読んだ人より、アプリを1つリリースした人のほうが私は信用できます。
もちろん優秀な人はどっちもやっちゃうんですが、大多数はそれを自分ができると思わないほうがいいです。

 

それにしても前から思ってましたが知識体系化の作業って非常に難しいですね。
なぜ難しいかと言えば、例えばQiitaやSNSみたいなシステムだと評価者が分かってない人ばかりですから(私含め)、いいね数やバズ具合で正しいかどうか判断できませんし。
ブログみたいなのも書き手の事情や出世ゲームや好みや優秀さに依存していますから、果たして自分の事情と合うかどうかは判断が難しいところです。
結局どこまでいっても自分の頭で考えていくしかないというのがプログラマーという職業だと思います。いつか業界の新陳代謝がゆっくりになればそれも終わる日が来るかもしれませんけど、我々が現役の間はたぶん無理そうです。

フリーランスエンジニアの単価と「安すぎる」というコメントの謎

この記事が目についたんですが。

qiita.com

 

良いか悪いかで言ったらQiitaでそういうのは見たくないというのは個人的な感想なんですが。それは置いといて、毎度恒例、はてブでは「安すぎる」というコメントが多く見られました。

[B! エンジニア] エンジニア200人に聞いて、業務委託単価表を作りました - Qiita

 

こういう「単価出してみました」に対する「安すぎる」というブコメは何年も前から大量に見つかります。果たしてこのQiitaは安いんでしょうか?

 

 

私は「妥当」派です


2年前に書いた記事で私が同じような単価感で書いています。

 

otihateten.hatenablog.com

otihateten.hatenablog.com

 

壁の存在も大体似ていますね。6000円あたりから急に難易度が上がっています。

 

じゃあこの「安い」と言ってる人達は何者なんでしょうか?


「私の周りのエンジニアはこんな安くない」と言うようなブコメも何件も見たことがあります。
彼らの意見を総合すると

  • ジュニアクラスでも最低80万
  • 100万はもらわないときつい
  • 140万以下は安い
  • 時給というのがまず意味わからない

彼らのコメントを観察するとどうやらSIerであることがわかります。ではSIerフリーランスはそのくらいもらっているんでしょうか?
月150万円だとすると、年間1800万円です。弁護士や医者の最近の平均が年収1500万円なので、これは夢がありますね。SIのフリーランスエンジニアはひょっとしたらすごい儲かるのではないでしょうか??

 

昔、そう思って頑張って調べたんですが、そんな案件は一つも見つかりませんでした。エージェントにも何人か聞きましたが私の体感の方があってました。
SIerの業界の案件も扱ってるレバテックフリーランスの最高単価が160万円です。普通に検索すると高くて100万円前後です。
PMOレベルになると150万円単価もあるらしいですが、そこまでいくとエンジニアの枠を超えてしまいます。「一般的なフリーランスエンジニア」ではなくなるのでQiitaの記事を「安すぎる」とは言えなくなってしまいます。

 

仮説:会社間の人月単価と混同している?

例えば受託企業で働く時、1人月の案件を幾らで相手の会社に提示するかという、会社間の単価が存在します。
これは当然フリーランスエンジニアの単価よりも高くなります。
例えば昔居た受託企業では、1人月を120万円で相手の会社に請求し、それを1人月80万円のフリーランスエンジニアに作業させて、その利ざやを儲けとしていました。
このような商売になっているので、当然会社間の単価とフリーランスエンジニアの報酬は変わってきます。

彼らはこの会社間の単価とフリーランスの報酬を混同しているのではないでしょうか??

つまり彼らはフリーランスエアプなのではないかと。
SIerというのはほとんどが受託ビジネスなので、人月単価と言うと会社間のソレを指してしまうのではないかという予想です。もちろんWeb系も受託は多いですが、声がでかい人は自社サービスであることが多いので人月単価と言えばフリーランスの報酬のイメージが強いと思います。

 

会社間の単価、フリーランスの単価、正社員の給料の差

妥当性ではなく相場として、大体こういうふうになっていると思います。

 

正社員の給料10万円に対して、会社間の単価が24万円くらいで、フリーランスの単価が16万円。

よりリアルにすると

正社員の給料50万円に対して、会社間の単価が120万円くらいで、フリーランスの単価が80万円くらい。
正社員の給料600万円に対して、会社間の単価が1440万円くらいで、フリーランスの単価が960万円くらい。

正社員は大企業と中小企業でまた違うんですが、ざっくりこのような感じだと思います。
売上1000万円稼ぐ正社員の給料が大体420万円くらいになるので、感覚としてあってるのではないでしょうか?

※この計算は労働分配率の高い中小企業に限られます。大企業だと労働分配率が非常に低いことがあります。

 

正社員の給料と、フリーランスの報酬はなぜ差があるのか

ここらへんです。たぶん。自信薄。

 

フリーランスの報酬と、会社間の単価はなぜ差があるのか

  • 契約形態(準委任、請負)
  • 信用度
  • 作業の広範さやサービスの違い
  • 相場

ここらへんだと思います。これも専門ではないので自信薄。

 

正社員とフリーランス、額面で何倍の差があるか?

フリーランス/大企業 だと1.55倍くらい
フリーランス/中小企業 だと1.35倍くらい

の差があります。
差が大きいほど福利厚生の差があるということになります。

福利厚生が大きい大企業で600万円もらってる人は、中小企業では680万円、フリーランスでは930万円稼がなければ下がった事になります。

 

あと、CTOってそんな稼いでなくない?

ググれば大量に出てきますけど、平均すればだいたい784万円らしいですよ。何でそれがフリーランスになって年2000万円に化けるんですかね?

 

時給にしっくり来ていない人ら

最近Web系では人手不足やら働き方の改革やらなんやらで時短での労働が増えてきたと思います(体感)
そのため副業や複業が増えてきていて、時給という概念が強めに前に出てきています。
あとは準委任契約をすれば140〜180時間など、時間のレンジで契約してそれをはみ出したら精算という形になるので、その時に時給というのが登場します。
最近のWeb系におけるフリーランスエンジニアには時給は馴染みがあるのですが、それにしっくりきていないということは労働形態や契約形態からして別物ということになります。前提を履き違えた上で安いだと高いだの言うのはエンジニアとしてどうなんでしょうか。

 

おまけ:他の業種・職種の単価など

頑張ってググればSIer方面の会社間の単価が出てきますが、上級SEで大体160万円とかそこらへんらしいです。IBMとか日立とか富士通とかそういうところのSEです。いわゆる元請けや1次請け(門外漢なのでググった情報でしかないですが)
Webの受託企業だと会社間で120万円は中々いかないと思います。120万円いくと大企業からも「高いね」と言われるらしいです。昔居た会社でPMが言ってました。
上でも書きましたが、PMOになるとフリーランスの単価が150万超えることもあるそうです。フリーのコンサルの単価はググれば200万とか出てきますけど、案件の難易度が「これ誰ができるの?」というレベルで、個人的には200万でも安いと感じる物が多い印象です。
Web系におけるフリーランスエンジニアの単価は大体65万くらいが平均になってきます。50万切ると安い印象があります。Qiitaの元記事では1,2年目のエンジニアについて言及が有りましたが、ここらへんはそもそも相場形成がされていないと思います。フリーランスって基本的にベテラン前提ですから。
ていうかここらへんってエージェントに複数登録すればすぐわかりますよね。

あと注意したいのがWeb系副業の単価で、副業になると相場がかなり落ちると思います。大体2500円〜3500円/時の案件が結構多いです。商流によってはそうではないケースも増えてきていますが。副業は案件数がまず少ない上に、やりたい人が非常に多いので需要と供給で買い手市場なんです。例えば大企業の福利厚生をある状態で副業をすればフリーランスほどの単価がなくても皆やりたがるんですよね。

 

追記:PMO案件の単価のグラフ発見、中央値で120万くらい?

案件実績 | PMOコンサルティングプロジェクトならPMO案件.jp

 

追記:総合して考えると、大企業の年収800万を超えるようなエンジニアは正直フリーランスエンジニアになってもメリット薄いと思うんですよね。もちろんそれを修行と捉えてその後でまた正社員に戻るなら別ですけど。あとは時短でヌルく生きたい人とかも別ですが。

 

おまけ:120万円の単価を超えるにはどうすればいいか?

前に書いた記事を元にすると、最近の私はここらへんです。

 

f:id:otihateten3510:20210930004954p:plain

完全に「現実的に不可能」の更に外にいってますね。
2年でもう昔考えたラインをぶっ壊しています。
なんか、120万円とか150万円とかそこらへんを超えるには天才でない限りそこそこ無茶をする必要がある気がします。あと「こうすれば超える」というのが無いと感じます。パターン化が難しい。むしろそういう替えの効かない経歴になってくると超えるんじゃないですかね?
超える兆候はあると思います。営業せずに勝手に仕事が入ってくるとか。前に参考にしたmizchiさんも似たこと書いてた気がします。
あとやっぱり法人化はでかいんじゃないですかね。ぶっちゃけよくわからないですけど。
請負にすれば上がるのかどうか、というのは私はまだ知見がありません。請負にすれば上がるのか法人だから上がるのか、最近はラボ契約というのもありますし。あれってたぶん準委任ですよね??

 

まとめ

推測の域を脱さないですけど、勘違いしてる奴らが多いのでは?というのが結論です。

 

こういうコメント見る度に昔から腹を立てていまいた。
例えば自分が妥当だと思ってる報酬があって「安すぎる」というコメントがあったら、それを見た人にとって精神衛生上良いことは一つもないですよね。しかもそれが真実ならともかく勘違いなら尚更です。私はまだそういうのかなり調べるので良いんですけど、若手とかが「月120万円くらいもらえるんだ!」とか「今の会社は不当に安い報酬なんだ!」とか勘違いしたり、「こんな安い単価を受けちゃダメだぞ」を真に受けたりしたら可愛そうだなと思いながらいつもそういったコメントを見ていました。
こいつらただの世間知らずでは?そういうのに限って経営者だったりするから余計腹が立つんですよね。200人に聞きましたというアンケートなのだから、自分の感覚と合わなかった時には前提を疑うべきだと思うんですが。

 

Web系の人は「会社間の単価」というものに対する馴染みが薄めなのでそういうふうな声が出てこないんですけどね(Twitterとかでは安いというコメントは少ない・・・と思ったらバズってきて徐々に出てきました。やはり普段Qiita見てない層に届いてるんですかねこれ?QiitaってかなりWeb系寄りの情報多いのに、そこへ来て定義がどうの言ってるのもクレーマー感すごいです)

 

 

追記:「フリーランスの」と限定していなかったから?

この記事のブコメにもあった、「Qiitaの記事のタイトルに『フリーランスの』がついてない」という話。確かにさっき私も見て私も気づきました。あのタイトルだと会社間だと誤解するかもと。
なるほどこれは「業務委託単価」と言った時に想定するものに個人差があるという、名前空間の問題だったのかもしれません。
(つっても記事内の本文見れば書いてますけどね)
「業務委託単価」と言った時に人によって前提が異なるというのは教訓なのかも?

 

追記:イキリ勢?

なんか不必要にバズってしまいましたが。
この記事に対する反応を見ても、あくまで相場に対する話をしているのに
「150万以上の案件は有る。お前らが見つけられないだけ」だの
「このような安い金額で請けるべきではない」だの
「俺の周りでは皆高い」だの
「弊社はそんな安くやってない」だの
頭の悪いイキリコメントが頭の良い界隈で散見されたので、多分そういう人らも混ざってるんだと思いました。

それって例えるなら「サラリーマン200人に聞いたら平均年収が436万円でした」という話題に対して「1000万円超えの仕事はある」だの「そのような仕事はするべきではない」だの「俺の周りでは皆高い」だの「弊社の給料は~」だの言ってることになるんですが分かってるんですかね?皆知ってますし今そういう話してないです。

 

百歩譲って「こんなに安いとは嘆かわしい。皆もっと上げていこう」とか「具体的な金額を出すと相場が硬直化するから良くない」とか「もっとこうすると単価は上げられる」などは筋が通ってると思います。

 

追記:発注価格で考えてたから?

フリーランスが受け取る価格じゃなくて、発注側の価格で考えると非常に安く感じる説。これもあるかもしれませんね。
私は最近ほとんど直接契約なんですが、世の中の多くはエージェント経由です。
エージェントは噂ベースですが5%〜20%は抜くでしょうから、80万円は、発注側からは84〜96万円に見えるわけです。時給ベースで考えれば5000円が5250円〜6000円に見える感じですね。ただ、その程度の差なら「安すぎる」という感想より「やや安い」くらいの感想が出てきそうですけど。

iOSエンジニアはMVVM・RxSwiftをやるべき?キャリアパスから解説する

タイトルは釣りです。

 

本当に書きたいのは

エンジニアはスキルの陳腐化やコモディティ化とどう戦っていくべきか

です。
クソ面倒くさい話を書きます。
死ぬほど長いです。

 

 

モチベーション

最近16人のiOSエンジニア志望者と1時間程度の面談を行ったのですが、多くの人が似たようなことを言っていました。

 

アプリ開発について勉強していて、アプリも出してみたが、次に何をすべきかわからない。とりあえず求人情報を見たらMVVMとRxSwiftが書かれていたのでアーキテクチャについて勉強しようと思う。

 

それでMVVMってどうなの?というあたりを15分くらいで早口で説明するのですが、ちょっと口頭で話すには複雑すぎると思いました。
あと自分でも色々考えをまとめたかったので書きます。

 

免責事項

正直ここらへんの話語りたくないんですよね。
知識不足が露呈しそうで。
iOSアプリ開発は30案件くらいやってますが未だに自信がない。
話半分くらいでお願いします。
違う意見があったらください。

 

MVVMとは?

ja.wikipedia.org

 

ここ3年くらいのiOS界隈ではMVCの上位版みたいな語られ方をしますね。

 

MVC, MVVMはどこから来たのか?

きちんとどこから来たのか調べ始めると私の休日(※休んでない)が溶けるので辞めますが、乱暴な言い方になりますが、今のアプリ界隈におけるMVCってそもそもWeb開発から来てませんか? Webのフレームワークって明確にMVCが別れていますよね。アプリにおけるMVCと全然印象が違います。

 

たぶん合ってると思うんだよなあ。
2010年頃のWeb開発では既にMVCは常識中の常識でした。

f:id:otihateten3510:20210912173234p:plain

 

対してMVVMは明らかにWindowsから来ています。

 

f:id:otihateten3510:20210912173513p:plain

f:id:otihateten3510:20210912173609p:plain

 

WikipediaのMVVMについての説明を読んでみましょう。

根拠
MVVMは、WPF(Windows Presentation Foundation)のデータバインディング機能を利用して、ビュー層からほぼすべてのGUIコード(コードビハインド)を取り除き、ビュー層の開発を他のパターンから分離することを目的として設計されています[3]。このように役割を分けることで、インタラクティブデザイナーはビジネスロジックのプログラミングではなく、UXのニーズに集中することができます。このように、アプリケーションのレイヤーを複数のワークストリームで開発することで、生産性を高めることができます。一人の開発者がコードベース全体を担当する場合でも、エンドユーザーからのフィードバックに基づいてユーザーインターフェースが開発サイクルの後半で頻繁に変更されることが多いため、ビューとモデルを適切に分離した方が生産性が高くなります[要出典]。

MVVMパターンは、MVCによって提供される機能的な開発の分離という利点と、純粋なアプリケーションモデルにできるだけ近いところでデータをバインドすることによるデータバインディングフレームワークの利点の両方を得ようとするものです[3][4][11][clarification needed] バインダー、ビューモデル、およびあらゆるビジネス層のデータチェック機能を使用して、入力データを検証します。その結果、モデルとフレームワークができるだけ多くの操作を行い、ビューを直接操作するアプリケーションロジック(例:コードビハインド)を排除または最小限に抑えることができます。

www.DeepL.com/Translator(無料版)で翻訳しました。

 

ちなみに推奨されてるだけで、WPFをMVVM無しにでも作れるみたいです。

Web界隈では、大体2016年頃から流行ったのではないでしょうか?(合ってる?)Vue.jsが流行り始めた当たりからです。Qiitaでひっきりなしにそういった話題が出ていたのを覚えています。

f:id:otihateten3510:20210912174958p:plain

 

やや遅れて、RxSwiftが流行ります。RxSwiftはSwiftでMVVMをするならできれば入れておきたいLibraryです。だいたいSwiftが出た次の年くらいですかね? 2016年にSwift2.3で結構安定しまして、そこらへんからRxSwiftが盛り上がってきます。(ちなみにSwift4.0で仕様がかなり変わって大変でした)

 

f:id:otihateten3510:20210912175108p:plain

 

まあつまりちょいちょい流行っていて、アプリ界隈はWindowsやWebからやや遅れて、言語がモダンになったのにあわせて(Swift,Kotlin)2016年くらいから行り始めたという感じです。

 

RxSwiftとは何なのか?

ReactiveXというパラダイム・思想です。

 

reactivex.io

 

f:id:otihateten3510:20210912180215p:plain

 

ざっくり言えばオブザーバーパターンを実現するためのLibraryです。
あと関数型言語っぽく書けます。
上のページには他に、コードの行数を減らせるとか、非同期エラー処理に強いとか、並行処理が容易と書いています。

 

ここで脳が破壊されるのが、Rxを評価するということはすなわちオブザーバーパターンや関数型言語の評価をすることと同義であり、それは非常に厄介です。永遠のテーマに近いのではないでしょうか。大多数のエンジニアには荷が重いはずです。

 

そんな中、なぜRxSwiftが流行ったのかと言えば、上の特徴とは無関係に、データバインディングができて、MVVMが実現できるからに他ならないでしょう。

 

MVVMがやりたい → RxSwiftを導入する → 関数型言語・オブザーバーパターンについての勉強が必要

 

この流れができています。

まあここらへんも私の妄想でしかない可能性があるんですが、とりあえずはデータバインディングとMVVMが標準装備されているAndroidの方では、RxKotlinがさおど流行ってないんですよね。


Githubでも
RxSwift ★20.9K
RxKotlin ★6.7k

とこんな具合です。
RxJavaは強いんですけど(★45.3k)

 

関数型言語・オブザーバーパターンはなんか良いやつなの?

両者大昔からあって、現代のメインストリームのパラダイムになれなかったやつらです。
良い悪いっていうより、完全に向き不向きだと思うんですよね。作るプロダクトに対して選択するのが良いと思ってます。
ちなみに私はLISP恐怖症なので良いイメージ無いです。

 

ja.wikipedia.org

ja.wikipedia.org

 

なぜMVVMをやりたいのか、真のメリットは?

  1. 分業ができる
  2. 変更容易性により、生産性を高められる(要出典)
  3. FatViewController, FatModelを回避したい(可読性)
  4. 疎結合になり再利用性が高まる
  5. 自動テストが可能になる

あー、なんだか色々否定するのが難しくなってきました。そして自信もない。

まず1の分業はしていません。Webではフロント/バックエンドで上手くやってるのかもしれませんが、アプリでは明らかにできていません。
2,3,4について言えば作ってみればわかりますがメリットどころかコードが膨大になって複雑性が増すので却って有害な場合が多いです。これはあまり反論がないのではないかと思うんですがどうなんでしょう?それで最後に残るメリットが「テスト可能性」なんですよ。というのが私の主張です。

※ここのロジックが一番ふわふわしていますが、説明できる自信がないです。結果的にそうなっているとしか言えず、何故そうなるかとか、ちゃんとした人がコードを書けば大丈夫だとか、色々言われそうです。

 

iOSアプリ開発で自動テストは必要なのか?

上記のロジックから考えると今度俎上に上がるのはこの議題なんですが、これも非常に語りづらいです。
私はiOSアプリにおいて自動テストの優位性はかなり低いと思います。全部不要というわけではありませんが、少なくともテストコードを書くためにアーキテクチャーを大幅に変える必要はないと思っています。

 

自動テストを書く理由ってここらへんですよね。

  • フロントからアクセスしづらい機能だから
  • 大量にテストをまわしたいから
  • 継続的なデプロイを高頻度で行うから
  • 手動テスト工数をそれほど積めないから
  • 実行環境が多岐に及ぶから
  • 実行環境を用意できないから
  • 再現が難しいから
  • 変更が外的要因だから、いつでも検知できるようにするため
  • クリティカルなサービスであるため(人名やお金)
  • より完璧な品質のため
  • TDD的な思想、リファクタリングする時に必要だから
  • 仕様把握のため

このうちiOSアプリにおいて該当するのは本当に僅かです。WebやAndroidに比べても必要なシーンは少ないし、ピンポイントでそこだけ対応するのが妥当だと思っています。
以下のフローは多くのプロジェクトで起きていると思いますが、考えてみると高い学習コストを払ってまでこの選択をすべきなのか疑問です。

 

自動テストを書かなきゃいけないから → MVVMがやりたい → RxSwiftを導入する → 関数型言語・オブザーバーパターンについての勉強が必要

 

これはMVPやVIPERなどのアーキテクチャでも同様です。
(ReSwiftは別の文脈ですが)

 

iOS MVVMは一過性の流行なのか?

アーキテクチャのトレンドは毎年のように変わります。

MVCがクソと言われ、Apple提唱の方法から離脱し、MVPが流行り、MVVMが流行り、CleanArchitectureが流行り、VIPERが流行り(?)
かと思えばCocoaMVCって良いよね、と回帰してる人も現れたりして、みんな思い思いに自由に勝手なこと言っててすごいです。ついていけません。

 

じゃあMVVMが一過性なのかと言えばNOです。
ここからは非技術的な話が入ってきます。

 

1.MVVM+RxSwiftで慣れた人は、MVVM+RxSwiftが書きやすい

当たり前なんですが、その書き方に慣れた人はその書き方が一番書きやすいんです。RxSwiftの熟練者だけのチームがあれば、当然次のプロジェクトでもRxSwiftを採用するでしょう。CocoaMVCはおそらく書きづらいと思うはずです。

そして、会社を挙げてRxSwiftを使っている有名な会社がいくつかあります。代表例はDeNAクックパッドドワンゴです。サイバーエージェントは確かAbemaTVあたりがRxだったはずです。

他にはベンチャー企業がRxSwiftをよく採用しています。新しいもの好きですね。

 

2.RxSwiftが向いているプロジェクト、MVVMが向いているプロジェクトがある

たとえばライブ配信アプリのように、沢山の要素(view)が同時に動くようなアプリではRxSwiftが向いているらしいです。これはオブザーバーパターンが向いているからです。

そして大規模なアプリでは自動テストの必要性が上がってくるため、当然MVVMを採用したくなります。結果的にMVVMやRxSwiftが消えることは直近1,2年ではありません。

 

MVVMは無くならない

わかるでしょうか?この2つの理由はお互いにコラボレーションします。一定の割合でこれは残っていくはずです。

 

副次的に起こるRxSwift+MVVMの必要性、そして避けられないコモディティ化

大企業が作ってるような大規模な案件や、ライブ配信のような新規性のある案件、目立ってるベンチャー企業がRxSwift+MVVMを採用すると、当然皆が真似します。実際に2018年、2019年はそこそこ流行った認識です。

しかし当然、向いていないプロジェクトでも採用されました。

logmi.jp

 

また、AppleがRxSwiftと似たような仕組みであるCombineというのを発表しました。これがiOS13からなので、採用し始めるプロジェクトが出るのがおそらくそろそろ出始めると思います。本格的に採用するのは、おそらくSwiftUIが本格化する来年下旬か再来年だと想います。

developer.apple.com

 

また、SwiftUIではデータバインディングができるらしいので、RxSwiftを使わずともMVVMが実現できるようになります。

 

これらをまとめると、RxSwiftの優位性はかなり落ちるでしょうし、MVVMを続けようとするプロジェクトもどれほど残るかやや疑問ではあります。

f:id:otihateten3510:20210912193101p:plain

 

じゃあMVVMやRxSwiftを勉強しなくていいのか?

これが難しいところで、例えばiOSエンジニア志願者なら答えはNOになってしまうと思います。
まず上で書いたように、RxSwift+MVVMを得意とするチームが少なからず存在すること、またそれに向いたプロジェクトが存在していることが理由の一つ。
そして、たとえそうではなくとも、一度書いたRxSwift+MVVMのコードは5年、10年と保守していかなければならないわけで、そうなると募集要項に「RxSwift+MVVM」が入ってくるわけです。

これはSwiftが流行り始めた頃のObjective-Cや、今後SwiftUIが流行った時におけるStoryboardと同じ立場です。つまりレガシーコードになっていくんですが、その需要は確実に存在するため対応が必要です。

 

クソみたいなレガシーコード・チキンレース

エンジニアは常に自分がレガシーコードしか触れない人材になることを恐れています。そのため次の技術を探し、勉強し、トレンドに乗っていち早くそのコードを試して、極力早くそのプロジェクトから脱出するというチキンレースを行っています。
それが上手くできた人は、毎年のように言ってることがコロコロ変わりますが、常にハイレベルのスペシャリストだと認識されるでしょう。

未経験者が就職する際には、一旦その人らが生み出したクソをメンテナンスする業を背負わなければ業界に潜り込めませんので、勉強する必要が出てきます。

 

これは戦略的なゲームです。
例えばFlutterを例にあげれば、いち早くその流行を察知し、勉強し、技術記事を書き、著書を書き、登壇して、スペシャリストになり、それを散々布教した上で企業にアドバイザーとして技術支援して高い報酬を得る。みたいな人も居ます。
羨ましいです!

 

そしてそういう人らの情報を真に受けた我々下々のエンジニアがそれを勉強して、それが業界標準になり、誰もがそれを勉強しなければならなくなる、という社会の仕組みです。

 

だから私登壇とかああ言うのぶっちゃけ嫌いなんですよね。
まあ本人らは楽しくやってそうですし、完全に善意でやってると思うんですが。回り回って事業の速度を遅くしたり工数増大させたりしてるだけでは?という・・・すいません愚痴が過ぎました。

 

新人が採る選択肢はまず2つ、就社(Closed)か、就界(Open)か

もし大企業に就社して、そこの方針が「RxSwift+MVVM使おう!」だったら、それを勉強するべきです。もしそれが別の技術だったとしても勉強するべきです。特に大きい会社では色んな独特な技術が使われています。それがたとえニッチで学習コストが高かったとしても、頭が良い人を採用し、時間をかけてやっていけばいいわけですから。会社の方針は間違っていませんし、社員もそれに沿うのが出世への近道でしょう。
それでいいんです。そういう会社は売上がすごく高いんですから。世間で何が流行ってるかよりも社内で何が使われてるかの方が重要です。

対して、例えばフリーランスジョブホッパーのように「どこでも通用する技術を身に着けよう」と言うのであれば少し話が難しくなります。まず大多数がやっている開発方法を優先すべきでしょう。ニッチだったりレガシーなものを採用しているプロジェクトへのアサインは首を絞めますから、会社や案件選びから考えていかなければなりません。
また、新しい技術が袋小路になっていないか、それがレガシー化した時に自分のスキルとして何が残るか考えなければなりません。

 

Closedな人材としてやっていく場合

何より必要なのは入りたい会社の採用している技術です。
それを調べたりヒアリングするところから始まると思います。
まあこっちは簡単です。

Openな人材としてやっていく場合

こちらは難解です。
まず、特定の技術をやりたいという欲求が具体的にあるのならば、それができるところに行くべきでしょう。
RxSwiftだったり、SwiftUIをやってるイケてる会社を探すのが良いと思います。

 

そうではない場合、より厄介です。
そもそも会社の募集要項に「RxSwift+MVVM」があるのはいくつか考えられます。

  • 現状そのプロジェクトが有る
  • そのくらい勉強している、やる気ある優秀な人材がほしい
  • 流行ってる技術を採用している会社だというアピール

会社としては優秀な人に来てほしいので間口を広くしたいという状況があります。
そうなると、「弊社では最新トレンドの技術が試せますよ」とアピールしたいわけです。この様々な思惑の中、行動を見極めなければならないと思います。

 

もしその会社がSwiftUIを採用していないのに「SwiftUIできる人募集!」と書いていたらどう思うでしょうか?不誠実な会社だと思うでしょうか?そういう会社はたくさんありますが、そうとも言い切れません。
そういう最新技術やってますアピールをする会社には、もちろん技術に対するモチベーションが高い人が集まるでしょう。
逆にレガシーな技術を採用している会社には、優秀な人があまり来てくれないかもしれません。

プロジェクトはチーム戦ですから、優秀な人がより来てくれる会社に言ったほうが安全ですよね?

 

ただ、そういう会社に行くと当然上で言ったような「最新トレンドの社会の流れ」に簡単に流されて苦しい思いをします。
要はどう足掻いても絶望です。

 

iOSエンジニアの差別化しづらい問題

エンジニアってより難しいことやってハイレベルの人材になるみたいな風潮あるじゃないですか。例えば検索技術とか、データベース技術とか、セキュリティ関係とか、ああいうのはそんな感じあるんですが
特にiOSエンジニアはAppleにしたがって普通にやるのがベターみたいなシーンが多くて、ぶっちゃけ歴3年以降、他のエンジニアとの差別化が難しくなってくる職業だと思います。

そんな中焦って色んなものに手を出すんじゃないかと睨んでるんですが、これって難しいですよね。キャリアパスとしてはしょうがない側面もあるし、でも「より難解なことしたもん勝ち」ってなんか嫌ですよね。

フリーランスやってると、RxSwift案件の単価が明らかに2割くらい高いんですよ。これってどういうことかというよ、他人の書いたRxSwiftを引き継いでくれるエンジニアが少ないってことだと思うんですよ。なんかね、お客さんにはマイナスですよね、っていう。

 

絶望から逃れる手

上流工程のような、技術以外のスキルを身につける手がありますが、これでも結局トレンドには流されます。上流工程を身に着けつつ、フリーランスになれば結構この絶望から逃れられます(今の私がこれです)

登壇者になる手もあります。

優秀な、分かってるリーダーの下につくというのも手です。ただしその人がつよつよエンジニアだとついていけない事も往々にしてあります。

自分がそのリーダーになってしまうというのも手です。ただし出世する必要がありますし、部下を制御できるかはまた別問題です。

 

採用しないにしても勉強するのは有り

話の流れで漏れましたが、新しい技術を採用はしないにしても勉強するのは有りだと思います。
何かしらの考え方を参考にして、似たようなことを自分のコードで試すということができます。
教養にもなりますし、いくつかの新しい技術は実際にデファクトスタンダードになってしまいますから、その見極めの練習も必要です。

 

iOS + MVVMは今後どうなる?

私はCocoa MVVMになると思っています。
より柔軟に、画面やパーツ毎に切り替えできるようになるんじゃないでしょうか?ある意味理想的だと思います。

 

話足りないこと・まとめ

まとめるの無理ですわこれ。

とりあえず新人は真面目アピールのために勉強せざるを得ないんじゃないですかね?あと会社の方針はよく聞いたほうが良いです。

あとは、技術の採用というのは絶対的な解があるわけではなくて、トレードオフがあったりチームメンバーに依存したりします。あくまでやってるのは理論じゃなく工学なので。

だから「より良いアーキテクチャーやライブラリーがあるんじゃないか?」というのは幻想だったりします。そういう探求もエンジニアのさがだと思いますが。残念ながらAppleも進化していってるので、その結果iOSエンジニア自体が徐々にコモディティ化していってます。まあアプリエンジニア自体がレアなので全然まだまだブルー・オーシャンですけどね。

そうそう、AndroidGoogleがMVVMを推奨しています。でもこのMVVMはMVVMじゃないとかそういう人たちも居ます。よぐわがんね。宗教戦争

developer.android.com

 

そもそもViewModelって最初は違う意味合いだったんですよ。Utility的な。それがいつの間にかアーキテクチャになって。てか昨今のアーキテクチャという概念自体が、どうにもWebにおけるフレームワークを作りたがってる感じなんですよね。Webは本当にフレームワークありきなんですけど、アプリはiOSAndroidもそれそのものがフレームワークみたいなもんなんで、フレームワークonフレームワークみたいな黒魔術みを感じます。

あとCleanArchitectureはアーキテクチャじゃなくて「きれいに書く方法だ」みたいに言われてますね。私はその本読んでないので何とも言えないですが。

何かしら技術を採用するときは、大抵そのカウンターとなるデメリット記事があったりするので探してみてください。Reduxとかも結構見つかります。ReSwiftってやつ。

エンジニアってどうもこういう枠組み発明をしたがる傾向がありますね。昔はWebやSIerでオリジナルフレームワークが作られてて地獄だった、みたいな昔話が出るんですが、アプリ業界ではそういうアーキテクチャ地獄についてまだ好意的な意見が多いですよね。ちょっと謎。

 

あとなんだろ、思いついたら追記します。

 

宣伝

iOSエンジニア志望者のたまり場みたいな場所を作ろうかなとちょっと考えています。
興味があったらお問い合わせください。
そこからベテランエンジニアがピックアップしていくみたいなイメージで考えてます。あと就職の相談したりとか。
そう言えばオフショアとかニアショアとか存在するのにインターン活用ってあまりないよなと思って、思いつきです。ぜんぜん儲かる気がしないのでただの慈善活動になりそうですけど。

似たようなのは2個くらいあるらしいですけど、用途として被らないようにしたいですね。勉強は見ませんが仕事は与えるみたいな感じで。

 

f:id:otihateten3510:20210912204718p:plain

 

近況 2021/08/27

  • 未経験者を雇って仕事を助けてもらう(2名)
  • ナショナルクライアントから仕事をもらう
  • 単価がチームラボ時代を超える
  • シェアオフィスが取り壊されるので、お引越し

 

下手すると1年半で新規アプリ5件もリリースすることに・・・
こんだけiOSアプリをリリースしてる受託会社あんまないのでは?笑

 

未経験者を雇って実績を与えて就職させるような慈善事業を思いつきました。
案外今の自分には合ってるやり方じゃないかと思います。一人でやるより楽しいですしね。
でもやっぱり3人4人の新人にタスクを振ろうとすると、上手く丁度いいタスクがなかったりして難しいですね。そもそも仕事振っちゃダメっていう案件の方が圧倒的に多いですし。

今は結構奇跡的な気がします。
規模の大きい受託会社じゃなくて、私に直接依頼してきてくれるけど、新人に手伝わせていい、みたいな優しいクライアントに恵まれた感じです。

 

10月までは死ぬほど忙しいことが確定しています。
いい加減に自社アプリを進めたいんだけど無理ですね。とりあえずお金を貯めておきます。

 

今の仕事の実績が見える状態になったら、余計に仕事が舞い込む気がしているんですが、やはり規模拡大したほうがいいのか・・・?でも社名じゃなく個人で依頼してきてるはずなんで、やっぱ難しいんですかね。