オブジェクト指向と脳筋コード~正しいOOPは短いコードでは害にしかならない~

はじめに

オブジェクト指向はもはや一般に広まりつつある。特に、最近ではMVC(Model-View-Controller)やMVVM(Model-View-ViewModel)等のフレームワークでオブジェクト指向を深く理解していなくても、カプセル化された環境でプログラムを書けるようになった。

オブジェクト指向が導入された背景として、関数やGOTO文だけでは手続きの記述にしかならないため、コードが分散されて全体像の見通しが悪くなる、ということがある。オブジェクト指向はコードの見通しをよくするための一つのスタイルでしかない。

仮に、ここでは何も考えず最低限関数化された思考ダダ漏れのコードを脳筋コードと呼ぼう。設計という概念が存在せず、とにかくアウトプットが大事ということもあるだろう。

今回は短いコードに着目して、オブジェクト指向と脳筋コードについて論じようと思う。結論としては、個人が把握できるコード量であれば脳筋コードで書いたほうが技術的負債は軽く済む。

オブジェクト指向の基本スタイル

オブジェクト指向の基本的なスタイルとして、クラス、カプセル化、多態性が挙げられる。この3つの概念はオブジェクト指向を理解する上で極めて重要な概念となる。

まず、システムの全体像を把握し、それらを抽象化してクラスの概念に落とし込む。事前設計はもちろん大切で、設計されていないオブジェクト指向ではコードが無限に増殖する。というのも、ボトムアップで開発するため、抽象化が足りなければ現在いるのはトップダウンなので、一度ボトムアップのための抽象化が必要になる。

事象のほとんどは抽象化しようと思えばいくらでも抽象化できるので、この時点でクラス化の粒度を決めておかないと際限がなくなる。

次にカプセル化になる。オブジェクト指向の背景の一部には、大量のグローバル変数が様々な場所で変更されると、コードのどこを追えばいいのかわからなくなる。カプセル化はグローバル変数をクラス内で局所化し、メンバ変数という形でクラス内に限定するための概念となる。

もちろん、カプセル化するとクラス内で変更が完結されることになるが、場合によってはクラス間のメッセージの伝達によって、クラスの内部状態が変更されることもある。もし、ここでエラーが発生すれば、別のクラスが想定しているメッセージと、当該エラーが発生したクラスにおいて、想定されていないメッセージのやり取りがあると仮定できるため、バグの発生箇所だけでなく仕様の甘い部分を確定する効能もある。

最後に多態性となる。インターフェースや抽象クラス、継承等によって、同じ性質を持つクラスをまとめるための概念となる。よく、犬は哺乳類なので、哺乳類がスーパークラスであれば、犬や猫は哺乳類のサブクラスだという表現がなされるが、多態性は抽象化の中でも非常に重要な概念になる。

もし、多態性を考慮する、ということは、抽象化に取り組んでクラス設計を行うことになる。抽象化できる部分は抽象クラスやインターフェースに追い出し、詳細な実装はサブクラスで行う。

これらをすべて総合するとオブジェクト指向は基本的に設計ありきの開発手法になる。設計がない状態でオブジェクト指向に取り組むと、際限なく変更が生じ、テスト項目も変更される。従って、行き当たりばったりの開発手順を踏むとテスト駆動開発すらおぼつかない状態になりかねない。

脳筋コードでプログラミング

脳筋コードとは、設計のないプログラミングである。かっこよく言うと動的計画法とも言う。ただ、パラダイムとして動的計画法は十分に研究されている分野であり、きちんとした動的計画法は未知の問題に対して非常に有効な手段とも言える。

私は脳筋コードを書くタイミングとして、CSVで書き出したデータをグラフにする程度のところで利用する。他にも、ある問題について簡単な統計手法で何かを予測したいときに役立っている。

とにかく、計画性がなく、欲しいアウトプットに向かって開発するため、あまり頭の良くないコードが量産される。もちろん、再利用性は考慮していない。一方、アウトプットに向かって集中できるため、非常に早く目的のプログラムを書ける

初心者は脳筋コードになりやすい傾向にあり、あまり綺麗なコードを書く余裕や知識がない。しかし、この脳筋コードは最初に誰しもが通る道である。

オブジェクト指向か? 脳筋コードか?

開発レベルでの問題として、詳細な設計を行うか、さっさとコードを書くか、ということよくある。

オブジェクト指向の背景を読み解くと、基本的には設計有りきの開発手法とも言える。つまり、設計があるということは、保守する人が必ずいる、ということである。保守する必要がなければ会話で済ませればいいが、それで簡単にクラス設計ができるとは思えない。

例えば、オブジェクト指向ではデザインパターンを知っているか知っていないかで大きな差が出てくる。CommandやStateなどのパターンを理解していなければ、なぜこのような設計に至ったのか理解が難しい。VisitorとCommandの違いがわからなければ、保守したときに謎のクラス設計になりかねない。

このように、オブジェクト指向では全体像に対する設計の形で実装を進めるため、その設計がはっきりしていないとあらゆる部分で変更が生じる。この変更は短期的な負債としてのしかかるだけでなく、アウトプットまでの道のりを遠ざける要因になる。

一方で、脳筋コードは何も考えずにアウトプットを出すための開発手法になる。設計などは必要なく、手順だけはっきりしているので、一度にたくさん書いてそれで終わり。保守の必要性などは考慮していない。

脳筋コードはオブジェクト指向と比較すると、すぐにアウトプットが出せるという利点がある。しかし、設計という概念がないので保守するのは極めて困難になる。

これらの性質を考えると、どちらが優れているか、という結論には至れない。しかし、どのタイミングで脳筋コードに手を出せるか、という決断はできる。

脳筋コードを書いたほうがいいタイミング

非常にわかりやすく書くとプロトタイプを誰かに見せて、その後は設計の基礎として温存する、悪く言うと使い捨てる。脳筋コードは大規模な開発には全く向かないが、小規模で短時間の成果が求められるときに脳筋コードで書いてもいい。

脳筋コードを誰かが保守すると考えると恐ろしいと思うが、CSVに書き出したデータをグラフにまとめる程度であればクラス設計なんてする必要がない。脳筋でコードを書いてしまっても良い。

だいたい、人が把握できるコード量として500行程度が限度だと思うが、天才プログラマまであれば何千行でもやらかしていいと思う。後日、脳筋コードは捨てられることになるが、それを元に要件定義を洗い直してクラス設計をするならば、プロトタイプとしての功績は十分に残る。

もちろん、タイミング次第でもあるが、すぐに手を動かして出力をしたいなら、設計なんて考えている時間は惜しい。その時間を短縮するために、脳筋コードを書き、温存するか捨てるかのどちらかの選択をすればいい。

脳筋コードに言ってはならないこと

あらかじめ多くの言葉を使って脳筋コードには計画性がなく、誰も読むことのできないコードだと説明したが、その言葉を脳筋コードや作業者にぶつけてはならない。赤を赤だと批判するようなものだ。

たちが悪いのは、プロトタイプで素早く作成した脳筋コードに対して、汚いだとか、読みにくいだとか、罵声を浴びせることである。脳筋コードでフォーカスすべきことはアウトプットであり、その過程を野次るのはエンジニアとして三流以下である

プログラミングをするとき、様々な目的が交差して設計から保守・運用まで行われる。脳筋コードは結果を出すためだけにフォーカスされた手法なので、その過程について問うのは生産性がない。

脳筋コードは脳筋コードで見せられる形として機能しているのだから、その礎として十分な成果を出している。これは保守しやすい設計に匹敵する

納期があと1日しかないので脳筋で書かざるを得ない、という状況もあるかもしれないが、納期に間に合わせるために書いた脳筋コードは非難すべきではない。納期という目的のために書かされたのだから、汚くなっても仕方がない。もし非難されるのであれば、納期が1日しかない状況を作ったマネージャの問題であって、プログラムを書いた本人ではない。

まとめ

オブジェクト指向がいい、テスト駆動開発がいい、等々の様々な開発手法がまことしやかに囁かれているが、時と場合による。今すぐ急いで書きたいなら脳筋に頼るしかないのも事実である。

脳筋に頼るタイミングは時間や成果で加味される。大規模で保守・運用を必要とする部分で脳筋に頼ってはならない。以上。

普段は研究していて生活が厳しいのでサポートしてくれる方がいるととても嬉しいです.生活的な余裕が出ると神が僕の脳に落書きを残してくれるようになります.