クラスに変更が起こる理由は、一つであるべき。Principle)クライアントは自分が使わないメソッドに依存することを強制されない。クライアントから見えるべきで、他のメソッドには依存したくない。最小にして、変更の伝播を最小限に食い止めたい。ISPは「インターフェイスをクライアント毎に分離しよう」という原則なのです。氏も同じような話をしています。リファクタリングのコストが高くなるので、早い段階で分割を進めてしまうという理由があるからではないかと指摘しています。対しては、強力な型システムがあることによって、これらの懸念を払拭できるため、先走りのモジュール分割を避けることが出来るというわけです。実際に、Elmでは一つのファイルやモジュールが大きくなることについて、他の言語(特にオブジェクト指向言語)よりも寛容であるということがよく言われています。そもそも適切な抽象化が難しいのに、その抽象化が有用であるという証拠が揃わない内に分割を進めてしまうと、より不適切な分割をしてしまう可能性が高くなってしまいます。先走って分割したモジュールが、後々の状況変化に対応できなくなって、例外条件に対応するコードが増えて行き、そしてスパゲッティ化していく過程というのはシステム開発の現場で働く多くの人が目撃しているのではないでしょうか。abstraction「間違った抽象化よりも、コードの重複の方を好む」ということで、長らく信奉されてきたDRY原則への挑戦がここでは行われています。abstractionそして、偶然なのか何なのか、これも同じ8月に、オブジェクト指向における抽象化がなぜ難しいかというのを良く表している大変興味深い記事を見つけることになります。~何のために、「データとロジックを一体に」するのか?~カプセル化することが自己目的化していて、何のためにカプセル化するのかという視点が極めて希薄なことです。その結果、「うまいカプセル化」「まずいカプセル化」の区別がない、という状況に陥っています。...本来は、値引き判定のロジックをどのオブジェクトに配するかを決めるにあたって、どのような知識を隠蔽すべきか、あるいは裏返して言えば、どのような知識は開示して構わないかという点に思いをめぐらすべきでした。...解決策は、「データとロジックを一体に」という、どちらかというとゲームのルールのような具体的で単純なルールから視点を引き上げ、「情報隠蔽(=知識隠蔽)」のような、より本質的な、目的志向的な設計原則に立ち帰って考えることです。この記事の要旨は、増田亨氏の「現場で役立つシステム設計の原則」という書籍で紹介されているオブジェクト指向のコード例について、「データとロジックを一体に」というオブジェクト指向の表面的なルールに囚われ過ぎて「何を隠蔽して何を表に出すのかという設計判断」を蔑ろにしているという指摘です。この記事を読んで個人的に思ったことは、設計判断の根拠となる「スコープが適切でない」ということを、後から文脈をズラすことでいくらでも言えてしまうというのが問題の本質じゃないか、そこに「データ・ロジック一体型設計」の限界があるということなのではないか、ということでした。Abstractions」という、2002年に書かれた記事に出てきます。なった時にかかるコストというのは、抽象化がなかった時よりも高くついてしまう可能性があります。隠蔽された部分の知識も結局のところは必要なのだとなれば、抽象化された部分と隠蔽された部分の両方の知識が必要になるからです。togetherオブジェクト指向の問題点を指摘する場合、一番厄介なのは、オブジェクト指向に定まった定義がないという事実です。このブログでは以前、オブジェクト指向の歴史を遡って、あれってそもそも何だったのかということについて検討したことがあります。ゆびてく歴史的な経緯から言えば、オブジェクト指向を発案したアラン・ケイ氏が言うところの「メッセージング」が、オブジェクト指向の本質だということなりそうですが、一般に普及した「オブジェクト指向言語」と呼ばれるもので、メッセージングをサポートしているものはほとんどありません。きっかけに流行した「抽象データ型」を起源とする流れが、一般的に認識されているオブジェクト指向だと考えて差し支えなさそうです。氏によれば、一般的にオブジェクト指向の強みだと思われているほとんどの要素はオブジェクト指向固有ではなく、オブジェクト指向固有の強みなど、実際には一つもないそうです。Companyすんごく長いけど一読の価値あり。オブジェクト指向固有でないものを除外していくと、最後に残るのが「データとロジックを一体に」という先ほどのルールです。このルールがオワコンになりつつあるのではないかというのが、この約1年間、Elmでプログラミングをしていて実感するようになったことです。関数型プログラミングをしていると、データとロジックが分かれていることのメリットを実感する機会が度々あります。アプリケーションにはアプリケーション固有の複雑さというものがあって、それらは多くの場合、必要な複雑さである場合が多いような気がしています。オブジェクト指向では、データとロジックを一緒にしなければならないという制約のために、それらの例外的だと思われるケースを捨象して、現実に即さないモデルに(強引にでも)落とし込むことになります。オブジェクトに関数が結びついているからこそ「このメソッドはこのオブジェクト構造を処理するためのものだ(他の用途には使えない)」という風に専門化できていたんであって、データと関数を個別のものと扱う以上は、「この関数はこのオブジェクトだけを扱う」という前提を置けないのです(当たり前です)。あるオブジェクトと別のオブジェクトが、型であったりクラスであったりが異なったとしても、関数は、そのオブジェクトが、関数の処理できる構造であれば、処理できるべきなんです。関数とオブジェクトが独立しているというのはそういう意味であるべきです。あれば、すべての関数にまたがるような、共通の汎用データ構造があって、すべてのデータはその汎用性を担保してたほうがいい。氏が、彼のオブジェクト指向批判の中で、「オブジェクト指向とは、つまりモデリングなのだ」と喝破していますが、複雑な事象を分かりやすい用語(ターム)の集合に落とし込めるという先入観が、アプリケーションレベルの複雑性を扱う時に明らかな障害となって現れるケースが多くなっているような気がします。メッセージングが今のオブジェクト指向と関係ないのだとすれば、「データとロジックを一体に」がオブジェクト指向の核心になりますが、そうだとすれば、オブジェクト指向自体がオワコンだという結論になってしまいます。それはどうもそうっぽいという感じがしているのです。makingここからは少し余談になりますが、以上のような気づきを得た上で、過去のオブジェクト指向批判の文章を読むといちいち首肯できることが多くて困ってしまいます。オブジェクト指向というのは、オブジェクト指向にしかない問題を作り上げて、それを解決するためのツールを作るというマッチポンプ的なことをしてお金を稼いでいるという話があります。Armstrong(さっきのバナナの人)あるいは、オブジェクト指向ではそもそも過剰な複雑性を作り込んでしまう傾向があるという批判があります。いえば、オブジェクト指向には、インターフェースに対してプログラミングするという考え方があるので、プログラムは自然にレイヤー構造になっていくからです。「コンピュータサイエンスは、間接層(indirection)を設けることであらゆる問題が解決できるという信念に基づいた学問である。DeBruler」とあったりしますが、しかし、間接層はもろ刃の剣であることに注意しなければなりません。1つのものを2つに分割するということは、それだけ管理しなければならない部分が増えるということなのです。オブジェクトが、他のオブジェクトに委譲を行って、その先もさらに委譲を繰り返すような場合、プログラムが読みにくくなるのも事実です。間接層は、最小限に絞り込むべきなのです。言え、実際には過剰なレイヤー構造になっていることが多いような気がします。enough」や「YAGNI」なんてことが言われるようになりましたが、今を思えば、これはオブジェクト指向の側にそもそも過剰な複雑性を生む性質があったために、わざわざ言わなければならなくなったことのようにも思えてきます。Companyこれはまさにオブジェクト指向にしか存在し得ない問題を、比較的大掛かりに解決しようとした例の代表だと言えそうです。氏に批判されています。流れで、いよいよオブジェクト指向に対する懐疑心が無視できないレベルに達した2017年冬。組織やチーミングの話を追いかけてると、どうしてもプログラミングは基礎教養なんだって話に辿り着いてしまうな。認知バイアスなのかもしれないけど。2016例えばDevOpsは、DevとOpsを密に連携させようという話、というよりも実質は、インフラはソフトウェア化したからプログラミング出来ないと話にならないよという話だったりする。2016あるいは、コンウェイの法則も裏を返せば、ソフトウェアの構造が組織の構造に影響を与えるという話。2016まさにそんな感じの話がInfoQで紹介されていた。Ithttps://www.infoq.com/news/2016/10/conways-law-spring-oneプログラミングが単にコンピュータを動かすための命令を書くことだと捉えるとこの視点は出てこないけど、プログラミングというものは結局コンセプトを定義する事なのだ(デザイン)と捉えれば、プログラムを書く事も組織を設計する事も相似形になる。2016これは強引なアナロジーかもしれないけど、サイモン先生は組織を役割分担の仕組みだと言った。役割分担はプログラミングで言えばオブジェクト指向設計に相当する。役割が比較的安定している時はその仕組みでもうまく回るけど、役割の境界が不安定になると途端に難しい状況になる。2016ひょっとしたら、これでオブジェクト指向から関数型への流れを説明出来るかもしれない。Team組織やチームの話を追いかけると、プログラミングは基礎教養なんだって話に辿り着いてしまう件にコメントオブジェクト指向とは何だったのか?このブログでも何度か取り上げているように、プログラミングにおけるここ数年間のトレンドで最も大きなものは、関数型プログラミングの隆盛だと言って良いだろう。そのトレンドと共に相対的に存在感を失いつつあるのが、それまで長らく主流を占めていた「オブジェクト指向」という考え方である。関数型プログラミングの観点から眺めると、オブジェクト指向プログラミングではシステムの状態を暗黙に扱う(情報隠蔽)ために実行時の挙動が予測しづらくなり、高度な並行性が求められる現在の環境では、信頼性を確保する際の大きな障害となるように見える。筆者も含めて、オブジェクト指向という考え方にあれだけ熱狂した立場から考えると、昨今のオブジェクト指向に対する評価に対して若干の違和感を感じざるを得ないのも事実である。いうわけで今回は、オブジェクト指向の発案者による発言を参照しながら、改めて「そもそもオブジェクト指向とは何だったのか?」ということについて考えてみたい。始めに「オブジェクト指向」という言葉の意味については、どこかに正式な定義が存在する、というわけではないようだ。これは「関数型」についても同様のようである。このブログで書かれていることはある種の解釈や立場表明をしているに過ぎないということに注意して頂きたい。メッセージング「オブジェクト指向(object-oriented)」という言葉を最初に提唱したのは、Smalltalkというオブジェクト指向環境を発明したアラン・ケイ氏だと言われている(これは本人も認めている)。(強調は筆者)そのアラン・ケイ氏によれば、オブジェクト指向で最も重要なのは「メッセージング」なのだと言う。(強調は筆者)上記引用にもあるように、ケイ氏は「オブジェクト(指向)」という言葉を持ち出したことに後悔さえしていると言う。メッセージングの観点から言えば、クラスやオブジェクトさえも重要ではないということから、本来は「メッセージ指向」と呼ぶべきだったのかもしれない。オブジェクト指向を実践してきた多くのプログラマにとっては、むしろ馴染みの薄いものではないだろうか。ケイ氏は、オブジェクトを、ネットワークを形成してメッセージを送り合うコンピュータのメタファーとして捉えており、インターネット上のサーバーのように、リクエストをメッセージとして受け取り、そのメッセージをサーバー側で解釈して何らかの処理を行うというモデルを想定していた。メソッド呼び出しがメッセージングに相当するように思われるかもしれないが厳密には異なる。このメッセージを非同期にやり取りするという、今まさに広がりを見せつつある並行処理のモデルを70年代の段階で実現していた(後にアクターモデルと呼ばれる)。[2016/05/09追記]この部分に事実誤認があるとの指摘をコメント欄にて頂いた。ケイのメッセージングとはまた別物です。Smalltalk(-72、-74、-76、-78)は非同期のメッセージングベースで実装されたことはありません。コメント欄(sumimさん)よりとのこと。ご指摘感謝![2016/05/10追記]さらに別の方からコメントを頂く。Hewittの考案であり、Kayのメッセージングとは「別物」ということですが、歴史はしばしばもうちょっとややこしいものです。Modelの着想を得た、という経緯もあります。Kayの名前があるもの、それ以上のクレジットがなかったために、Carlが「コミュニティー」からもうちょっとアイディアの出典を正直に述べなくてはならないという批判を受けることになったという話もあります。入門も是非ご参考あれ。このメッセージングに関係して、最近タイムリーなブログ記事を見かけた。アラン・ケイ氏のオブジェクト指向を体現している言語環境なのではないかという考察である。ちなみに、この二つの言語は一般的には関数型プログラミング言語として認識されているはずである。オブジェクト指向に近い言語である」という趣旨の発言をしているようだ。それは、メッセージングという仕組みの内に、ケイ氏が考えるオブジェクト指向の要点が全て含まれているからである。ケイ氏は、メッセージングの位置づけを日本語の「間」という言葉で説明しているが、氏によれば、システムの「間」つまりコミュニケーションに着目することによって、システムにとって重大な目的(ゴール)だけを表現し、その他の詳細については二次的に決定すれば良い、そしてそのような決定の先送りがシステムの寿命を延ばす鍵になるのだと言う。メッセージがどのように解釈されるのか、クラスから作られたオブジェクトによって処理されるのか、そのクラスは継承によって構造を共有しているのか、あるいはプロトタイプベースなのかという問題は全て二次的な問題である。ある段階からあらゆることを決定し固定化したがる人たちによって不毛な議論が繰り返され、その結果、進歩が停滞しているとケイ氏は苛立ちを見せていた。progress」の考え方は、21世紀になってから普及したアジャイルの考え方そのものである。アジャイルはオブジェクト指向のコミュニティが生み出したものであるが、その考え方の源流はオブジェクト指向の始まりから既に埋め込まれていた。抽象データ型ここまでの話で、オブジェクト指向の発案者であるアラン・ケイ氏の、メッセージングという真意が明らかになった。これだけでは職業プログラマの多くが実践してきたオブジェクト指向らしきものは一体何だったのかという疑問が残る。route」の他に、「抽象データ型」を中心に据える流れも起こり、こちらの方がむしろその後主流になったと説明している。typing)として職業プログラマの間では主流になった。mind”」)、型システムそのものについて否定的に見ているわけではないようである。Programming”クリエイティビティさて、結果的に抽象データ型が主流になったのあれば、それがいわゆる多くの人が認識するところのオブジェクト指向なのだから、今更「アラン・ケイ氏のオブジェクト指向」についてわざわざ考慮する必要があるのかと考える人もいるかもしれない。筆者にとってこの二つの立場の違いは、単にプログラミング言語の差異に留まらず、コンピューティングというものに対する立場を二分する大きな断絶を象徴する分岐であるように思えるのである。抽象データ型というのは、単にプログラミング言語の問題である。システム開発者側の問題だと言っても良いかもしれない。開発側の観点から仕事上のトラブルを少なくするといった、よりプラグマティックな理由から型システムという仕組みを評価できるだろう。職業プログラマの間で型システムが普及した理由にはこのような側面もあったのではないだろうか。Smalltalk」を読むと、オブジェクト指向は単にプログラミングだけの問題ではなく、もっと壮大な理想を追求するために考案されたのだということが分かる。Smalltalkhttp://worrydream.com/EarlyHistoryOfSmalltalk/オブジェクト指向が生まれる直前の60年代という時代は、コンピュータが、予め計画された計算を行うだけというイメージの、一つの部屋を専有する巨大な機械から、もっと人間の力を高める形でインタラクションを提供する新しいメディアへと生まれ変わろうとする、いわゆるパーソナルコンピューティングの黎明期に当たる。Agency)というアメリカ国防総省管轄の研究機関である。開発したことでも知られる。構想であり、この構想には今日では当たり前になっているパーソナルコンピュータやネットワーク、GUI(ウィンドウシステム)など、パーソナルコンピューティングにとって重要なあらゆる要素が詰め込まれていた。reach」)ということであったが、これは言い換えれば「クリエイティビティ(創造性)」の追求である。ケイ氏が最も熱心に取り組んでいたのはコンピュータを使った子供の教育であった。オブジェクト指向プログラミングを子供に教えることによって、ソフトウェアを自身の問題に合わせて自在に変更出来るようにし、より高い問題解決能力を獲得させることを目指した。この教育プロジェクトの試行錯誤によって得られた知見には大変興味深いものが多い。クリエイティビティに寄与する一つの根拠として、より少ない原則で多くを表現できるというものがある。object」というやつである。message」と言ったかもしれない(そのようなプログラミング言語が実際に存在する)。この全てがオブジェクトであるという原則と、大きなシステム(オブジェクト)は小さなシステム(オブジェクト)の組み合わせで作られるという「再帰的デザイン」によって、どんな複雑なシステムをデザインするときでも、覚えなくてはならない原則は少なくて済むようになる。おいて重要なのは、システムを使うという行為と作るという行為が全く同じになるということである。システムを使うときと全く同じ操作で、その延長線上でシステム自体を変更することができる。このように、導入において覚えることが少なくて済む、そしてその少ない道具立ててであらゆることが表現できるという枠組みが、子供の教育にとって重要であることは想像に難くない。実際に試してみて分かったことは、あるオブジェクトにメッセージを送るという1ステップの変更については小さな子供でも理解することが出来るが、複数ステップの変更を組み合わせないと解決できないような問題になると、それがほんの2、3ステップだったとしても極めて難しくなってしまうということだった。これは子供だけでなく、プログラミング経験のない大人でも似たような現象が見られたようである。初歩の問題は容易にクリアできるが、問題が複雑化すると、それがプログラマから見たら些細だと思われる問題でも全く歯が立たなくなる。これは今で言うプログラムデザインの問題である。templates」という仕組みを考案した。これはぼんやりとしたデザインのアイデアとプログラムによる実例の中間に位置する道具立ててで、今で言うところのデザインパターンやフレームワークに相当するものである。progress」にすることの重要性について繰り返し語っているが、それはいかに多くの技術者や専門家が手段に埋没し、そして宗教論争に明け暮れているかということに対しての警鐘にもなっている。Smalltalk」の一つのハイライトは、1979年、ケイ氏の勤めるパロアルト研究所(PARC)に、あのスティーブ・ジョブズ氏が訪れる場面である。プロジェクトを立ち上げていたが、決定的なアイデアがなく模索中の段階であった。ケイ氏は、PARCに訪れたアップルの面々に対して、ALTOというパーソナルコンピュータ試作機のデモを行う。搭載されており、その上ではウィンドウベースのGUIが動いていた。氏がその場で修正して訪問者を驚かせたという場面が紹介されている。環境の強力さが垣間見えるエピソードである。この邂逅の後の歴史は多くの人の知るところなのでここでは深追いしないが、1995年に行われたインタビューにおいて、ジョブズ氏がパロアルト研究所で見たデモについて、そしてその当時は理解出来なかったというオブジェクト指向の重要性について語っているので、その動画を紹介しておきたい。この映像は放送後に一度紛失したと思われたマスターテープがジョブズ氏の死後に偶然見つかったということで、95年の放送時はカットされた部分も含めて全編放送されたものであるが、その内容にはただひたすら圧倒されるのみである。現在オブジェクト指向についてその起源から検討してみたが、この歴史を前提に改めて考えてみると、昨今言われる「オブジェクト指向から関数型へ」という話が大分狭い領域の話であることに気づかされる。モジュールシステムの進化という観点から言えば、関数型プログラミングが有効である場面が増えているのは疑いようがない。large」という形で適材適所に住み分けることになるのではないだろうか。binding)と言ったコンセプトは形を変えてあらゆる場面で見かけるようになった。その代表的なものの一つが、アジャイルという考え方である。オブジェクト指向はその出自から考えても分かるように、より上流の考えを重視する目的指向のパラダイムである。アジャイルはその後、経営やデザインなど、ソフトウェア開発の枠組みを超えて、クリエイション一般に適用出来るような普遍的な考え方として普及しつつある。オブジェクト指向と関数型の違い古いブックマークを漁っていたら、オブジェクト指向と関数型の違いに関する面白い記事を見つけた。氏の興味深いツイートから始まる。2010試訳オブジェクト指向は、可変部分をカプセル化(隠蔽)することによって、コードを分かりやすくする関数型は、可変部分を最小化することによって、コードを分かりやすくする筆者なりに解釈すれば、オブジェクト指向はインターフェースにフォーカスし、可変部分を捨象することによって複雑なシステムを単純化し、関数型は副作用のない関数を組み合わせることによってシステムの可変部分を最小限に保ち、システムの動的な性質を掴みやすくしようとする。オブジェクト指向の「可変部分を捨象する」という考え方がシステムを単純化する一方、インターフェースの裏側で起こることは予測し辛くなる。インターフェースの「契約」に現れない状態変化、極端な例を挙げれば「重要なデータを削除しないこと」など、それら全てについて自動テストを用意するのは現実的ではないため、オブジェクト指向のシステムが提供出来る信頼性には自ずと限界があることになる。興味深いのは、オブジェクト指向の上に関数型の仕組みを乗っけるのは止めた方が良いという主張だ。コードの中に、関数型の部分とそうでない部分が混在してしまうと、全体としては関数型の恩恵を受け辛くなるのだろう。比較という観点からも興味深い指摘である。Scalaは基本的にオブジェクトから出発して関数型の流儀を徐々に入れて行くの対し、Elixirはまず関数型から出発する。氏は、100%純粋な関数型を実現するのは非現実的であり、大体85%ぐらいを目指せばいいのではないかと主張する。残りの15%は注意深く分離してコードの中に分散しないようにすべきであると。Frameworkで採用されているデータアクセスのフレームワーク、Ectoの中にも見られた。Repositoryパターンが採用されている。自身に副作用を内包するのとは対照的である。Blog.投稿先:キャンセル。