![見出し画像](https://assets.st-note.com/production/uploads/images/37346312/rectangle_large_type_2_2d8367c69cd724c1ecbb016393bcea27.jpeg?width=800)
プログラミング言語との付き合い方
このエントリは、Clean Agileの書評を書いてるときに脱線していたら、脱線にしてはえらい長々してしまったので、独立したエントリに分割したものである。なんの根拠も裏付けもないただの私感を垂れ流す。
きっかけとなったのは、ウォーターフォールにソフトウェア開発の動向が支配されていたという歴史的動向をざっとおさらいされていたこちらの記述だった。
我々がウォーターフォールに支配されていた様子は、当時の動向を見ればわかる。1968年にダイクストラが「構造化プログラミング」を提唱したが、そのあとすぐに「構造化分析*7」と「構造化設計*8」がやってきた。1988年に「オブジェクト指向プログラミング(OOP)」が普及し始めたが、そのあとすぐに「オブジェクト指向分析(OOA)*9」と「オブジェクト指向設計(OOD)*10」がやってきた。つまり、「分析」「設計」「実装」の3つのフェーズが我々を虜にしていたのだ。
この話でとくにこの、プログラミング方法の普及に伴い分析と設計があとからついてきたという歴史観に考えるものがあった。
"設計"など抽象的な概念は具象が有るからこそ成立する
「構造化プログラミング」や「オブジェクト指向プログラミング」の普及にインスパイアドされてOOA・OODがあることを考えると、人間の思考は手段・道具に影響されるし、道具があるから思考できるという側面がある。究極人間が物事を区別・認識できるのは言語による区別によるものだというソシュール言語学の考え方があるが、ソフトウェア開発のなかでも道具によって思考できている。
OOPがOOD/OOAに展開されていったのも、OOPという道具が普及したことによって人々が「オブジェクト」という思考道具をメンタルモデルとして手に入れたことが大きいはず。そして、そのオブジェクトは言語における class という文法表現を具体的にイメージできる。抽象度のあげた「オブジェクト」という概念を最終的な仕事における具象であるプログラミング言語で理解できる。抽象的ということは、前提に何かしら具体的なものがつながっていないとそもそも存在し得ないわけで、プログラミング言語という具象によって手に入れた抽象概念といえるのではないか。
プログラマのメンタルモデル
プログラミングと言う行為、ソフトウェア設計という行為に対して、とある"なぞの人"さんは「ソースコードは人間が読むコンピュータの操作手順書」と評していたが、究極はそうだなと思う。また、「誰のためのソースコード?」という新原さんのブログポストでは、ソースコードと概念モデルを整理した上で次のように考察を締めくくっていました。
ソースコードは、コンピュータをどう動かすかということを示すものですが、これを書くのも読むのも人です(今のところ)。つまり、人がソースコードをどう理解するのかという視点はソフトウェア開発の現場では重要なことです。
ともするとプログラミング言語との付き合い方は、その言語を使う人達な標準的なメンタルモデルに沿ったソースコードであることが必要とされる。とあるぶどうぐみさんは、Goらしさとは何かを考察されていた。
Goらしさ自体の背景はとてもまとめられているのでぜひGopherの方々は一読あれといった感じだが、なぜそもそもGoらしさとは何かを考えることが大事なのか?
Goらしさを体現したソースコードとすることが、標準的なメンタルモデルと一致した可読性の高いソフトウェアになる、という構造がこの言語を取り巻くコミュニティのあり方として存在するからなのだろう。そして言語ユーザーの標準的なメンタルモデルによって理解しやすいコードだからこそ、人員の増加などに耐えうる事業としてスケーラビリティを得ることができるのだろう。
JavaであればEffective Javaという教典がプログラマーの標準的なメンタルモデルになっていて、それに沿ったコードのあり方にすることがソースコードのデザインとして重要となる。PHPであればなんやろな...なんやろな...。
さまざまな要因がメンタルモデルを形成する
『Goらしさxxx』のブログエントリでは、Goらしさについて考察する中で次のようにも反証している。
とはいえ、Goらしさに固執することで生産性が落ちるならば本末転倒なわけで難しい。
Web開発ではDDDやクリーンアーキテクチャなどの考えやgRPC、OpenAPIやWebフレームワークを採用することもあるだろう。
"Goらしい"ソースコードのあり方・付随するコンピュータの実行モデル(並行性モデルであるCSP: Communicating Sequential Processesとか)が、それらと競合することはまぁ有るだろう。SOLIDの原則ですら同じパッケージなのにそれらをすべて同時に満たせないことは多い。
抽象度の高い設計原則も、現実のソフトウェアエンジニアの人間活動を考えると手段・道具が前提に、使う道具との塩梅を考えた上で行わないといけない。つまり、ソフトウェアエンジニアにとって影響を受けるメンタルモデルは、プログラミング言語だけにとどまらないということだ。
事業がどういったものなのかという事業ドメインにも影響を受けるし、はたまたクラウドコンピューティングなどインフラストラクチャの具体的なサービス・機能が「できること」が脳内に制約を与える。
プラグラミング言語を極めた先...?
プログラミング言語を極めたからと言ってソフトウェアの最終的な成果物が費用対効果の高い優れたものになるかと言われると unclear 。逆もまたしかりである。プログラマーという役割になる瞬間がある以上、そこでは言語に大きな影響を受けた人間のメンタルモデルが介在する。
プログラミング言語の習熟やユーザーとしての熟練を目指すことよりも、より抽象度の高い設計・分析を志向したい人がいる。しかし、現実のソフトウェア開発でメンテナブルで費用対効果が高く事業の成長をドライブするようなシステムを作りたい場合、それを実行していくのが人間であるソフトウェアエンジニアでありプログラマーであり、"メンテナブルで費用対効果が高い"ためには彼らにとってのデザインを考えねばならない。
そこにはプログラミング言語は仁王立ちしており、プログラマーの一番の道具として彼らのメンタルモデルを形成・支配する。
チーム開発におけるプログラミング言語
チーム開発においては、コーチングとティーチングの両方の側面が有る。たとえば、Javaコーダーだった人がGoを書きますといった場合には、いったん unlearn して貰う必要がある。そうでないと標準的なメンタルモデルの王道から大きく外れるからだ。こういったシーンでは「先輩社員」がジュニアにコードレビューなどを通して伝達するティーチングプロセスになるだろう。
一方で、標準的ないわば Must を抑えた先にある複数の選択肢があったり、別の概念との競合が発生した場合そこには独自のメンタルモデルの形成が必要になる。つまり、「私達にとって理解しやすい・私達が扱いやすい形はなにか」をデザインするのだ。ある程度成熟した開発者の少人数チームであれば「要はバランス」をどこに取るかという議論をすることになるだろう。
Goプロジェクトにおける向き合い方として、「Goらしさ」にメンタルモデルを振りに行った上で、コンフリクトを起こしている別の概念が具体例にある場合に、そのコンフリクトの解消方法を「Goらしさ」によせるのか別概念の有用性をチームで合意した上で型を崩す判断が考えられる。
ユビキタス言語を形成してプロジェクトで同じ言葉を使えるようにするように、プログラミングチームとしてのメンタルモデルを、ある種コーディング規約・方針などによって確立せねばならない。
"標準・基本"を学び続けるインセンティブ
たとえば、Goらしさをチームとして大事にして共通のメンタルモデルとして身につけていこうとしたとする。そすると、世界のGopherたちが何を考え実践しているかを知り続けるインセンティブが生まれる。
世の中は一つの言語をとっても日々変わり続ける世界の中で能動的な学びをやめるのは致命傷だが、どういうメンタルモデルを生み出そうとするかを規定すると、学習する姿勢に大きな影響を与える。
これは、フレームワークを採用してそれを活用し続けるチーム方針とした場合もおそらく同じもの。ここから考察されることは、言語らしさという要素が内部から生み出されない外的要因であるが、それを選択するという判断したからにはその選択した判断を自分たちにとって正解にし続ける努力をするという合意に相違ないということだろう。
プログラミングのメンタルモデルを形成するアプローチ
現実世界で格闘してきて、20人以上とかになりチーム分割されたモノリスステムでのプログラミング、そこでは具体的にPHPだったが、これは対話プロセスやボトムアッププロセスは相当難儀なものがあった。文化浸透が難しいため組織構造をハックしてマネージャー陣をうまく巻き込み、一つの価値形成をしていくなどなかなかな労力だ。
そもそもMustな部分で振る舞いをみなしてもらうケースだってあるだろう。言語思想とマッチしない実装や、現在のバージョンを使ったプログラミングが習得できてない(ex. PHP7のコーディングとPHP5以前は結構異なる)場合、トップダウン的にUnlearnを強制したりlinterによる機械的指摘がアプローチとして取られる。
コードレビューはティーチングの場にはなるが、協議して価値形成をしていくには、別の場が必要だと経験上思う。それが輪読会や読書会、コードリーディング会といった勉強会の価値だと思う。それらのイベントを通してチーム共通のメンタルモデルを形成していくのが手になるだろう。
この記事が気に入ったらサポートをしてみませんか?