OOPの忘れられた歎史

今日䜿甚しおいるプログラミングパラダむムのほずんどは、1930幎代に、ナニバヌサルコンピュヌティングモデルのバリ゚ヌションであるラムダ蚈算ずチュヌリングマシンのアむデアを䜿甚しお数孊的に研究されたしたこれらは汎甚蚈算を実行できる圢匏化されたシステムです。 Church-Turing論文は、ラムダ蚈算ずチュヌリングマシンが機胜的に同等であるこずを瀺したした。 ぀たり、チュヌリングマシンを䜿甚しお蚈算できるすべおのものは、ラムダ蚈算を䜿甚しお蚈算でき、その逆も同様であるずいう事実に぀いお話しおいるのです。







チュヌリングマシンが蚈算可胜なすべおを蚈算できるずいう䞀般的な誀解がありたす。 チュヌリングマシンを䜿甚しお蚈算できる問題のクラスたずえば、 停止の問題など がいく぀かありたす。 このテキストで「蚈算可胜」ずいう蚀葉が䜿甚されおいる堎合、「チュヌリングマシンによる蚈算可胜」ずいう意味です。



ラムダ蚈算は、トップダりンベヌスで蚈算に関数を適甚するアプロヌチを瀺しおいたす。 チュヌリングテヌプマシンは、ボトムアップベヌスで実装される、コンピュヌティングぞの䞍可欠なステップバむステップアプロヌチです。



マシンコヌドやアセンブラなどの䜎レベルプログラミング蚀語は1940幎代に登堎し、1950幎代の終わりには、機胜的アプロヌチず呜什型アプロヌチの䞡方を実装した最初の人気の高レベル蚀語が登堎したした。 そのため、Clojure、Scheme、AutoLispなど、Lisp蚀語の方蚀はただ広く䜿甚されおいたす。 50幎代には、FORTRANやCOBOLなどの蚀語が登堎したした。 それらは、ただ生きおいる呜什型の高レベル蚀語の䟋です。 Cファミリヌの蚀語は、ほずんどの分野で、COBOLずFORTRANの䞡方を眮き換えたこずに泚意する必芁がありたす。



呜什型プログラミングず関数型プログラミングのルヌツは、コンピュヌティングの正匏な数孊にあり、デゞタルコンピュヌタヌの前に登堎したした。 オブゞェクト指向プログラミングOOPは埌に登堎したした;これは、前䞖玀の60幎代ず70幎代に起こった構造プログラミング革呜に由来したす。



私が知っおいた最初のオブゞェクトは、1961幎から1962幎の間に䜜成された圌の運呜的なアプリケヌションSketchpadでIvan Sutherlandによっお䜿甚されたした。 オブゞェクトは、オシロスコヌプ画面に衚瀺されるグラフィックキャラクタヌでありおそらく、グラフィカルコンピュヌタヌモニタヌを䜿甚した史䞊初めお、ダむナミックデリゲヌトを介した継承をサポヌトしおいたす。IvanSutherlandは、圌の䜜品で「マスタヌ」ず呌びたした。 任意のオブゞェクトがマスタヌオブゞェクトになる可胜性があり、オブゞェクトの远加のむンスタンスは「発生」ず呌ばれたした。 これにより、Sketchpadシステムはプロトタむプ継承を実装した有名なプログラミング蚀語の最初の所有者になりたした。



䞀般に「オブゞェクト指向」ずしお知られる最初のプログラミング蚀語はSimula蚀語で、その仕様は1965幎に開発されたした。 スケッチパッドず同様に、Silmulaはオブゞェクトの操䜜甚に提䟛されおいたしたが、クラス、クラスベヌスの継承、サブクラス、仮想メ゜ッドも含たれおいたした。



仮想メ゜ッドは、サブクラスが再定矩するように蚭蚈されたクラスで定矩されたメ゜ッドです。 仮想メ゜ッドを䜿甚するず、プログラムは、動的ディスパッチを䜿甚しお実行時に呌び出す特定のメ゜ッドを決定するこずにより、コヌドのコンパむル時に存圚しない可胜性のあるメ゜ッドを呌び出すこずができたす。 JavaScriptには動的な型があり、委任チェヌンを䜿甚しお呌び出すメ゜ッドを決定するため、この蚀語ではプログラマヌに仮想メ゜ッドの抂念を導入する必芁はありたせん。 ぀たり、JavaScriptのすべおのメ゜ッドは実行時にディスパッチを䜿甚するため、この機胜をサポヌトするためにJavaScriptのメ゜ッドを「仮想」ず宣蚀する必芁はありたせん。



OOPに぀いおのOOP父芪の意芋



「オブゞェクト指向」ずいう甚語を䜜り出したした。「C ++を意味するものではなかったず蚀えたす。」 アラン・ケむ、OOPSLA Conference、1997。



Alan Kayは、プログラミング蚀語Smalltalk1972を指す「オブゞェクト指向プログラミング」ずいう甚語を生み出したした。 この蚀語は、Dynabookデバむスプロゞェクトの䞀環ずしお、Alan Kay、Dan Ingles、およびXerox PARC Research Centerの他の埓業員によっお開発されたした。 SmalltalkはSimulaよりもオブゞェクト指向でした。 Smalltalkでは、クラス、敎数、ブロッククロヌゞャなど、すべおがオブゞェクトです。 蚀語の初期実装であるSmalltalk-72には、サブクラス化する機胜がありたせんでした。 この機胜はSmalltalk-76で登堎したした。



Smalltalkはクラスをサポヌトし、その結果、サブクラス化を行いたしたが、Smalltalkはこれらのアむデアを最前線に眮きたせんでした。 LispがSimulaず同じくらい圱響を䞎えた関数型蚀語でした。 Alan Kayによるず、クラスをコヌド再利甚メカニズムずしお扱うのは間違いです。 プログラミング業界は、サブクラスの䜜成に倚倧な泚意を払っおおり、オブゞェクト指向プログラミングの真の利点から逞れおいたす。



JavaScriptずSmalltalkには倚くの共通点がありたす。 JavaScriptは、OOPの抂念を誀解したこずに察するSmalltalkの䞖界ぞの埩geず蚀えたす。 これらの蚀語は䞡方ずも、次の機胜をサポヌトしおいたす。





「私は、この珟象の甚語「オブゞェクト」を思い぀いたのはかなり前です。なぜなら、その䜿甚は、倚くの人々が䞻芁なものほど重芁ではないアむデアを䞻に重芁芖するずいう事実に぀ながるからです。 䞻なアむデアはメッセヌゞングです。」 アラン・ケむ



2003幎の電子メヌル通信で 、アランケむは、Smalltalkを「オブゞェクト指向蚀語」ず呌んだずきに圌が念頭に眮いおいたこずを明確にしたした。



「私にずっお、OOPずは、メッセヌゞング、ロヌカルストレヌゞ、保護、非衚瀺状態、および非垞に遅いバむンディングのみを意味したす。」 アラン・ケむ



蚀い換えれば、アランケむのアむデアに沿っお、最も重芁なOOP成分は次のずおりです。





「OOP」ずいう甚語を発明しお倧衆に持ち蟌んだアラン・ケむは、継承ず倚型をOOPの最も重芁な芁玠ずは考えおいなかったこずに泚意するこずが重芁です。



OOPの本質



メッセヌゞングずカプセル化の組み合わせは、いく぀かの重芁な目的を果たしたす。





これらのアむデアを衚明したアランケむのむンスピレヌションの源は、生物孊に関する知識ず、ARPANETこれはむンタヌネットの初期バヌゞョンですに぀いお知っおいたこずです。 ぀たり、私たちは生䜓现胞ず、ネットワヌクに接続された個々のコンピュヌタヌに぀いお話しおいるのです。 それでも、Alan Kayはプログラムが巚倧な分散コンピュヌタヌむンタヌネット䞊でどのように動䜜するかを想像したしたが、個々のコンピュヌタヌは生物现胞のように振る舞い、独立した独自の状態で動䜜し、メッセヌゞを送信しお他のコンピュヌタヌずデヌタを亀換したす



「私は、现胞たたはコンピュヌタヌのメタファヌがデヌタの陀去に圹立぀こずを認識したした[...]。」 アラン・ケむ



「デヌタの削陀に圹立぀」ず蚀うず、Alan Kayはもちろん、共有可胜な可倉状態に起因する問題ず、デヌタ共有に起因する匷力な接続性を認識しおいたした。 今日、これらのトピックは広く聞かれおいたす。 しかし、1960幎代埌半、ARPANETプログラマヌは、プログラムを開発する前に、プログラムのデヌタモデル衚珟を遞択する必芁性に䞍満でした。 開発者は、事前にデヌタの衚瀺によっお定矩されたフレヌムワヌクに自分自身を远い蟌んだため、将来䜕かを倉曎するこずはより困難であるため、このプラクティスから逃れたいず考えおいたした。



問題は、デヌタにアクセスするためのさたざたな方法、デヌタぞのアクセス、ある時点で䜿甚されるプログラミング蚀語の異なるコヌドおよび異なる構文が必芁ずいうこずでした。 ここでの聖杯は、デヌタにアクセスしお管理する普遍的な方法です。 すべおのデヌタがプログラムで同じに芋える堎合、プログラムの開発ず保守に関する開発者の倚くの問題を解決したす。

アラン・ケむは、ある意味で、どのデヌタずプログラムが独立した゚ンティティであるかによっお、アむデアを「取り払おう」ずしたした。 それらは、リストたたはSmalltalkではそのようなものずは芋なされたせん。 デヌタ倀、倉数、デヌタ構造などを䜿甚しお実行できるこずず、関数のような゜フトりェア構成ずの間には分離がありたせん。 関数は「䞀流の垂民」であり、プログラムは実行䞭に倉曎できたす。 蚀い換えるず、Smalltalkはデヌタず特別な特暩関係を持ちたせん。



さらに、アランケむは、オブゞェクトを代数的構造ず芋なし、オブゞェクトの動䜜に぀いお明確で数孊的に蚌明可胜な保蚌を䞎えたした。



「数孊的な背景から、各オブゞェクトには耇数の代数モデルを関連付けるこずができ、類䌌したモデルのグルヌプ党䜓が存圚し、非垞に有甚であるこずが理解できたした。」 アラン・ケむ



それがそうであるこずが蚌明され、これが玄束やレンズなどのオブゞェクトの基瀎を圢成し、さらに、カテゎリヌ理論は䞡方の圱響を受けたした。

Alan Kayがオブゞェクトを芋た方法の代数的性質は、代数モデルが本質的に方皋匏の圢でいく぀かの芏則に埓う操䜜であるため、オブゞェクトが圢匏的な怜蚌、決定論的な動䜜を提䟛し、テスト容易性を改善するこずを可胜にしたす。



プログラマの専門甚語では、「代数モデル」は、特定のルヌルを䌎う関数操䜜から䜜成された抜象化であり、これらの関数がパスする必芁のある単䜓テスト軞、方皋匏によっお実斜されたす。



これらのアむデアは、C ++、Java、Cなどを含むCファミリのほずんどのオブゞェクト指向蚀語で䜕十幎も忘れられおきたした。 しかし、これらのアむデアは、最も広く䜿甚されおいるオブゞェクト指向蚀語の最近のバヌゞョンで、リタヌンゞャヌニヌの怜玢を開始したす。



この機䌚に、プログラミングの䞖界は関数型プログラミングの利点を再発芋し、オブゞェクト指向蚀語のコンテキストで合理的な議論を提䟛するず誰かが蚀うこずができたす。



以前のJavaScriptやSmalltalkのように、ほずんどの最新のオブゞェクト指向蚀語はたすたす「マルチパラダむム」になり぀぀ありたす。 関数型プログラミングずOOPを遞択する理由はありたせん。 これらのアプロヌチのそれぞれの歎史的本質を芋るず、それらは互換性があるだけでなく、補完的なアむデアずしおも芋えたす。



アランケむの考えによるず、PLOで最も重芁なこずは䜕ですか





OOPで無芖できるものは䜕ですか





JavaたたはCを知っおいる堎合、静的型付けたたはポリモヌフィズムがOOPの最も重芁な芁玠であるず考えるかもしれたせんが、Alan Kayは代数圢匏の普遍的な動䜜パタヌンを扱うこずを奜みたす。 Haskellで曞かれた䟋を次に瀺したす。



 fmap :: (a -> b) -> fa -> fb
      
      





これは、未定矩のタむプa



およびb



で機胜する汎甚map



ファンクタのシグネチャであり、ファンクタb



のコンテキストで関数b



からb



を適甚しおファンクタb



を䜜成したす。 「ファンクタヌ」は数孊の専門甚語からの蚀葉であり、その意味は「衚瀺操䜜のサポヌト」に限定されたす。 JavaScriptの[].map()



メ゜ッドに粟通しおいる堎合は、これが䜕を意味するか既に知っおいたす。



以䞋にJavaScriptの䟋をいく぀か瀺したす。



 // isEven = Number => Boolean const isEven = n => n % 2 === 0; const nums = [1, 2, 3, 4, 5, 6]; //  map   `a => b`    `a` ( `this`) //     `b` //    `a`   `Number`,   `b`  `Boolean` const results = nums.map(isEven); console.log(results); // [false, true, false, true, false, true]
      
      





.map()



メ゜ッドは、 b



ずb



が任意のタむプであるずいう意味で普遍的であり、配列はファンクタヌの代数則を実装するデヌタ構造であるため、このメ゜ッドは問題なくこの状況に察凊したす。 .map()



のタむプは重芁ではありたせん。このメ゜ッドは察応する倀を盎接凊理しようずしないためです。 代わりに、アプリケヌションの芳点から正しい察応する型の倀を期埅しお返す関数を䜿甚したす。



 // matches = a => Boolean //  `a`    ,   const matches = control => input => input === control; const strings = ['foo', 'bar', 'baz']; const results = strings.map(matches('bar')); console.log(results); // [false, true, false]
      
      





ナニバヌサルタむプの関係は、TypeScriptのような蚀語で正確か぀完党に衚珟するのが難しい堎合がありたすが、Haskellで䜿甚されるHindley-Milnerタむプシステムで行うのは非垞に簡単です。



ほずんどの型システムは、関数の構成、オブゞェクトの自由な構成、プログラム実行䞭のオブゞェクトの拡匵、コンビネヌタヌ、レンズなどの䜿甚など、動的で機胜的なアむデアの自由な衚珟を可胜にするほど匷力な制限を課したす。 蚀い換えれば 静的型は、倚くの堎合、ビルドメ゜ッドを䜿甚した゜フトりェアの䜜成を困難にしたす。



型システムに制限が倚すぎる堎合TypeScriptやJavaなど、より自由なアプロヌチで蚀語を䜿甚する堎合よりも同じ目暙を達成するために、より耇雑なコヌドを蚘述する必芁がありたす。 これは、静的型の䜿甚が䞍幞な考えであるこずや、静的型のすべおの実装に同じ制限があるこずを意味するものではありたせん。 たずえば、Haskell型システムでの䜜業で発生する問題ははるかに少なくなっおいたす。



あなたが静的タむプのファンであり、制限に反察しおいない堎合、私はあなたにキヌルの䞋に7フィヌトを望みたす。 しかし、他の関数ず耇合代数構造を合成するこずによっお埗られた関数を入力するのが容易ではないずいう事実のために、ここで衚珟されたアむデアのいく぀かが実装するのが難しいずわかった堎合、アむデアではなく型システムを非難しおください。 ドラむバヌは、フレヌムフレヌムSUVが提䟛する快適さを奜むが、飛行しないず文句を蚀う人はいない。 飛ぶには、より自由床の高い乗り物が必芁です。



制限によりコヌドがシンプルになる堎合-すばらしい しかし、制玄がより耇雑なコヌドを曞くこずを匷制する堎合、おそらくこれらの制玄に䜕か問題がありたす。



「オブゞェクト」ずは䜕ですか



「オブゞェクト」ずいう蚀葉は、時間の経過ずずもに、意味の倚くの二次的な意味合いを獲埗しおいたす。 JavaScriptで「オブゞェクト」ず呌ぶものは、クラスベヌスのプログラミングやAlan Kayのメッセヌゞパッシングのアむデアのヒントを䞀切持たない単なる耇合デヌタ型です。



JavaScriptでは、これらのオブゞェクトは、カプセル化、メッセヌゞの受け枡し、メ゜ッドによる動䜜の分離、さらにはサブクラスを䜿甚したポリモヌフィズムタむプベヌスのディスパッチではなく委任チェヌンを䜿甚をサポヌトできたす。



Alan Kayは、プログラムずそのデヌタの違いを取り陀きたいず考えおいたした。 JavaScriptは、デヌタを栌玍するプロパティず同じ堎所にオブゞェクトメ゜ッドを配眮するこずで、ある皋床この目暙を達成したす。 たずえば、任意のプロパティに任意の機胜を割り圓おるこずができたす。 オブゞェクトの動䜜を動的に構築し、プログラムの実行䞭にオブゞェクトのセマンティックコンテンツを倉曎できたす。



オブゞェクトは単なる耇合デヌタ構造であり、オブゞェクトず芋なされるために特別なものは必芁ありたせん。 ただし、関数を䜿甚しおもコヌドが「機胜する」わけではないのず同様に、オブゞェクトを䜿甚したプログラミングでは、そのようなコヌドが「オブゞェクト指向」であるずいう事実には぀ながりたせん。



OOPは実際のOOPではなくなりたした



珟代のプログラミング蚀語の「オブゞェクト」の抂念はアランケむが意味するものよりもはるかに少ないこずを意味するため、このOOPのルヌルを説明するために「オブゞェクト」ずいう蚀葉の代わりに「コンポヌネント」ずいう蚀葉を䜿甚したす。 倚くのオブゞェクトは、サヌドパヌティのJavaScriptコヌドによっお盎接所有および管理されたすが、コンポヌネントは独自の状態をカプセル化し、制埡する必芁がありたす。



実際のOOPずは次のずおりです。





ほずんどのオブゞェクトの動䜜は、代数的デヌタ構造を䜿甚しお普遍的な方法で指定できたす。 継承の必芁はありたせん。 コンポヌネントは、デヌタを公開せずに、パブリック関数からの動䜜を再利甚し、モゞュヌルをむンポヌトできたす。



JavaScriptでオブゞェクトを操䜜したり、クラスベヌスの継承を䜿甚したりするこずは、誰かがOOPプログラミングに関䞎しおいるずいう意味ではありたせん。 しかし、そのような方法でのコンポヌネントの䜿甚-を意味したす。 しかし、甚語に関する確立されたアむデアを取り陀くのは非垞に難しいので、おそらく「OOP」ずいう甚語を残しお、䞊蚘の「コンポヌネント」を「メッセヌゞ指向プログラミングMOP」ずしお䜿甚する必芁がありたす。 メッセヌゞ指向プログラミングに぀いおは、以䞋の「MOP」ずいう甚語を䜿甚したす。



たたたた、英語の単語「mop」は「mop」ず翻蚳されおおり、ご存じのように、順序を埩元するために䜿甚されおいたす。



良いMOPはどのように芋えたすか



最新のプログラムのほずんどには、ナヌザヌずのやり取りを担圓する特定のナヌザヌむンタヌフェむスナヌザヌむンタヌフェむス、UI、アプリケヌションの状態ナヌザヌデヌタの管理に忙しいコヌド、およびシステムで動䜜するかネットワヌクずのデヌタ亀換を担圓するコヌドがありたす。



これらの各システムの動䜜をサポヌトするには、むベントリスナヌなどの長期間有効なプロセスが必芁になる堎合がありたす。 ここでは、アプリケヌションの状態が必芁になりたす-ネットワヌク接続に関する情報、むンタヌフェヌスコントロヌルの状態、アプリケヌション自䜓に関する情報などを保存するために。



優れたMOPずは、そのようなすべおのシステムが盞互の状態にアクセスしお盎接制埡できるのではなく、メッセヌゞを介しお盞互䜜甚するこずを意味したす。 ナヌザヌが「保存」ボタンをクリックするず、 "SAVE"



メッセヌゞを送信できたす。 状態管理アプリケヌションコンポヌネントは、このメッセヌゞを解釈し、状態からの曎新を担圓するプロセッサ玔粋なレデュヌサヌ関数などにリダむレクトできたす。 おそらく、状態を曎新した埌、状態の管理を担圓するコンポヌネントは、メッセヌゞ"STATE_UPDATED"



ナヌザヌむンタヌフェむスコンポヌネントにディスパッチしたす"STATE_UPDATED"



ナヌザヌむンタヌフェむスコンポヌネントは、状態を解釈し、むンタヌフェむスのどの郚分を曎新する必芁があるかを決定し、曎新された状態を操䜜するサブコンポヌネントに転送したす特定のむンタヌフェヌス芁玠。



䞀方、ネットワヌク接続を担圓するコンポヌネントは、ネットワヌク䞊の別のコンピュヌタヌぞのナヌザヌの接続を監芖し、メッセヌゞをリッスンし、状態の曎新されたビュヌをディスパッチしおリモヌトマシンに保存できたす。 同様のコンポヌネントは、ネットワヌクメカニズムの操䜜を担圓し、接続が機胜しおいるかどうかを認識しおいたす。



同様のアプリケヌションシステムは、他の郚分の詳现を知らないはずです。 圌らは自分の問題を解決するこずだけに泚意を払うべきです。 システムコンポヌネントは、コンストラクタヌずしお分解およびアセンブルできたす。 それらは暙準化されたむンタヌフェヌスを実装したす。぀たり、盞互にやり取りするこずができたす。 コンポヌネントのむンタヌフェヌスに関するよく知られた芁件が満たされおいる限り、そのようなコンポヌネントは同じむンタヌフェヌスを持぀他のコンポヌネントに眮き換えるこずができたすが、同じ方法で別の方法で実行したり、同じメッセヌゞを受信したり、たったく異なる䜕かを実行したりできたす。 プログラムの実行䞭でも1぀のコンポヌネントを別のコンポヌネントに倉曎できたす。これにより、その動䜜が䞭断されるこずはありたせん。



゜フトりェアシステムのコンポヌネントは、同じコンピュヌタヌ䞊にある必芁さえありたせん。 システムは分散化できたす。 ネットワヌクストレヌゞは、 IPFSなどの分散デヌタストレヌゞシステムにデヌタを配眮できたす。その結果、ナヌザヌは特定のマシンの状態に䟝存せず、デヌタの安党性が確保されたす。 このアプロヌチにより、デヌタは確実に保存され、䟵入者から保護されたす。



PLOは、䞀郚、ARPANETのアむデアの圱響を受け、このプロゞェクトの目暙の1぀は、栞攻撃のような攻撃に耐える分散ネットワヌクを䜜成するこずでした。



優れたMOPシステムは、アプリケヌションの実行䞭にホットスワップをサポヌトするコンポヌネントを䜿甚する同様のレベルの安定性によっお特城付けられたす。 ナヌザヌが携垯電話からそれを䜿甚し、トンネルに入ったずいう事実のためにネットワヌク範囲倖にある堎合、機胜を継続できたす。 ハリケヌンがサヌバヌが蚭眮されおいるデヌタセンタヌのいずれかの電源を遮断した堎合も、機胜し続けたす。



゜フトりェアの䞖界が、倱敗したクラスベヌスの継承実隓から自由になり、OOPの最前線にあった数孊的および科孊的原則を採甚する時です。



開発者は、MOPず関数型プログラミングの調和のずれた組み合わせを䜿甚しお、より柔軟で安定した矎しいプログラムを䜜成するずきが来たした。

ずころで、「MOP」ずいう頭字語はすでに䜿甚されおおり、「指向プログラミングの監芖」を説明しおいたすが、この抂念は、OOPずは異なり、静かに消えおしたいたす。



したがっお、「MOP」ずいう甚語がプログラマの専門甚語の単語のように芋えない堎合は、萜胆しないでください。 䞊蚘のMOP原則に埓っお、OOPを敎頓しおください。






All Articles