プログラミングは芸術である。
プログラミング「言語」というだけあって、
同じ目的だとしても、そこには幾通りのもの書き方があり、
書き方によってはパンドラの箱にもなり、かと思えば美しく書かれたコードは見るものを魅了する。
文章による表現である以上は、書き手の個人が反映され芸術性出てくるのが
プログラミングであり、それは工芸品に近いものである。
だが芸術でありながらも実用面(保守性)が良いものである必要があり
この二律背反が人を悩ませる元なんだろうなと思う。
今回は保守性というキーワードで記事を書いてみようと思う。
背景
はい。
自分の持てる全ての力でポエミーな導入文にしてみました。笑
自分は職業エンジニアであり趣味プログラマー(趣味なら気楽にやれる)でもあるんですが
この保守性の問題で良く頭を悩まします。
自分の中で意識している保守性をあげるための方法を記事にしてみたいと思います。
自分はある程度の大規模から小規模までPJ経験があるのですが、
小規模な場合は自分で開発し、自分でメンテし、自分で機能エンハンスします。
開発時に如何に保守性の良いものを作っておくかで自分のその後の苦しみが大きく変わります。
開発自体の終わりは始まりでしかなく、運用し始めてからが本番というのは
当然のことなのですが、全て自分でやってるとより実感します。
最初に結論を書いておくとやっぱりこれですね。
- クローンコードは悪
- まずは作ってリファクタリング
- C#大統一理論
それでは細かい部分を書いていきます。
保守性の良いコードを書くために
作る前にはプログラムレベルの役割分担図を手書きでも良いので書いてみる
闇雲に作るとコードが分散してクローンができたり、内容が散って修正時に苦労します。
ある程度のコード量が予見される場合は、クラスや名前空間などで固めておくのが良いですね。
オブジェクト指向もこれに似た概念で、近い概念のもの(操作とデータ)はまとめておくことを
体系化したものと言えるのではと思っています。
人間は器用に考えるのは疲れます。考えれば分かるのはNGで素直にわかる仕組みにしておくのが大事ですね。
まずは作ってみてからリファクタリング
いざ作って見るとなんか違うというのは、いくら経験を積んでもあります。
なんだかこのインターフェースは使いづらいな…など違和感ある部分は直したほうがいいですね。
違和感は経験からくるものですので、「まあいっか」はあとで間違いなく燃え上がります。
いきなり完璧というのはなかなか難しいですので、リファクタリングは最初に必ず実施するべきと考えています。
リファクタリングを一度もかけなかったプログラムというのは自分の場合はないぐらいの感じです。
(まあいっかで放置したインターフェースで、後に続々インターフェース実装が増えると辛いことになったりします。)
アジャイル開発な発想に近いですね。
クローンコードは悪
まずは作ってみてからリファクタリングと関連しますが、作りながら似たコードを2度書いたなと思ったらすぐに関数化します。
見通しは悪くなるわ、直すときには複数修正+複数テストになるのでまったくいいことはないです。
世の中にはクローンコード解析といった内容をしてくれる診断サービスなどもありますが
それだけ百害あって一利なしな内容になります。
既存のプログラムで近いものがあるのなら拡張して対応する
「何の影響があるかわからないし」「自分の良く知っているやりかたじゃないし」
といった理由で機能拡張せずに似たコードができると「クローンコードは悪」な状態になります。
デグレが絶対に許されない環境でどうしても…といった場合はもちろんあると思いますが、
後々面倒ごとが発生するので苦しいながらも直すことにしています。
(近年のユニットテスト書くのはこれをサポートしてくれるよい方法だと考えてはいます。)
アーキテクチャは必然がない限り統一する
CySharpのneueccさんのC#大統一理論信者です。笑
C#大統一理論は主にサーバサイドとクライアントサイドの話が語られていますが、
自分としては業務的なシステムの担当が多いため、これに加えて定期、非定期なバッチ処理等も含めて
同じ言語とアーキテクチャで統一することがが良いこと思っています。
(最近バッチフレームワークもリリースしてくださったので、また使わないと!と思っています)
必然性もなくコロコロとアーキテクチャを混ぜていると保守性が超ダウンします。超です。
何故なら同じことをやる関数でも、言語が異なることによってマージできない「クローンコードは悪」が必ず発生します。
他にはよく言われていますが言語理解度が全て高い人員など稀なため、人が減る保守時に大きなインパクトがあります。
担当が作りやすいといった理由で異なるアーキテクチャを使うのは絶対にNGにすべきでしょう。
(恐ろしいことに現実にはこういうのがあったりします。そして保守が面倒で泣きます)
何かの言語や場所に限らず統一するのはいいことです。java1.4あたりの古くから画面と合わせて遅いながらもバッチはjavaで書いてました。
シンプルイズベスト
趣味開発ではトリックコードは好きだったりするのですが、複数人の開発では保守性の悪さに繋がります。
少々のパフォーマンスの遅さや、多少行数が増えてもシンプルに書きます。
他でも言われていたりしますが自分のコードも数年後に自分にとっては「なんやねんこのコード」だったりします。
極力シンプルにしておくことが未来の自分のためでもあるでしょう。
コードの適度な分割
すごく大きいクラス、大きい関数というのは保守性が著しく悪くなります。
プログラミングだけではなく人に伝えること(プレゼンなど)全般にいえると思うのですが、
大きな概念、全体図などから小さな物事へ説明すると、どこの部分か把握しやすく伝わりやすいです。
分類もなくだらっと多くのものを説明されると理解できません。
コードにも言えることで、ある程度分割しておくのは人間の理解しやすい形にすることと言えるでしょう。
このため処理のステップ単位ぐらいでは関数化しておき、コールされる関数を見ていくこと
で内容が想像できるような作りにしておくことが良いと思います。
関連性があるし・・で長くすると後から見通しが悪くて見るのが大変といった保守性の悪いものになりがちです。
まとめ
書き方にフォーカスしたお話になりましたが、いかがだったでしょうか。
ユニットテストも組み込むべしなど別の観点含めみなさんいろいろ思っていることがあるかと思います。
皆さんの意見を聞かせてください!
今回は自分の考える保守性の高いコードの作り方ということで今回は記事を書いてみました。
何かの参考になることがもしもあればいいなと思っています。
※一旦書いてみましたがもう少し加筆するかも