SI開発におけるコードの品質について
自分で開発がしたくて事業会社に転職したのに、最近何故か大手企業からの受託開発でSIっぽいことをやっています。あら不思議。 いわゆるウォーターフォール型の開発で、工程ごとにがっつり何回もレビューをやるやつです。 私の会社は大手企業からの一次受けで、主にPM的な業務を行い、実際の開発は協力会社さんにお願いしてシステム開発を行っています。
レビューによる品質確保
大手案件だけあって、とにかくレビューがたくさんあります。ドキュメントもかなりしっかり設計書をそろえる必要があり、その多量のドキュメントに対してレビューを行います。 ドキュメントの版数管理もきっちりされて、要件定義、外部設計においてはかなり入念なレビューが行われます。テスト件数、バグ率なども開発規模に対して指標があり、当然そのあたりもレビューされます。 面倒な部分はありますが、エンジニアは放っておくとドキュメントを作らなくなりがちなので、これはこれで必要な作業かと思います。 何を作ることに合意したのか、正しい仕様は何なのかというのをしっかりドキュメントとして残しておくことは必要です。
正直言って、今回のプロジェクトにおいて外部設計までのドキュメントは複数回の入念なレビューを経てかなり良い品質で仕上がっていると思います。 一方で、製造工程のレビューに関しては開発会社内でちゃんとやってればいいよというちょっと緩いスタンスになっています。
顧客の求める品質とは
さて、こういったSI開発における品質の良さとは何でしょうか。 それは、要求仕様がすべて満たされており、設計仕様通りに動作し、スケジュール通りに納品され、稼働時点で不具合がないことと考えられます。 またテスト工程において規定のバグ検出がなされていることをもって製造の品質を担保しているように見えます。
品質の落とし穴
さて、そんな開発の中で私は今製造工程において社内レビューを行っています。 協力会社さんから納品される成果物は、外部設計に定めた仕様通り動作しており、不具合もありません。 単体テストのバグ検出率などもまぁまぁ問題ない範囲でしょう。
しかし、コードに関しては控えめに言っても糞コードが出来上がっています。 例をあげると
- 定数を使わずコードに数値リテラルを直書き
- メソッド名と処理内容が合っていない
- 循環的複雑度が50を超えているメソッドがある
- 色んな情報を詰め込んでグローバルに持ち運ばれるオブジェクトがある
- javascriptのフォーマットがイマイチ(セミコロンありなし混在、インデントがおかしい)
- javascriptがちょっと危なっかしい(未宣言変数の使用、グローバル変数多数、ところどころscriptタグの中に直書き、比較が全部"==")
といった具合です。
自分が保守担当になったら絶対に触りたくないコードです。
いつリファクタリングすべきか
糞コードではありますが、顧客の求める品質は満たしていると言えば満たしています。 仕様通りに動作し、バグがありません。
私がコードレビューでいろいろ指摘して修正することは、顧客の求める品質に対しては工数の無駄かもしれないし、逆に今は存在しない新たなバグを生んでしまうことになるかもしれません。
一方で、こういった大手ユーザーのシステムは、一度本稼働してしまうと修正がとても難しいことも知っています。どんなに糞コードでも、とにかく今問題なく動いているものを不用意に修正することは許されません。リファクタリングは今存在しない新しいバグを生んでしまう原因になるからです。
その結果、保守工程では保守性の悪いコードに微修正を少しずつ加えていく形になり、結果不具合が発生するものの、全面的に作り直す工数ももらえず、延々不具合を生み続けることになるのです。
だから、リファクタリングするなら今やってしまうのが一番良いと思っています。
すべては自分の我儘かもしれない
会社の利益を一番に考えるなら、ここではリファクタリングをしないほうがいいのかもしれません。ここで厳しくコードレビューすることで、今のプロジェクトメンバーには当然負荷をかけ、苦労することになります。正直言って、ここまである程度スケジュール通り順調に進んでいたプロジェクトが、私のコードレビューのせいで確実に炎上プロジェクト行きでしょう。 今のプロジェクトメンバーが地獄を見るか、見たこともない運用保守担当が地獄を見るか、その選択になるかもしれません。
炎上させてまでこれを直す必要はあるのか。仕様通り動いているんだから納品してしまえば一緒じゃないのか。今自分達が頑張る必要はあるのか。お前は誰の味方なんだ。お客様第一の前にプロジェクトメンバーのことを考えろ。PMがコードにまで口を出すのはおかしいんじゃないか。
いろいろ考えましたが、コードレビューはしっかりやることにしました。 プロジェクトメンバーからは文句を言われそうですが、やはりこれを納品することはできません。
この失敗の原因は、もっと作り始めの初期段階でコードレビューをしなかったことだと思います。そう考えると、やはりプロジェクト計画をしっかり立てられなかった私の失敗です。 プロジェクトメンバーのみなさん、申し訳ありません。
教訓
コードレビューは製造を始めた初期段階でやりましょう
私がApple(というかiOSアプリの開発)を嫌いになった理由
私はどちらかというと、生まれも育ちもWindowsなのでMacともiOSともほぼ無縁の生活を送っています。
しかしながら、仕事でほんの少しだけiOSアプリの開発に携わる機会がありました。そしてそのほんのわずかな関わりだけでiOSの開発がとても嫌いになってしまったので、その理由を記載します。
ただし、私はどちらかというとWindows信者寄りなのでその分は差し引いて読んでもらったほうがいいかもしれません。
一言で言うと「開発者泣かせ」です。
XCodeで編集したら勝手に保存されている
これは慣れの問題かもしれませんが、一般的なWindowsソフトであればちょっと設定を変更したり、コードを少し変えたりしたけどやっぱりやめたいという場合、保存せずに終了したら保存されません。しかし、XCodeの場合、編集した時点でデフォルトで保存されており、キャンセルしたい場合は明示的に変更を取り消す必要があります。
これで一番困るのが、XCodeが何らかの事情でフリーズした場合に、とても中途半端な状態で勝手に保存されていることです。もはや最初の設定がどうだったかもわからないし、一度XCodeを終了してしまったので、元に戻すこともできないという状態に陥ります。
え?バージョン管理ソフトを使っていれば問題ない?
・・・はい、それは完全にその通りです。文句言ってすみませんでした。
XCodeをバージョンアップしたらビルドが通らなくなる
これはどちらかというとSwiftの問題です。 Swiftは基本的に後方互換のないアップデートを行います。さらに、新しいXCodeでは古いSwiftがビルドできなくなります。
そのため、何らかの事情でほんの少しだけ手直ししたい場合でも、XCodeおよびSwiftのバージョンがあがっていると大幅な修正が要求されます。 頻繁に継続アップデートしているアプリならまだしも、一度リリースしたら滅多なことでは触らないようなアプリの場合、メンテナンス負荷が異常にあがります。
これが本当に殿様商売すぎて嫌です。開発者の労力を何だと思っているのか。こっちは趣味じゃなくて仕事でやっているので、できるだけ本質的でない部分にはコストをかけたくないんです。それなのに後方互換を切り捨てるせいで、本来やりたい変更とは別のところでコストが発生します。
アプリの審査
人力でアプリを審査することが必要な理由がわかりません。 システムで自動的に一定の基準をもって審査するというのであればよいと思います。
しかし、人が審査するので以下のような問題点が発生します。
- 1回目に指摘されなかった内容が修正して再提出したときに指摘された
- 割り当たった担当者によって指摘してくる内容が違う
(バージョンアップして再審査に出したときに前バージョンでは指摘されなかった内容が指摘される) - 審査にかかる時間が不明確
- 人とのやり取りが発生するので、差し戻されると返事を1往復するだけでもそれなりの時間がかかり、リリース計画が立てづらい
しかも、人手で審査している割には世の中に出回っているアプリには結構課金詐欺アプリみたいなのもたくさんあります。
本当にその審査必要ですか?
ベンダーロックインしまくっている
どのメーカーも多かれ少なかれベンダーロックインはあるんで構わないんですが、iOSだと比較対象がAndroidになってしまうのでどうしてもこういう感想になっちゃうんですよね…。
頻繁にディスプレイサイズを変えてくる
OS側で吸収して調整してくれればいいんですが、アプリの実装側で調整が必要というあたりがどうにも気に入りません。
しかし実装方法次第ではOS側で吸収してくれる(?)ようなので、実装側の問題もあるのかもしれません。
iPhoneX対応してなくても審査通してくれるなら問題ないんですけどね!
以上、完全にただの愚痴でした。
コミュ力が低いエンジニアが会議の主催を乗り切る方法
はじめに
SIに限らず仕事と切っても切り離せないのが会議の存在です。SEでなくても、プログラマでもインフラでもサポートでもテスターでも、ずっと働いていて会議や打ち合わせをしないということはないでしょう。お客様と会議することもあれば、社内メンバや委託先の人と会議することもあるかと思います。
私はあまり喋るのが得意ではないのですが、私を含め喋るのが苦手というエンジニアはそこそこいるのではないかと思います。 しかし喋るのが苦手だからと言って、会議を避けていては話は進みませんし、無策で打ち合わせに突入すると「何の成果も!!得られませんでした!!」と帰還するはめになることは受け合いです。 (※稀に参加者に恵まれると成果が出ることはあります。)
そこで、私が数々の無残な敗北から学んだ喋るのが苦手なエンジニアが会議を乗り切る方法をメモしておきたいと思います。主に自分が会議を主催する場合の話になります。
会議の準備
会議に臨む前に、心の準備と資料の準備が必要です。
1. 会議の目的を明らかにする
ゴールがぼやけていると、何を話せばいいのかわかりません。自分が何を話せばいいかわかっていないということは、当然他の参加者もわかりません。なので、最初に会議の目的をはっきりさせます。 会議の目的は大きく分けて下記3つに大別されます。
- 情報を伝えること
- 情報を引き出すこと
- 何かについて決定・合意すること
どのカテゴリの会議か切り分けられたら、さらに目的を詳細化します。 (混ざっている場合もあります。)
目的が「情報を伝えること」の場合
この場合、誰に何の情報を伝えたいかをリストアップします。 あわせて情報を受け取った人にどうしてほしいのかを考えて一覧にします。
目的が「情報を引き出すこと」の場合
この場合、自分が知りたい情報をリストアップします。 その上で知りたい情報を得るためにはどのような質問をすればよいかを考えて一覧にします。
目的が「何かについて決定・合意を得ること」の場合
この場合、誰と何を合意・決定したいのかをリストアップします。
その上で合意・決定するための質問を考えて一覧にします。
例:「~で進めていいですか?」
「AとBどちらにしますか?」
2. 会議の資料を作る
会議の目的ははっきりしたし、喋る内容も考えました。
しかし、作戦を立てただけで勝てるほど世の中甘くありません。 トークが苦手なエンジニアが資料なしで会議に臨むのは、丸腰で巨人に戦いを仕掛けるのと同じことです。
手順1ではっきりさせた目的を元に会議資料としてまとめます。 私が考える資料作成のコツは下記の通りです。
適度に行間を空けて大き目の文字で書く
会議に老人が多い場合などは、字が小さいと字を読むほうに力を使ってしまい、肝心の会議内容へ割く力が減ってしまいます。文字は大きく読みやすく、会議の参加者に負担をかけないようにします。
できるだけ短い文章で表現するように努力する。
長い文章は主張が曖昧になり、読みづらいです。できるだけ短文を目指します。 接続詞を使いたくなったら、一度文章を切ってわけてしまうとよいです。
平易な日本語を心がける
イケてる横文字を使うと頭が良さそうに見えるかもしれません。あるいは専門的なエンジニアらしく見えるかもしれません。 しかし、会議の目的は頭の良さや専門性をアピールすることではありません。できるだけ万人が理解できる簡単な表現を使います。書いてある意味がわからなければ、その文章はただの模様です。言うなれば、紙にこぼしたコーヒーと同じです。
必然性のない絵やアニメーションは入れない
絵やアニメーションで注意を引いたり笑いを取るのは上級者のテクニックです。トーク力に自信がない場合は使わないほうが無難です。
質問は答えやすさを考える
質問するときはできるだけ「YES/NO」で回答できる質問にします。人間これが一番答えやすいです。 YES/NOで回答できる質問をある程度繰り返して内容を絞った上で複数の選択肢や自由回答の質問をすると論点が絞りやすいです。 次点で選択肢の中から選ぶタイプの質問、それも無理なら自由回答する質問にします。
テストの問題の答えやすさと同じようなものです。〇×問題は回答しやすいですが、自由記述問題は回答が難しいです。
選択肢を示すときは判断材料を一緒に提供する
仮に自分がその質問をされたら、何をもってYES/NOを決断するのか、何をもって選択肢を選ぶのかを考えます。 そう考えたときに判断材料がなくて決めかねると思ったら、質問した相手もだいたい決められません。 判断材料として選択に付随するメリット、デメリットなども一緒に提示するようにします。
自分がわからない内容が判断材料であれば、何がわかれば判断できるのかを考えます。そして判断材料となる情報を相手から引き出すための質問も一緒に考えておきます。
選択肢や質問に対して自分はどう思うのか考えておく
自分自身がどちらの選択肢がよいのか、どう回答すればよいのかわからないような質問は、相手もわからないことが多いです。 仮に自分だったら質問にどう回答するかということは事前に考えておき、相手が回答に困っているようであれば「例えば私であれば~」のように補足説明することで、話が分かり易くなりますし、場合によっては自分に有利な回答に誘導することができます。
依頼は期限を明確にする
よくある失敗ですが、依頼したもののいつまでたっても対応してもらえない、挙句の果てには忘れられていた、ということがあります。会議で物事を依頼するときは、明確に期限を切らないと対応してもらえない可能性が高まります。さらに期限を明確にしていないと督促もしづらくなります。依頼には期限を設定するようにします。
会議の進行
準備が完了したら、後は当日資料に沿って進めるだけです。 トークが下手でも資料通りに進めれば、だいたい目的は達成できるかと思います。 しかしながら、注意しなければならないことがいくつかあります。
1.制限時間を意識する
会議の時間は有限です。時間内に目的を達成するためには一つの話題にどれぐらいの時間がかけられるかは考えておく必要があります。白熱した議論が予想されるものは最後に回し、スムーズに進みそうなもの、もしくは重要度の高いものから先に処理してしまうのがよいです。
2.話題が逸れたら軌道修正する
よく会議の最中に話題が違う方向に逸れていくことがあります。そのまま放っておくと、全然違う話で会議の時間の大半が消費されてしまったということになりかねません。話が脱線して1-2分で終わらないようなら、無理矢理本来の話題に戻します。
「それはまた別のところで議論するとして…」
「その話は長くなるので…」
「まぁ一旦それは置いといて先にこの話を…」
とか適当に割り込んで止めてしまいましょう。
偉い人が相手なら
「すみません!申し訳ないですが今日はこの話を…」
とかそんな感じで。
3.時間がかかりそうな話題は持ち帰りも検討する
その場で決まりそうにない話題は持ち帰って検討してもらうことも考えます。 その場合、いつまでに決めてほしいのかははっきりさせておきます。
議事録の作成
遠足は家に帰るまでが遠足です。 会議は議事録を関係者に送りつけるところまでが会議です。
ぶっちゃけほとんど覚えていない
会議の参加者の8割は、翌日になれば会議内容の3割程度しか覚えていません。
1週間もたてば、下手すると会議があったことすら忘れ去られているかもしれません。
「なんだ夢か。」
会議の成果を参加者に示す
そこで、会議の中で達成した目的を議事録という形で参加者に周知します。
議事録には下記2点を記載します。
- 会議の目的としていたことで、達成した内容を記載する。
- 宿題がある場合は、誰(グループや組織でもよい)がいつまでに対応するのかを明記する。
他の議事経緯などはおまけです。 上記の内容をまず書いて、細かい議事内容が必要であれば、そのあと書いておきます。
自分に有利な議事録を作成する
ちょっと裏技です。
議事録というのは恐ろしいもので、多少会議の内容と違うことを書いても多くの場合気づかれません。 特に会議内容の一部を議事録に記載しなかった場合でも指摘されることは稀です。
参加者のほとんどは後になって議事録を見るころには会議の記憶は薄れており、そういえばそうだっけなーぐらいの感じになります。
そこで
- 自分に不利な内容はある程度の裁量で議事録に記載しない。
- あまり重要でない内容であれば、その場で決まったことにしてしまう。
というアプローチをとることで、かなり自分に有利な会議内容だったことにすることができます。 これが本当に効いてくるのは、何か月もたって、そういえばこれどうなったんだっけ?などと過去を振り返るときに効果を発揮します。
「それは〇月×日の打合せで決まりましたよ。議事録見てください。」
「うーん、それはまだ検討してませんね。過去の議事録を探しましたが、どこにもありません。」
タイムマシンがなくても、いとも簡単に過去を改変することができてしまうのです。 ただし、過去改変しすぎると未来を破壊する可能性があるので注意して下さい。
当然、議事録を周知したタイミングで「内容が漏れてます。」とか「認識が違います。」とか指摘が入る場合があります。その場合は素直に「申し訳ありません、内容が漏れていました。」とか「記載が誤っていました。」と言って訂正します。
おわりに
苦手なことをやらざるを得ない場合は入念な下準備と対策が必要です。
他の人が息をするようにできていることが自分にはできないのはなかなかつらいものです。 しかし、ある程度時間をかけて努力すれば一般的な人に近い水準までもっていくことは可能です。
トークが苦手な場合は、しっかり下準備してから会議に臨むことである程度の成果は出せるようになります。 会議をうまく乗り切って楽しいエンジニアライフを過ごしましょう。