書き置き

何かを書き残す

SIerの炎上商法について解説してみる

タイトルは釣りですよ。もちろん。

炎上っていうのは唐突に発生するのではなくて、何かしら兆候があるものです。 SIerはこれを巧妙に隠すことで、ぎりぎりになって「もう追加工数積まないと無理です!」と言ってきます。

今回はこの"兆候"の部分を隠すために使われる手法について解説します。

「見積もり直したので、次のフェーズは大丈夫です」

フェーズAが想定よりもかかってしまいました。 "炎上"というレベルではありませんが、遅れは問題なので振り返り、対策をします。 フェーズAでの失敗を踏まえ、計画を立て直すんですね。

その際によく使われるのが、この言葉です。 以下のような理由と一緒に提示されます。

  • 前フェーズによって、次フェーズの見積もり精度は上がっている
  • 前フェーズで想定外要素は出し切った

フェーズAでの実績をもって見積もり直したのですから、 ↓で言うところの②より④の方が精度は上がっている。こういった主張をします。

f:id:utonn:20180305223416p:plain

実は見積もりの精度は上がっていない

②より④の方が精度が高い。これは確かでしょう。 3ヶ月先のことより1週間先のほうが精度が高い、これは当たり前です。

ですが、これでフェーズAのような失敗は無いと言えるのでしょうか?

そう、失敗したのはフェーズAなんです。
ということは、精度の悪かった①と比べなければ「フェーズAのような失敗」が無いとは言えないはずです。

なのに「精度が上がった」という点だけに着目し、あたかも大丈夫そうに見せかける。
しかし④の見積もりは精度は上がっておらず炎上、追加コストが発生する。 これが炎上商法の手口です。

しかし、こういった見積もりを出している人たちは
自分たちが論点をズラしていることに気づいてすらいないことも多いです。

どうすればよいか

「①と④の精度は同じくらいであろう」と考えましょう。

①と④はぜんぜん違う作業なのです。
ただフェーズが進んだだけで、見積もりの精度が上がるはずありません。

①→③が1.5倍なら、④も1.5倍はかかるんです。 それがきっと今のチームの見積もり能力です。

 

見積もり通り終わったらどうすんだって? 早く終わってよかったね!

最近身近にWF主義者の方がいて。
どうにも「失敗しない」ことに固執しすぎてる感があったので考えてみた。

ケーススタディ

仮にAgile的なやり方の場合に以下とする。

  • 開発期間1ヶ月
  • 失敗率 50%

そしてWF的な場合

  • 開発期間2ヶ月
  • 失敗率0%

だいぶ極端な数値だとは思う。
WFにした途端倍の工数かかるとか、WFだと2回に1回失敗するとか、流石に大げさかもしれないがちょっと考えてみよう。

リリースすることで月500万の売上増を見込めるとした場合。

Agile的な方が早いが失敗率は50%なので、案件達成での売上増期待値は250万といったところか。
対してWFは2ヶ月あれば確実に500万プラスさせることができる。

Agile:毎月の増分 250万 × 12回 = 3000万
WF:2ヶ月に1回 250万 × 6回 = 3000万

どちらも1年後の月あたりの売上は、前年比で3000万という計算になる。
2回に1回失敗という酷い品質なのに、変わらないのだ。

それだけではない。

WFの場合、2ヶ月に1回しか売上が上がらない。
それに対してAgile的な場合、毎月250万の売上増が期待されている。

仮に1月の売り上げが1億として3月までの売上を見ると

WF:

  • 1,2月開発 → 3月から500万増える
  • → 1億×2 + 1億500万 = 3億500万

Agile

  • 1,2月開発 → 2月,3月それぞれから250万増える
  • → 1億 + 1億250万 + 1億500万 = 3億750万

あたりまえだが早くリリースした分、先に売上が反映されるのだ。
素早いリリースというのは、こういったメリットが有る。
過度に「失敗しない」ことに固執するよりは、早く出せるメリットに目を向けてみてはどうだろか。

現実を見てみる

だいぶテキトーな数値を元に計算してみたが、実際どうだろか?

Agileの失敗率はそんなに高いか? 失敗っていっても完全にパーになるか? WFの工数増分は適当か?

それぞれの感覚でもって、考えてみてほしい。

vagrantでansibleでelixir

パソコン買い変えました!無印MacBookのマシマシで!快適!

ということで、せっかくなのでイチからelixir載ったlinuxを作り直し &vagranのprovisioningで済ませちゃおう作戦

モノはこちら→

GitHub - utonn/vagrant-elixir

elixirのインストールについて

今回は、erlangとelixirともにソースインストールしてます。なぜってyum出来なかったからね。 とりあずtry&erroしつつ、事前に必要そうなパッケージがこちら

yum install -y git autoconf gcc ncurses-devel
yum install -y openssl openssl-devel unixODBC unixODBC-devel gcc-c++ fop

上はビルドに必要なもの。
下はelixirが力を十分発揮するのに必要なもの。

あとjinterface(Javaのライブラリとか使えるようになるっぽいやつ)は使わなそうだから無視
wxも、GUIとか開発予定ないので無視

ansible_localでのプロビジョン

vagrantからansible使ってプロビジョニングは、普通にansible使うのとansible_localってのがあるらしいです。

ansibleは、hostマシンからansibleする
ansible_localは、guestマシンからansibleする

ansible_localの場合、当然guestマシン上にansibleが必要になるのですが、そこはvagrant様が自動で入れてくれます。便利。
ということで今回はansible_localを採用。

使う側の環境に左右されないっていうのはいいよね。

playbook

ansible初心者なので、いろいろ試行錯誤がありました。
ansible_localを採用したので、ほぼansibleをローカルにかける時と同じはず。

inventoryにhostsがないと実行してくれない

今回ローカルだけなので、hostsとか別ファイルじゃなくてもいいかなーとか思ってたら
inventoryにないhostは対象にならない仕様っぽい。要調査。

なので127.0.0.1とだけ書いたファイルを用意して、Vagrantfileにてinbentoryファイルとして指定しました。

特定のディレクトリで複数コマンドを実行する

commandモジュールを使うとき、chdirで実行ディレクトリを指定できるわけですが、複数コマンドを同じディレクトリで実行するときって毎回これ書くの?って感じでした。

with_itemsっていうタスクをループできる機能があるってことなので、それを使うことで楽に書けるっぽい

    - name: build & install erlang
      command: "{{ item }}"
      args:
        chdir: /usr/local/src/otp
      with_items:
        - ./otp_build autoconf
        - ./configure
        - make
        - make install

インストールしたライブラリのパスを使う

erlangインストール後、elixirのインストールでerlangのパスが必要になのですが、
普通にPATH=hogehogeってのをコマンドモジュールで実行したらうまいこといかなかった。

で、結局うまく行かなかった理由は分からないのだが、
コマンド(というかタスク?)実行時にPATHを指定するには、environmentを設定すれば良いらしい

    - name: build & install elixir
      command: "make clean test"
      args:
        chdir: /usr/local/src/elixir
      environment:
        PATH: "{{ ansible_env.PATH }}:/usr/local/bin"

MVCについて思うこと

MVCってありますよね。Mode,View,Controllerなやつ。

いままで幾つかWebの現場でも、やっぱりサーバ側はMVCフレームワークを使ってるのだが
どうにも上手いこといってる気がしない。

「Controllerは基本シンプルになるはず」論。

アクションを受け取ってModelを読んでViewに渡すだけだ、っていう。
でもさ、表示内容とか、そもそも何を表示するか、ってそんな単純じゃないんだけど。
ユーザやデータの状態で何をどう表示するのか変わってくることもあるわけで。
ってかそこがだいぶ重要なことって多いと思うんだが。

Viewはほぼイコールでテンプレートだ。

テンプレート上であまり複雑な条件を書くと、それはそれは読みづらい。
でも表示制御のために面倒な条件が必要なことはある。その場合は…Controller側でbooleanに変換する?
それともテンプレート上で使えるカスタム関数的なものを、1箇所onlyであっても作ってるのか?

一番微妙なのが、Model。

データとビジネスロジックを持つと言われている。

ビジネスロジックってなんやねん!、って勢いで様々な処理が、もしくは単にDBにselectするだけの処理が
Modelと言われる層に突っ込まれていく。

しかも結局Modelのいち関数は、ある画面専用になったりする。
複雑な条件でデータアクセスが必要なこともあるし、必要な項目は画面によって違ったりする。
それを無理やり共通で使えるようにして、結局中で分岐してるだけな謎コードが出来上がる。

データモデルの設計がちゃんとできていれば、こういうことは起きないんだろうか?
DB設計ではなく、アプリケーションレイヤでの抽象的なデータモデルが。

という感じで

MとVとCは、名前上は分かれているがどの処理をどこに置くかは
個々人のさじ加減になってしまうことが多いのではないかと思う。

そんなわけで、MVCって活きてるのだろうか?
みんなどうしてるんだろう?

プロジェクトのバッファの話

見積もってみたら4ヶ月かかる。じゃ1ヶ月バッファを取ろう。
ということで、合わせて5ヶ月のプロジェクトだ。

さて、プロジェクトが始まって3ヶ月。どうも上手く行っていない。
まだ2ヶ月分の予定しか終わってない。1ヶ月の遅れということだ。

いやホント1ヶ月分バッファとっといてよかったよ。
これが無かったら延期せざるを得なかった。
残り2ヶ月、頑張ろう!

 


   

当然失敗するだろうね、これ。

2ヶ月の見積もりに3ヶ月かかったのが実績である。
残りも見積もりでは2ヶ月分。実績から見れば、これも3ヶ月はかかるだろう。
なのでこの時点で1ヶ月は遅延するという方向で動き始めなければならない。

1ヶ月遅れたのは想定外の問題が発生したからであって、残りは計画通りに行くって?
残り2ヶ月に想定外が発生しない根拠は?

この"残り2ヶ月"は、プロジェクト開始時に行った見積もりだ。
今見積もり直したら、実は3ヶ月となるかもしれない。
そしてさらに"想定外"を考慮すれば、さらに1ヶ月はあったほうが良い。

確かにこの例は、数値が極端だとは思う。
でも、きちんと実績からスケジュールの見立てを立て直すことをしているだろうか?
バッファが吸収してくれたから大丈夫とかやってないか?

「ここまでの遅延は○○だからで、このあとの計画はきちんと精査したから大丈夫」とかいうのは、まず信じないほうが良い。

ウォーターフォールもどき

ん?ウォーターフォールで開発やってる?
へー。どんな感じなの?

は?設計が遅れて製造と一部並行してるって?
なにそれ、もう計画破綻してんじゃん。フェーズゲート機能してないじゃん。
てかそれで大丈夫なんだったら、最初の計画なんだったん?

何?途中でスコープの調整して乗り切ったって?
おいおい、ウォーターフォールってのは決めたものをちゃんと期日までに作り切るのが強みじゃなかったのかよ。

その後も計画練り直したり、諸々調整しつつ課題解決頑張ったら評価上がったって?
なんだよそれ、結局最初の計画破綻してるんだろ?
だったらウォーターフォールとしては成功してないだろ。ウォーターフォールやってるんなら計画に対して評価しろよ。
トラブルないように計画できるのが最上だろうに。

たしかにさ、計画見直したり、都度コミュニケーション取ってさ、みんなで協力してやってくのは大事だと思うよ。

でもさ、もうそれウォーターフォールじゃねーよ。

中途半端なアジャイルもどきだよ。

ロジカルな思考について

最近、論理的思考について思いを馳せることが多かったので、メモ。

対称

よくある「何が問題か」

「問題」があるということは、「こうあるべき」という理想が必ずある。ここは必ず対称的だ。 無いのであれば、それは「問題」ではないのかもしれない。 もしくは、無いからこそ「問題」が表れないのかもしれない。

「問題」に対処するのも大事だが、それと同じくらい「こうあるべき」を考えることも大事である。

階層

よく「○○が出来ていないのが問題だ」っていうのが的はずれだったりする。

これと対称的になるのは、「○○が出来ているべき」ということになる。 で、出来てればいいの?

「○○」をやっているのは、きっと何らかの結果を期待してのこと。 というより、ある目的のための手段である場合がほとんどだろう。

「○○が出来ていないのが問題」というのは、つまり手段を言及しいる。 よく言う「手段の目的化」になってしまっているのではないか?

とはいえ、立場や権限によって、見る「階層」は変わってくる。 大きな組織の「目的」に対する「手段」は、小さな組織の「目的」となりうる。 個人レベルでも同じで、ある「目的」を達成するためには、「手段」を一時「目的」として そこに注力する、ということは必要だろう。

ただし、必ずその「目的」の上には、それを「手段」とする「目的」があることを忘れてはならない。 それが無いのであれば、その「目的」は無意味ということになる。

論理とは常識に基づく

ロジカルシンキング。論理的思考。 実はこれって、「常識」に大きく依存している。

・・・うまい例えが思いつかないけど

人によって「常識」は違う。 ということは人によって「論理」が違ってくるということ。

話が食い違うということは、「常識」がシェア出来ていないから。 うまく話が伝わらないということは、自分の「論理」の間にある自分の「常識」が相手に伝わっていないから。

理数みたいに絶対的なものはない

論理的思考っていうと、何かを分解したりする。 あるテーマに対して要素をあげていって、それが漏れなくダブリがないか、みたいな。

なんとなく、これを難しく考えてしまう。 「こういう観点もある」「これって、こう考えるとこっちと被るような」

でもこれ、絶対的な正解は、無い。

こう考えることは大事なことだろう。 でも、「事柄」に注目して考えてしまうと、迷宮に入り込む。

「事柄」は、見かたによって色が変わるからだ。

大事なのは、受け取り手がどう感じるか。どう伝えるか。 そこに向けて、ただの「事柄」に色を付けていく。

なので受け取り手によって、何が良いかは変わってくるということ。 これを忘れて、迷宮に入り込まないように注意したい。