見出し画像

【職人心得】確認しないで次の作業に移るな

こんにちは。ゼバ会です。
本日は、常日頃からクオリティに問題を抱えているプログラマーがやりがちな、誤ったコーディングの仕方をご紹介します。

皆さんは、部下を指導する立場になったことはあるでしょうか。
まぁ、いらっしゃる人も多いと思いますが、イメージは別に仕事じゃなくてもいいです。

たとえば、学生のイベントで自分がリーダーになって、本番前の練習指導をすることになったとします。
内容は、、、そうですね。
仮に「ダンスイベントの練習指導」とでもしておきましょう。
あなた自身は踊れない(or踊らない)んだけど、すでに決まった振り付け通りにみんなが踊れるようになるよう、練習プログラムの作成と練習の監督を務めるわけです。

コンピューターにおいて、プログラムを組む作業は、メンバーを適材適所配置して指導することと似ている面があります。
なぜなら、コンピューター内部で動くメソッド1つ1つは、ある一定の責任を全うすることを義務づけられているという意味では、仕事のプロジェクトメンバーとやってることが同じだからです。
プログラマーであるあなたは、メソッド1つ1つがちゃんと責任を全うできるよう指導する、リーダーというわけです。
ですのでリーダーとしてみんなを導いていく意味では、プログラミングもダンスの練習指導も、守るべき原則は同じなのです。

まずはザックリ説明をして、曲の全体構成やテーマを共有し、振り付け師役の生徒が1人で踊っている動画をみんなで見ます。
それから練習開始。
メンバー全員で、本番同様に踊ってみます。
比較的綿密にタイミングを合わせる必要があるため、メトロノーム役もあなたが行います。

、、、で、ここで問題が出た、とします。

全体的なタイミングが完全にバラバラ。
なぜなら、みんな実はダンスを始めたばかりの素人だったからです!
なんということでしょう!
あと1週間しかないのに!
第2話に続くっっっ! 。。。。と、アニメだったらなるところでしょう。

さぁ、そんなときあなたならどうするでしょうか?
あなたの頭に浮かんだ選択肢は2つです。

選択肢1.とにかく合うまで集合練習を続ける
選択肢2.すぐに個別練習に切り替える

仮に選択肢がこのどちらかしかないとすると、どちらを選べば、わずか1週間で本番に間に合わせることができるでしょうか?

人によっては、「そんなん場合によりけりじゃん?」と思われるかもしれません。
ですが今回のような状況では、選択肢2.個別練習に切り替える が最適解になります。
常に必ずであり、例外はありえません。

なぜか。
選択肢1. に可能性を見出した方は、おそらくは「ダンスステージは互いの協調性が大事」という意識が日頃から強めの人でしょう。
そういう人は、個別練習に切り替えると協調がとれなくなって、余計な時間がかかるように感じるのかもしれません。
ですがよく考えてみてください。

みんなと協調して動くって、本当にそんなに大事ですか?

理屈の上では、(あくまで理屈の上ではですよ?)全員が自分のパートを完璧に踊れば、最悪1度も通し練習をしていなくてもステージは成立するわけです。
なぜなら、メンバー各員は自分のパートをキッチリ踊りきることだけが責任範囲であって、そのメンバー各員を巧く協調させるのはリーダーであるあなた1人の責任だからです。
メンバー各員は、あらかじめ与えられた振り付けを完璧にこなしさえすれば、周囲のメンバーの動きを見て微調整する必要などないのです。

むしろ動きの微調整は振り付け師の責任ですよね。
あくまで理論上ですけどね。

〇 メソッドには、前後のメソッドと正しく連携する責任などない

さて、ようやくですが、この話をプログラミングに置き換えましょう。

人間が人間を指導してダンスステージを完成させる場合、振り付け師やリーダーは完璧ではないので、メンバーにも協調性が求められます。
ですがコンピューターの場合はそうはいきません。

そもそもコンピューターに協調性などありません
あなたの指導(=プログラミング)が全てです。

ということは、以下の2つのプログラミングのうち、より早く仕事が終わるのはどちらでしょうか。

方法1.全てのプログラミングを1度終わらせてから、全体をテストする
方法2.メソッドやブロック1つ1つ単位で製造とテストを繰り返す

もちろんプログラムコードの入力作業が早く終わるのは方法1.です。
途中にテストが挟まりませんからね。
なので納品がタイトなスケジュールの場合、入力をとにかく先に終わらせたくなる人もいるかもしれません。

ですがどんなに急いでいるときも、(むしろ急いでいればこそ)テストや戻り修正の時間も含めた総合的な開発時間は、必ず方法2.の方が短くなります。
なぜなら細かく作って細かくテストを繰り返した方が、発生した問題の原因箇所が狭くなるからです。

方法2.製造とテストを細かく繰り返す方法では、プログラマーは常に「ごく短くてシンプル」なプログラムだけを見続けていることになります。
なので問題が起こった際、修正する前に原因を特定する、という作業が生じにくいのです。問題が起こったら、常に必ずたった今修正した場所が原因です。

これはダンスステージの場合も同じです。
個別練習では、問題が発生しても原因は必ず自分ですから、今のミスは誰のせいだったかの特定をするプロセスが生じません
ですので、スケジュールのタイトな練習では、個別練習の時間をギリギリまで長くする方が効率的なのです。
もちろん、このことは通し練習(結合テスト)をやらなくていい理由にはなりませんが、だからといって結合テストばかりずっとやってても効率が落ちるだけです。

方法2.はテスト時間がスケジュール全体に散らばるため、一見すると手間が増えるように見えます。が、その散らばったテスト時間を全部合計すると、方法1.のテスト時間と比べて必ず短くなるのです。

ちなみにこの原則は部屋の片づけをするときなんかも同じで、こまめに片づけた方が、まとめてやるより掃除時間の合計は必ず短くなります。
試してみてね。

〇 方法2.の開発ができそうな場合の対処法

とはいえ、もしあなたがプログラマーとしてはまだ新人レベルであれば、「そんなこと言われても、、、」という気はしてしまうかもしれません。
なぜなら方法2.は、設計があらかじめできていることが前提となっているためです。

作りながらでないと設計できない人は、どうしても方法1.になってしまうのでしょうか?
とりわけ、莫大な種類の情報を雑多に用いて複雑な処理をし、最終的に1つの結果を作りだすようなプログラムの場合、全部作り終えてからでないとテストできないように感じることもあるかもしれません。

たとえば、ある従業員の労働時間を算出するプログラムについて、必要な入力値が以下であったと仮定します。

1. 本人の出勤データ
2. 本人の勤務予定情報
3. 会社の有給休暇情報
4. 会社の特休制度に関する情報
5. 出向先の会社情報
6. 出向先との労働契約情報
7. 本人の有給休暇申請
8. 本人の特休休暇申請
9. 会社の振休/代休制度情報
10. 本人の振休/代休の取得状況

んで、「何月何日、この人は合計7時間12分の労働をしました」という計算をするだけのために、この10個もある情報を全て漏れなく考慮しなければいけないとしたら、プログラムは絶対にスーパーウルトラミラクルハイパーロングスパゲッティのように、ダラダラ長いものにせざるをえないのでしょうか?

そんなことはないですよね。
そういうときに頭の中をまとめる方法としては、「全部は無理だけどここまでならまとまりそう」と感じるところまでまず設計・製造・テストを全て終わらせて、そっから先はできることを全部終えてから考える方法がまず1つ目。
とりわけ複雑なプログラムでは、まとまりそうな部分の整理を先に済ませてしまうのも大事です。

それからもう1つの設計手法としては、たとえば以下の観点も考えられます。

・人力だけで、何百人分もの手計算を1人にやらせるとしたら、その人にどう指示したらいいだろうか?

コンピューターとは、人間でもできる計算を人間よりも高速に行う装置にすぎず、別に人間にできないことができるわけじゃないのです。
ただ、コンピューターは人間よりも圧倒的に計算が早く、効率度外視の手順書でも文句一つ言わずに従ってくれるため、作り手側もついウッカリで非効率な処理を書いてしまうことがあります。
要は、「こいつならできるだろう」という意識が、ついうっかりで面倒くさい仕事を無計画に振ってしまう理由というわけです。

ですが、指示を出す相手が人間で、かつ、ぶっちゃけ頭もあんましよくない人だったとすると、あなたなら「こいつならできるだろう」なんて無責任な指示の出し方をするでしょうか。
絶対しないですよね?

私の場合、複雑な処理をシンプル化しなきゃいけないときに頭に思い浮かべるのは、実家の母親です。
うちのオカンは、本人には大変失礼ながらぶっちゃけけっこうアレで、以下のイラストを電話だと認識できない系統の人です。

画像1

これを電話だと思えないって、結構ヤバいと思いません?
そういう人も世の中にいるんです。

携帯電話の使い方を教える際、九州にいるお袋に都内から話していたのですが、「電話の絵が描かれたボタンを押して」と言っても意味が通じませんでした。
ヘタすると「シャープボタンを押して」も理解できないかもしれません。

それくらい何も分からない人に労働時間の計算を人力でやってもらうのだとしたら、「多分できるだろう」くらいの大雑把な指示書ではダメなわけです。
当然ながら、かなり細かい指示書でなければいけません。
また、複雑な数学計算式を使うなんて当然無理ですから、順番に1つ1つ確認しながら、かつ簡単な計算式だけで作られた手順書を、私が作ってあげないといけないわけです。

1.自分がいなくなった後でも
2.その人1人で処理ができるように
3.全体は長くてもいいからなるだけ綺麗に整理されたものを
丁寧に作りこんであげます。

で、それをプログラミングするのです。

別の回で、「プログラミングの美しさは思いやりの大きさで決まる」という話をしましたが、思いやりの心でプログラムを組むのなら、技巧を駆使した唸るような凄いコードであるよりも、そのへんのオバちゃんが見ても分かる手順書のような組みかたの方が、長期的にみたメンテナンス性はよくなります。

もちろん、メンテナンス性を重視しすぎて出せる性能も出せなくなるようでは本末転倒なので、そこは案分のしどころでしょう。
ただ、「これくらいなら分かってくれるだろう」という予想はだいたい外れると思っておいた方がよいかもしれません。
まぁ、プログラミングに限らず、世の中大人は分かってくれないのです。
大人なんてそんなもんです。

〇 次回予告

実をいえば今回の話題は、私のお気に入り本《Clean Architecture》の中でも語られている内容です。
具体的にはSOLIDの原則というキーワードが出てくるのですが、これはシステム設計者が持っておくべき心得のようなものです。
(アーキテクチャー設計はかくあるべし、みたいなルールのようなもの)

その中の1つで「単一責任の原則」というものがありまして、これは「システムを構成する部品は、ただ1つの責任だけを負うべき」という原則です。
本日の話題は、その原則を守るための具体的な実践方法だったわけです。

てなわけで次回は、このSOLIDの原則とやらにもう少しだけ踏み込んでいきたいと思います。

「オープン・クローズドの原則」
「リスコフの置換原則」
「インターフェイス分離の原則」

この3つは、SOLIDの原則を構成する項目のいくつかなのですが、実際にはプログラマーがやりがちな1つの行動について、別々の視点から注意を促しているだけです。

つまり、念のためだからって、やたら大量のデータのやり取りをすることを禁止した項目です。
「じゃあ僕は関係ないな。そんなことしないし」

と思ったあなた。
1つのメソッドが複数種の情報を同時に扱った時点でアウト、って言われたら、本当に自信をもって大丈夫って言える?

まぁ、そういうところについて実践的なテクニックのお話をいたします。
お楽しみに!

この記事が気に入ったらサポートをしてみませんか?