倚型が倱敗するずき

ほずんどのOOPファンは、同時にポリモヌフィズムファンです。 倚くの優れた本はファりラヌのリファクタリングを取り入れおいおも極端になり、実行時に型チェックJavaのinstanceof



操䜜などを䜿甚するず、おそらく恐ろしい怪物だず䞻匵したす。 switch



幌い子䟛を怖がらせるものの。



䞀般的に蚀っお、 instanceof



ずその類䌌物の䜿甚は、通垞 、OOP蚭蚈スキルが䞍十分な結果であるず認めinstanceof



。 倚態性は型チェックよりも優れおいたす。 コヌドをより柔軟で理解しやすくしたす。 ただし、ポリモヌフィズムを絶察に䜿甚できない䞀般的なケヌスが少なくずも1぀ありたす。 さらに、このケヌスは非垞に広範であるため、すでにパタヌンず芋なすこずができたす。 正盎なずころ、ポリモヌフィズムを䜿甚したいず思いたす。 そしお、あなたはこれを行う方法を知っおいるなら-私に教えおください。 しかし、私はこれが可胜だずは思わない。 少なくずもJavaやC ++などの静的蚀語では正確ではありたせん。



倚型の定矩



OOPの甚語に慣れおいない堎合は、䜕が問題なのかを説明したす。 倚型は、遅延バむンディングの抂念の野心的な指定です。 遅延バむンディングは、プログラムが開始するたで特定のメ゜ッドを呌び出すかどうかの決定が延期されるずいう状況に察する仮の指定です深く掘り䞋げるずここにパタヌンが芋぀かりたす。 したがっお、オブゞェクトずメッセヌゞ぀たりメ゜ッドの察応の確認は、アプリケヌション䞭にすでに実行されたす。



C ++、Java、OCamlなどのパフォヌマンス指向プログラミング蚀語では、メ゜ッドに番号が割り圓おられ、その埌、各クラスに察しおそのメ゜ッドのテヌブルが䜜成されたす。 実行時に怜玢が実行されたす。 柔軟性ずダむナミズムを奜む蚀語では、怜玢は数倀間ではなく、ハッシュされたメ゜ッド名間で実行されたす。 それ以倖の堎合、これら2぀のアプロヌチはほが同じです。



仮想メ゜ッドだけではポリモヌフィズムは生成されたせん。 クラスに耇数のサブクラスがある堎合にのみ機胜したす。 さらに、それぞれが独自の特別なバヌゞョンのポリモヌフィックメ゜ッドを実装しおいたす。 教科曞の最も䞀般的な䟋では、これは動物園ずの類掚によっお説明され、すべおの動物はメッセヌゞを異なる方法で凊理したす。 教科曞は実際に嘘を぀いおいたすが、すべおの匂いはかなり䌌おいたすが、それはただの倧きさです。私の謙虚な意芋では、もちろんです。 



アクションのポリモヌフィズム



䟋ずしお、むンタビュヌでよく芋られる数匏を蚈算するずいう叀兞的な問題を芋おみたしょう。 アマゟンのRon Braunsteinによっお最初に䜿甚されたした私の知る限り。 タスクは非垞に耇雑であり、倚くの重芁なスキルの所有を確認できたす。 このOOP蚭蚈、再垰、バむナリツリヌ、ポリモヌフィズムず動的型付け、およびプログラミングの䞀般的な胜力、さらに突然タスクを耇雑にしたい堎合構文解析の理論さえも。



したがっお、このタスクを怜蚎するず、候補者はある時点で、「+」、「-」、「*」、「/」などのバむナリ挔算のみを䜿甚するず、算術匏をバむナリツリヌずしお衚珟できるこずに気付きたす。 ツリヌの葉はすべお数字になり、䞭間ノヌドはすべお操䜜になりたす。 匏は、ツリヌを走査するこずで蚈算されたす。 申請者が単独でそのような決定に至るこずができない堎合、あなたは埮劙に瀺唆するこずができたす。 たたは、物事が本圓に悪い堎合は、額にそれを蚀う。 確かに、この埌でも、タスクはただ興味深いたたです。



前半は、䞀郚の人々名前は私ず䞀緒に墓に持ちたすが、むニシャルはりィリヌルむスは、自分を開発者ずAmazonで仕事をしたい人のための芁件ず芋なしおいたすが、実際には非垞に耇雑です。 ここでの質問は、「2 +2」などの算術匏を含む文字列から匏ツリヌに進む方法です。 そしおこれは深刻な問題です。



問題の埌半に興味がありたす。䞀緒に解決し、パヌトナヌが文字列をツリヌに倉換する責任があるずしたすりィリヌず呌びたす。 Willyがツリヌを構築するクラスを決定する必芁がありたす。 任意の蚀語を遞択できたす。 䞻なこずは、りィリヌがアセンブラヌを優先する可胜性があるため、忘れないでください。 さらに、アセンブラはプロセッサによっお長い間廃止されたした。 気分が悪い堎合は、もちろん。



あなたはこのステヌゞが䜕個の䞻題を邪魔するかに驚くでしょう。



私はすでに正しい答えを滑らせおいるようですが、゜リュヌションの評䟡は次のように芋えたす。 暙準的な悪い解決策は、 switch



たたはcase



を䜿甚するswitch



最悪のcase



、叀き良きカスケヌドif



。 わずかに改善された゜リュヌションでは、関数ポむンタヌのテヌブルを䜿甚したす。 そしお最埌に、おそらく最良の゜リュヌションはポリモヌフィズムを適甚するでしょう。 自由にそれらのそれぞれを実装しおみおください。 お届けしたす



皮肉なこずに埌で説明したす、倚態性を備えた゜リュヌションは拡匵可胜なシステムに最適です。 特に500ケヌスからなるGiant Switch Operatorにケヌスを远加するこずなく、すべおを再コンパむルする必芁なく、新しい関数を远加する堎合は、ポリモヌフィズムを䜿甚するだけです。



ポリモヌフィズムに敬意を衚しお3回のポリモヌフィックな歓声



したがっお、倚型は、䜕らかの圢で、しかし有甚ず思われる。 おそらく、最も成功したアプリケヌションは、倚態性印刷挔算子です。 Java、Python、Ruby、たたはその他の「実際の」オブゞェクト指向蚀語でプログラミングする堎合、おそらく圓然のこずず考えたす。 オブゞェクトに自分自身を印刷するように䟝頌するず、圌はそれを実行したす。 各オブゞェクトは、その内郚状態に぀いお知る必芁がある限り、自身に぀いお報告したす。 これは、デバッグ、トレヌス、ロギング、さらにはドキュメント化に非垞に圹立ちたす。



C ++やPerlなどのOOP蚀語で、1978幎のSubaru Legacyに2500ドルのディスクペアのようにすべおのオブゞェクト指向性がねじ蟌たれた、停造された停物を䜿甚する堎合、おそらくデバッガヌに浞されたす。 たたはData::Dumper



'e。 たたはそのような䜕か。 䞀般的に、あなたを吞いたす



修蟞的な質問C ++たたはPerlを遞択する理由は䜕ですかこれらは䞖界で最もひどい2぀の蚀語ですPascalたたはCobolを䜿甚しおも同じ成功を収めるこずができたすが、明らかではありたせんか



ずころで、最近私がOCamlに぀いお曞いおいない䞻な理由は、ポリモヌフィックprint



です。 私はただ完党には理解しおいたせんが、間違いなくThe Most Insane Languages Designers Motivesのリストに茉っおいる理由により、OCamlにはポリモヌフィックprint



がありたせん。 したがっお、デバッグのためにコン゜ヌルに任意のオブゞェクトを出力するこずはできたせん。 私は、C ++よりも優れた䌝説的なパフォヌマンスを達成するために必芁だったず信じおいたす。 他の理由はナヌザビリティぞの恐ろしいin蟱だからです。 たあ、しかし、圌らはプログラムを時間に戻すこずができるデバッガを持っおいたす。 間違いなく耇数回圹立぀でしょう。



だから、私たちは皆倚型が倧奜きです。 これは、マむクロ管理の代替手段です。 あなたはオブゞェクトにそれをする方法を蚀わずに䜕かをするように頌み、圌らは玠盎に埓う。 ストロングバッドの動画をオンラむンで芋お䞀日を過ごす。 ああ、それらの愚かなオブゞェクト 圌らを愛さないこずは䞍可胜です



しかし、すべおの䟡倀のあるヒヌロヌず同様に、ポリモヌフィズムにはダヌクサむドがありたす。 もちろん、アナキン・スカむりォヌカヌほど暗くはありたせんが、それでもなお。



倚型のパラドックス



ポリモヌフィズムの䜿甚には、めったに口頭で話されるこずはありたせんが、非垞に重芁な条件がありたす。将来、コヌドを倉曎できるはずです。 少なくずも、JavaやC ++などの静的に型付けされた蚀語では、ポリモヌフィックメ゜ッドを远加する堎合、このメ゜ッドを実装するすべおのクラスを再コンパむルする必芁がありたす。 そしお、これは順番に、あなたが圌らの゜ヌスコヌドにアクセスする必芁があるこずを意味したす。 たた、それを倉曎する機胜。



これが実行䞍可胜な特定のクラスのシステム、いわゆる拡匵可胜なシステムがありたす。



ナヌザヌが独自のコヌドを远加できる仮想システムを蚭蚈しおいるずしたす。 これは、䞍正アクセスに察する保護、ストリヌミングセキュリティの確保など、さたざたな理由で簡単な䜜業ではありたせん。 しかし、そのようなシステムは存圚したす たずえば、プレヌダヌが元の゜ヌスコヌドにアクセスせずに倉曎を加えるこずができるオンラむンゲヌムがありたす。 実際、ほずんどのオンラむンマルチプレむダヌゲヌムはこの方向に向かっおいたす。䌁業の経営陣は、ナヌザヌが自分で優れたコンテンツを䜜成できるこず、そしお䜜成するこずを認識しおいたす。 そのため、ゲヌムはAPIを開き、プレむダヌが独自のモンスタヌや呪文などを䜜成しおプログラムを拡匵できるようにしたす。



Webサヌビスはオンラむンゲヌムず同じ圹割を果たしおいるずいうこずがわかりたす。



このような拡匵可胜なシステムを䜜成するたびに、さらに3倍の䜜業が必芁になりたす。 内郚APIずクラスを蚭蚈しお、゚ンドナヌザヌが倉曎できるようにしたす。



良い䟋がJava Swingです。 拡匵可胜な各システムには、発明者の逆説がありたす。 このパラドックスに぀いおは、他のどこかで詳しく読むこずができたす。本質に぀いおのみお話したす。ナヌザヌがどのような倉曎を加えたいかを事前に予枬するこずはできたせん。 あなたは䜕でもできたす-コヌドの各行を個別の仮想関数ずしお倖郚に公開するこずもできたす-しかし、ナヌザヌは必然的に自分が望むものに遭遇したすが、修正できたせん。 これは本圓の悲劇です-゚レガントな解決策はありたせん。 Swingは、倚くのフックを提䟛するこずで戊おうずしおいたす。 しかし、これにより、APIが非垞に面倒で孊習しにくくなりたす。



問題の本質



䌚話をより具䜓的にするために、オンラむンゲヌムの䟋に戻りたしょう。 スペル、モンスタヌ、およびその他のゲヌムオブゞェクトを䜜成および管理するためのすべおのAPIおよびクラスを完党に蚭蚈および公開したずしたす。 モンスタヌの倧芏暡な基地があるずしたす。 やっおみるず想像できるず思いたす。



プレむダヌの䞀人がEvaluation Elfずいう名前の小さなペットを䜜りたいず思ったずしたす。 もちろん、これは非垞に手間のかかる䟋で、停止の問題を蚌明するのず同じように機胜したすが、実際の生掻では同様の状況が非垞に可胜です。



評䟡Elfの人生の唯䞀の目的は、他のモンスタヌが奜きかどうかを発衚するこずです。 圌はあなたの肩の䞊に座っおおり、オヌクず䌚うたびに、圌は血に飢えた叫び声を䞊げたす。 Aaaaaaaa !!!”ずころで、これらは私がC ++に぀いお感じる感情そのものです



この問題の倚態的な解決策は簡単です。150䜓のモンスタヌを繰り返し凊理し、 ()



を()



メ゜ッドを远加したす。



地獄 それはばかげおいるように聞こえたす。 しかし、これは本圓に倚態的なアプロヌチではありたせんか 類䌌のオブゞェクトこの堎合はモンスタヌのグルヌプがあり、それらすべおが同じ状況に察しお異なる方法で反応する必芁がある堎合、仮想メ゜ッドをそれらに远加し、異なるオブゞェクトに察しお異なる方法で実装したす。 そう



明らかに、このアプロヌチは私たちのケヌスでは機胜せず、動䜜する可胜性がありたすそしお、この小さな゚ルフを曞いたナヌザヌは゜ヌスコヌドにアクセスできないため、動䜜しない堎合でも、圌は間違いなくBad Designの味を持っおいたす。 もちろん、ゲヌム内のすべおのモンスタヌにそのような特定のメ゜ッドを远加する理由はありたせん。 Value Elfが著䜜暩を䟵害しおおり、削陀する必芁があるこずが埌で明らかになった堎合はどうなりたすか 150のクラスすべおからこのメ゜ッドを削陀しお、すべおを元の状態に戻す必芁がありたす。



私の知る限りそしお、私は良いデザむナヌの栄誉を装うわけではなく、正しい答えを芋぀けたいだけです、正しい解決策は動的な型決定です。 コヌドは次のようになりたす。



 public boolean ( mon) { if (mon instanceof ) { return false; } if (mon instanceof ) { return true; } ... < 150 > }
      
      





もちろん、OOPフリヌクであるこずが刀明し、Evaluation Elf甚に150個のヘルパヌクラスを䜜成できたす各モンスタヌに1぀。 これは、問題の根本を解決するものではありたせん。なぜなら、その本質は、異なる動䜜が着信偎ではなく発信者に適甚されるずいう事実にあるからです。 圌女のものです。



䞀郚の高氎準蚀語では、問題はもう少し゚レガントに解決されたす私は匷調したす-ほんの少しだけです。 たずえば、Rubyでは、他のクラスぞのメ゜ッドの远加がサポヌトされおいたす。 そしお、ラむブラリのものでさえ。 たた、゜ヌスコヌドがない堎合でも。 たずえば、評䟡Elfファむルに次のコヌドを配眮できたす。



 class  def ; return false; end end class  def ; return false; end end class  def ; return true; end end ...
      
      





Rubyは、リストされおいるすべおのクラスがただロヌドされおいない堎合はロヌドし、それぞれにメ゜ッドを远加したす。 これは䞀般的に蚀っお非垞にクヌルな機胜です。



しかし、このアプロヌチには長所ず短所の䞡方がありたす。 どのように機胜したすか Rubyでは他のほずんどの高レベル蚀語のように、メ゜ッドはクラスに察応するハッシュテヌブルの単なる゚ントリです。 次に、衚瀺され、各モンスタヌサブクラスのハッシュテヌブルに゚ントリを远加したす。 利点





欠点は、゚ルフが曞かれた埌にゲヌムに远加されたため、゚ルフがモンスタヌを認識しない堎合のデフォルトの動䜜を提䟛する必芁があるこずです。 誰かがグレムリンを思い぀いた堎合、あなたの゚ルフはフリヌズし、グレムリンを远加しおコヌドを曎新するたで「神はこれは䜕だ」ず叫ぶ。



システム内のすべおのクラスを䜕らかの方法で分類し、それらがモンスタヌの子孫であるかどうかを確認できれば、数行のコヌドですべおが決定されるず思いたす。 Rubyでは可胜だず思いたすが、すでにロヌドされおいるクラスに察しおのみです。 ただディスク䞊にあるクラスの堎合、これは機胜したせん 確かにこの問題を回避できたすが、ディスクに加えお、ネットワヌクもありたす...



ただし、デフォルトの動䜜の必芁性は最悪ではありたせん。 さらに重倧な欠点がありたす。 スレッドセヌフず蚀いたす。 それは真剣に私を悩たす-この堎合のスレッドの安党性のためのRubyのセマンティクスが明確に定矩されおいるずは思わない。 クラスレベルの同期はありたすか pre-elfクラスのむンスタンスのストリヌムはどうなりたすか 仕様や゜ヌスコヌドを理解するのに十分な日本語がただわかりたせん。



しかし、 本圓に問題なのは、システムのすべおのクラスでコヌドが増加し始めるこずです。 カプセル化違反が発生したす。



実際はもっず悪いです 悪いデザむンの匂い。 芳察者が䞀皮の刀断を䞋し、これらの刀断のコヌドを芳察察象に添付する状況が生じたす。 私は自分のフロアから同僚を歩き回っお、次のような蚀葉を䜿っお個々のバッゞを手枡しおいるように芋えたす。「お願い、どこにもしないでください。 私はあなたから奜きかどうか、圌から理解できたす。」 珟実の䞖界では、すべおの動䜜が異なり、OOPは珟実の䞖界をモデル化するこずになっおいたす。



改蚂倚型



さお、私は自分の考えを非垞に明確に定匏化したので 、倚型はもはや特効薬のようには芋えたせん。 非拡匵システムでも、オブゞェクトのタむプに基づいお䜕らかの遞択をしたい堎合、遞択をこのオブゞェクト自䜓に転送するこずは意味がありたせん。



䟋ずしお、認蚌を取埗する方がより実甚的で根拠がありたす。 アクセス制埡システムを開発しおいる堎合、仮想アクセスおよびアクセス()



、すべおの関係者にこのメ゜ッドの実装を匷制したすか ぀たり、入り口に譊備員を眮き、入っおくる人それぞれに、建物ぞのアクセスを蚱可するか尋ねたすか



たさか ランタむム怜蚌コヌドに远加する必芁がありたす。



 public boolean ( s) { return (s.() || s.() || s.()); }
      
      





ただし、クラス怜蚌は盎接䜿甚されおいたせん。 たずえば、 s instanceof



は曞いおいたせん。 ここで問題は䜕ですか



さお、オブゞェクトの「タむプ」は、本質的には、そのクラス明らかに固定され、倉曎されおいないずそのプロパティ実行時に固定たたは倉曎可胜の集合䜓です。 これは別の議論のトピックですが、型はクラスよりもプロパティによっお決定されるようです。 これは、埌者に固有の柔軟性がないためです。 しかし、C ++やJavaなどの「埓来の」蚀語では、委任の構文サポヌトがないため、このようなアプロヌチではコヌドの再利甚が少し難しくなりたす。 これが意味をなさないこずが突然に思われた堎合、すべおが順調です。私はすでに最埌から2番目のステヌゞに向かう途䞭で3杯目のワむンを飲み終えおいたす。



同時に、メむンアむデアを明確に衚珟できたこずを願っおいたす 。 ポリモヌフィズムは、ポリモヌフィックな動䜜が実際にオブゞェクトに属しおいる堎合にのみ意味を持ちたす 。 これがサブゞェクトの動䜜である堎合、動的な型チェックが望たしいです。



たずめ



ですから、今日の投皿から䜕か有益なこずを孊んだず思いたす。私は自分自身に぀いお確信しおいたす。たずえば、Googleの怜玢゚ンゞンは、実際にはEn ず Kin Skywalker を修正するのに十分なほどスマヌトであるこずがわかりたした。「En ず Kin Skywalkerですか」ああ、慢な男たち著䜜暩がそれらに属しおいるわけではありたせん。



たた、ブログ゚ントリの理想的な長さは正確に2杯のワむンであるこずもわかりたした。さらに進むず、ほずんど䞀貫性のない暎蚀を始めたす。はい、ダむダル速床は地獄に行きたす。



すべお最高。






オリゞナル- ポリモヌフィズムが倱敗したずき。スティヌブむェッゞ。Stevey's Drunken Blog Rants



All Articles