web-dev-qa-db-ja.com

Rich Hickeyが「インターフェース/クラス/タイプのそのすべての特定性があなたの再利用を妨げる!」

リッチヒッキーの考えさせられるgoto会議の基調講演 " The Value of Values "で29分に彼はJavaのような言語のオーバーヘッドについて話していて、 「これらすべてのインターフェースは再利用を妨げます。」彼はどういう意味ですか?それは本当ですか?

答えを探すために、私は偶然見つけました:

  • 最小知識の原則AKA デメテルの法則 は、気密APIインターフェースを奨励します。ウィキペディアには、いくつかの欠点もあります。

  • Kevlin Henneyの 帝国服の危機 は、再利用ではなく使用が適切な目標であると主張しています。

  • Jack Diederichの " Stop Writing Classes "の話は、一般にオーバーエンジニアリングに反対するものです。

明らかに、不適切に書かれたものはすべて役に立たないでしょう。しかし、適切に記述されたAPIのインターフェイスは、そのコードの使用をどのように妨げますか? ある目的のために作成されたものを別の目的で使用する の歴史全体に例があります。しかし、ソフトウェアの世界では、意図されていない目的で何かを使用すると、通常は壊れてしまいます。

私は、一部のコードの正当であるが意図しない使用を防止する優れたインターフェースの1つの良い例を探しています。それは存在しますか?描けません。

43
GlenPeterson

リッチヒッキーの完全なプレゼンテーションを見ていませんが、彼を正しく理解していて、29分のマークについて彼が言っていることから判断すると、彼はtypes再利用を中止します。彼は「インターフェース」という用語を「名前付きタイプ」の同義語として大まかに使用しています。

タイプPerson{ "name":"John" }とタイプDog{ "name": "Rover" }の2つのエンティティがある場合、Javaランドでは、共通のインターフェースまたは祖先を共有しない限り、相互運用できません。 (Mammalのように、より多くのコードを書くことを意味します)。したがって、ここのインターフェース/タイプは「再利用を殺す」ことです:PersonDogは同じように見えますが、それをサポートする追加のコードを作成しない限り、一方を他方と交換して使用することはできません。注:ヒッキーは、Java多くのクラスが必要なプロジェクトについても冗談を言っています(「ここで、誰がJava 20クラスだけを使用するアプリケーションですか?)」と書いています)。上記の結果。

ただし、「値指向」の言語では、これらの構造に型を割り当てません。それらはたまたま同じ構造を共有する単なる値であり(私の例では、両方ともnameフィールドに文字列値が設定されています)、したがって、簡単に相互運用できます。同じコレクションに追加したり、同じメソッドに渡したりすることができます。

要約すると、これは 構造的等価性明示的なタイプ/インターフェースの等価性 に関するもののようです。私がまだ見たことがないビデオの部分から何かを見逃していない限り:)

32
Andres F.

彼は、インターフェースをインスタンス化できないという基本的な事実に言及している可能性があります。インターフェイスをreuseすることはできません。実装できるのはそれをサポートするコードのみであり、インターフェースのコードを作成するときに再利用することはできません。

Javaには、インターフェースを引数として取る多くのAPIのフレームワークを提供してきた歴史がありますが、APIを開発したチームは、これらのインターフェースでreuseを実行するための幅広いクラスを実装することはありません。

これは、ダイアログボックス用のIWindowインターフェイスを持つGUIフレームワークのようなもので、コントロール用のIButtonインターフェイスを追加できます。ただし、Buttonを実装する優れたIButtonクラスは提供されていません。したがって、自分で作成することになります。

コア機能を提供する幅広い基本クラスを持つ抽象フレームワークは、再利用性が高く、フレームワークを使用する抽象クラスにアクセスできる場合に最も効果的に機能します。

Java開発者は、APIレイヤーがinterfacesのみを公開するというこのことを始めました。これらのインターフェースを実装することはできますが、それらのインターフェースを実装した開発者のクラスを再利用することはできません。 APIのクロークとダガースタイルのようなものです。

28
Reactgular

彼のプレゼンテーションのスライド13( 値の値 )は、これを理解するのに役立ちます。

http://i.stack.imgur.com/LVMne.png


価値観

  • メソッドを必要としないメソッド
    • コードなしで値を送信できます
      そしてあなたは元気です

私の理解では、Hickeyは、たとえば、私に送信した値をdoubleする必要がある場合は、次のようなコードを書くことを提案しています

    MyValue = Double(YourValue)

上記のコードは、どのような種類の値を送信しても同じです-完全な再利用のようなものです。

さて、これはオブジェクトとインターフェースを持つ言語でどのように見えるでしょうか?

    Doublable MyValue = YourValue.Double()

あ、待って! YourValueDoublableを実装していない場合はどうなりますか? 2倍にできないということではなく、完全に2倍になるかもしれませんが...メソッドがない場合はどうなりますか?Double? (say TwiceAsMuchというメソッドがある場合はどうなりますか?)

ええと、問題があります。 YourValue.Doubleは機能せず、再利用できません再利用できません。上記のスライドの私の読みによると、これはヒッキーが「これらすべてのインターフェースがあなたの再利用を殺してしまう!」と言ったときの意味です。

ご覧のとおり、インターフェースは、オブジェクトが「メソッドとともに」、それらを操作するコードとともに渡されることを前提としています。オブジェクトを使用するには、そのコードを呼び出す方法、呼び出すメソッドを理解する必要があります。

期待されるメソッドが欠落している場合、がセマンティック的にであっても、オブジェクトに対して目的の操作が完全に有効であっても問題があります。プレゼンテーションで述べたように、値はneedメソッドではありません(「コードなしで値を送信でき、問題ありません」)。マナー。


補足:コードのない値を渡すことの概念は、何らかの形でOOPの Flyweightパターン を思い出させます。

他の同様のオブジェクトと可能な限り多くのデータを共有することにより、メモリの使用を最小限に抑えるオブジェクト。これは、単純な繰り返し表現が許容できない量のメモリを使用する場合に、オブジェクトを大量に使用する方法です... Flyweightオブジェクトは、定義により 値オブジェクト です。オブジェクトインスタンスのIDは重要ではないため、同じ値の2つのFlyweightインスタンスは等しいと見なされます...

私が見たFlyweightの使用法は、通常、オブジェクトからコード(メソッド、インターフェース)を取り除き、コードなしの値を渡してものを渡すという同じアプローチに従いましたその受信コードには、これらを操作するために必要な手段があります。

これは、スライドの「値にはメソッドは必要ありません。コードなしで値を送信できます。問題はありません」のように感じます。

14
gnat

(つまり、私の)理想的な世界では、クラスとインターフェイスは常に動作を記述しますが、実際には、それらが実際にデータを記述するだけであることが多々あります。昨日だけ、誰かがいわゆるBankAccountクラスを作成したビデオを見ました。これは、美化されたintにすぎませんでした(実際、intよりもはるかに役に立たなかったため、 'すべてを「良い」デザインの名の下に単にint)として残しておけばよかったであろう再利用を殺します。データの複雑な表現の継続的な再発明に費やされるコード、汗、涙の量は驚異的です。意味のある方法でデータを使用していない場合は、そのままにしてください。

今、リッチヒッキーが赤ちゃんをお風呂に入れて投げ出し、価値のある土地(名詞の王国の隣)に住むべきだと言っている段階です。一方で、OOPは、賢明な方法で使用すると、再利用(および重要な発見可能性、関数型プログラミングに欠けていることがわかります)を促進できます)と思います。OOPこの緊張を最もよく捉える原則は、私はそれをかもしれないと思う http://c2.com/cgi/wiki?TellDontAsk (もちろん、これはDemeterの近い従兄弟です)

2
CurtainDog