このページについて
保守開発にほぼ縁がなかったのですが、最近保守開発に携わわることも増えたので、そのまとめです。
普段のシステム保守に関わりはなく、業務知識がないエンジニアが、ある程度まとまった保守開発の案件発足時に開発専門でスポット対応したときに困ったことが書いてあります。
ここに書く困った事案について対応しておくと、スポット対応や保守PJで増員or要員入れ替えで新参者を迎え入れた場合に、新しく入った人が困ることは少なくなると思います。
※保守開発の経験が増えて困った事案があれば、(愚痴にならないようにときにはネタを仕込んで面白おかしく)ここに書き足します。
ドキュメント周りで困ること
単語集がない
新規開発も同じですが、新参者に取ってPJへの途中参加は、日本語以外が飛び交う海外に行くのと同じです。新参者は業務用語が判らないので、業務用語の単語集があると喜びます。
単語集の整備は軽視されがちですが、あると色々と重宝するので整備した方が良いです。
単語集はExcelなどにまとめておくのも良いですが、Redmineの用語集プラグインで管理すると便利です。
同じ業務を表す異なる単語が登場する
ユビキタス言語を整備していない典型例でしょうか。表現のブレは、長年保守をしているエンジニアには判ると思いますが、新参ものにとっては長年システムに携わっている人たちが思っている以上に困っています。
新参者ははじめ設計書を読んでシステムを覚えろと命ぜられることが殆どだと思いますが、設計書上の用語が同じ意味で単語が異なると、いちいち詰まってしまい、設計書を読むだけで疲弊します。(しかも内容があまり入ってこない)
理想は既述の単語集を整備した上で、この単語集上の単語のみを使用して設計書を書いておくことです。こうすることで業務用語は単語集から意味を拾えるのでシステムの理解の進捗具合が格段に高くなります。
全体像をつかむためのドキュメントが存在しない
詳細設計書などの内部処理をこと細かに書いたドキュメントは、業務が判らない新参者にとってはほとんど役に立ちませんし、読むのも苦痛です。そんなものを読むよりもざっくりベースで良いのでシステムの全体像が判るようなドキュメントを読んだ方がタメになります。
細かいことは全体をざっくりでも頭に入れてから読んだ方が、理解が進みます。
メンテナンスがされていないドキュメントを大事にしている
メンテナンスされていないドキュメントはゴミ以上にやっかいなので大切になんてしないで、いっそ捨てて欲しいと思っています。コードもボロボロだとドキュメントは必要ですが、整備されたコードがあるならば、コードを見れば判るのでメンテナンスされていないドキュメントは不要です。ドキュメントがあると、実装とドキュメントに乖離がある場合にどちらが正しいのか、いちいち聞かないといけなくなるためです。(ほとんどの場合、コードが正しいですが、稀にコードが間違っている場合もあるため)
コード周りで困ること
主にJava界隈です
定数がprivate
コードの定義などが各機能でprivate定数で書かれていると、相当萎えちゃいます。
影響調査もしづらくなるので、システムで共通の定義になりうるものは定数クラスを作ってpublic公開しておいて欲しいです。(定数インタフェースでも良いですが、実装の詳細を書くものなので定数のみインタフェースは個人的に抵抗あり。。)
<補足>
privateの定数を使わないで欲しいということではないです。機能で閉じているものはprivate定数で良いです。影響調査などを行うときに使用するようなデータ(区分やステータスなど)はprivate定数で持たれてしまうとコードのGrepで拾えなくなり、影響調査から漏れる恐れがあるので嫌なのです。
個人的には重複した大量の定数を見ると随分と潤沢にメモリを使うんだな、、とは思います。(そして、そういうシステムは全体的にメモリを使いまくっているので、何かにつけて動作が遅いです)
クラス名がID体系
IDでもそのうち判るようにはなるでしょうが(これを見た時点でIDで判別できるようになるまで居たくないと思っているかもしれませんが)、そうなるまでは毎度探さないといけないため、探す時間が馬鹿になりません。そして苦痛。ぱっと見で判るクラス名にリファクタして欲しいというのが本音です。
不要になったコードがコメントで存在し続けている
某書籍などでレガシーコードに認定されるやつです。見づらいし、複数行まとめてコメントされている中の1行だけは有効とかいうのを見落とすなど危険があります。
いらないコードはさっさと消して、いつ消したかはSCMのコミットメッセージに記録しておいて欲しいです。
なんでもExceptionをcatch
すべてのメソッドで例外(しかもExceptionクラス)をcatchしており、処理が落ちたときに上位メソッドにエスカレーションもしないので何が起きたか判らないという罠。
メソッドの引数で渡したオブジェクトが、IN/OUT兼用
例えば検索メソッドの引数に検索条件と検索結果がフラットに並ぶような構造のオブジェクト。どこまでがINでどこからがOUTか判らなくて困ります。
役に立たない文面のログ出力
どこでエラーになったかは判るけど、何で起きたかが不明な文面のログは、自分の使い方が悪いだけなのかどうかも判らないため、人様のコードを読んで解決しないといけなくなります。
C言語でアプリを作っていたときは共通エラーコードを定義しておいて、使い方が悪いのか、内部処理が悪かったのか、データがないだけなのかで切り分けられたのでメソッドの設計思想として良い仕組みでした。(勿論機能特有のエラーコードも存在します。)
Javaでステータスコードでガチャガチャと条件分岐を書いたりするのは流石にアレなので、検査例外を上手く使うと良いと思います。
そもそもログがない
バッチ動かしたら開始と終了しか吐かない(しかも遅いから動いているのか不安になる)という、よくある問題です。(新規開発でも気をつけないと起きます)
ログの吐き過ぎは想像を絶するレベルで処理が遅くなるからダメですが、処理対象件数と100件単位とかで良いので、100件終わったよ!ということをお知らせしてくれるプログレスログの出力はお願いしたいです。
同じ処理がたくさんある地獄
以下は同じ処理で良さそうなのに全部各々が書いているようなものです。
- 画面遷移時に遷移先画面に表示するデータ取得を遷移元がある分だけ行っている
→ 影響範囲が広すぎるため簡単に直せない。内部フォワードするなり一つにまとめて欲しい - ソケット通信のクライアントロジックが色々な箇所にある。
→ ソケットでのデータのやりとりはエンディアンやデータの書き込み方、吸い上げ方など癖があるため全部をそれぞれ行うことは危険だと思っています。
ソケットへの書き込み、読み込みをIFメソッドとして与え、そのメソッド内で書き込み読み込みを行って欲しいものです。
メンテされないテストコード
テストコードがある場合、改造や不具合修正で手を加える前に試しに流して、現在の動作仕様を確認すると思います。
この時にエラーになるテストコードはゴミです。
なぜ起こるかというと、テストコードを一度書いて流して終わりにしているためです。
テストコードをメンテする気がない場合は、従来通りExcelにケースを書いて、テストを実施した方が数段マシです。
テストコードはメンテしてなんぼなので、CIでテストを回してテストコードがエラーになったら即刻修正する運用フローを作りましょう。
個人の意見ですが、定期的にテストを実行する気がないなら、テストコードは書くだけ工数の無駄なので、組織の取り組みとして完全に誤っています。
環境周りで困ること
Aさんのところでは動くのに自分のところだと動かない問題
開発環境構築手順が存在しないため、入れるべきソフトが足りていなかったり、ないと動かないディレクトリが作られていないといったことが殆どです。
プロビジョニングツールで自動化するとか、必要なライブラリはMavenやGradleで自動インポートするとかに変えて欲しいです。(.NETでもMavenとかでビルドできますよ)
設定ファイルが本番用のみで、開発するときはいちいち編集しないといけない
めんどくさいし、本番の設定から開発向けに設定を編集し忘れ、本番同様メールを送信しちゃったとか、実はDBの接続先が本番のままでした、などが起こりうる危険な状態です。
設定ファイルは環境ごとに管理するのが安全です。
Mavenを使うと以下のやり方で、環境別に存在する差分のみを管理できます。
Maven3で環境ごとのresourceを差分で管理する方法
DBが開発者で共通のものを使わないといけない
DBが共通だと周りと連携しながらテストや動作確認を進めていかないといけないため、フットワークが重くなります。特に理由がないならDBはローカルに立てさせて一人一台にした方が良いです。理由があっても一人一台にする方法を画策した方が良いです。
ER図作ってフォワードエンジニアリングしているならば、ローカルにDBを立てることは容易です。
おわりに
ここに記載した内容は保守するエンジニアに向けて、新規開発をするエンジニアが開発中にしてあげられることです。
ここに書いたこと以外でも、「このアプリ、どうやって保守するんだろ。。。」っていうことを新参者や保守チームに思われないように、普段から開発側が「どうやったらアプリ保守しやすいかな」を考えて開発すると良いものができあがるのかなと思います。