Rich Hickeyは、「[インターフェイス/クラス/タイプ]のすべての特異性があなたの再利用を殺します!」と言ったとき、何を意味しましたか?


41

Rich Hickeyの思考を刺激するgoto会議の基調講演「価値の価値」で29分間、彼はJavaのような言語のオーバーヘッドについて話し、「これらのインターフェースはすべて再利用を殺します」のような声明を出します。彼はどういう意味ですか?本当?

私は答えを探して、次のことを見つけました。

  • 最小知識の原則別名、気密APIインターフェイスを奨励するデメテルの法則。ウィキペディアには、いくつかの欠点もリストされています。

  • 再利用ではなく、その使用が適切な目標であると主張するケヴリン・ヘニーのインペリアル衣料危機

  • ジャック・ディーデリッヒの「クラスを書くのをやめなさい」は、一般的なオーバーエンジニアリングに反対する議論をしています。

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

私は、いくつかのコードの正当であるが意図しない使用を防ぐ良いインターフェースの良い例を探しています。それは存在しますか?想像できません。


1
見ていない/読んでいない(to-watchリストに "Stop Writing Classes"を追加した)...再び?
アンドレスF.

oOアプリケーションプログラミングインターフェイスインターフェイス
トーマスエディング

リンクをありがとう!ジャック・ディーデリッヒの話は特に輝いていませんでした(彼が聴衆の真の質問に説得力を持って答えていない様子を見てください。「ええ、ええ、その場合は...」。それに気づいてさえ;))、しかし、「帝国の服の危機」は非常によく、洞察力があります。
アンドレスF.

1
MPOは、再利用を信じていない人が、物事を十分に小さなユニットに分解しないことです。特定の目的のために構築された大きなものは再利用できません。ただし、小さなものには通常、小さな目的が複数のコンテキストで役立つほど小さい目的があります。
エイミーブランケンシップ

1
@AmyBlankenship私は、上記の「帝国の衣服の危機」が洞察に満ちていることを発見しました。著者は「再利用」を偽のアイドル(実際には有用であると証明されていないものであり、ほとんどの人は言葉を使っても理解できない)と考えています。彼はまた、ライブラリを「再利用」とは考えていません。ライブラリを使用し再利用しません。彼はまた、「両刃の剣」を再利用するために何かを設計することを考えています。あなたが再利用のために何かを設計するとき、それは常に(あなたが簡潔に失う可能性など)妥協案です:人々は通常、Win-Winの状況を考慮したが、実際にはないことを何か
アンドレスF.

回答:


32

Rich Hickeyの完全なプレゼンテーションを見たことはありませんが、私が彼を正しく理解し、29分のマークについて彼が言うことから判断すると、彼はタイプが再利用を殺すことについて議論しているようです。彼は「インターフェース」という用語を「名前付きタイプ」の同義語として大まかに使用していますが、これは理にかなっています。

Javaランドにtype と{ "name":"John" }typeの2つのエンティティがある場合、共通のインターフェイスまたは祖先(のような、より多くのコードを記述すること)を共有しない限り、おそらく相互運用できません。ここでのインターフェイス/タイプ「あなたの再利用を殺す」されるように:たとえと同じように見えますが、それをサポートするための追加のコードを記述しない限り、人は、他と互換的に使用することはできません。注Hickeyは、多くのクラスを必要とするJavaのプロジェクトについても冗談を言います(「20個のクラスのみを使用してJavaアプリケーションを作成したのは誰ですか?」)。これは上記の結果の1つです。Person{ "name": "Rover" }DogMammalPersonDog

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

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


2
ところで、Jack Diederichの講演「Stop Writing Classes」はこのトピックとは無関係のようで、YAGNIと「必要になるまでコードを書かないで、単純なコードを書くだけ」についてです。
アンドレスF.

9
ERROR: Object doesn't have a property called "name"多くの場合、value-oriented言語の結果であり、他の問題は、そのプロパティを呼び出さなくてもよい場合ですname。プロパティを持つオブジェクトは数百個ある可能性nameがありますが、すべてがPersonまたはではないため、リファクタリングは幸運Dogです。
Reactgular

2
@MathewFoscariniええ、私は必ずしもそれに同意するわけではありません、それは私がヒッキーが言っていたと思うことの私の解釈にすぎません:)私は型と静的型付けが好きです。Javaが嫌いになり始めたばかりです。そして、私の嫌いはinterfaces とは関係ありませんが、典型的なJavaプロジェクトである混乱とは無関係です。
アンドレスF.

1
Javaは、考えすぎることを好む人のためのプログラミング言語です。開発者がプロ​​ジェクトをオーバーエンジニアリングしようとする試みを簡単に隠すことができる数少ない言語の1つです。
Reactgular

「「値指向」言語では、これらの構造に型を割り当てません」-「動的な「値指向」では...」と言う必要があると思いますHaskellとScalaは値指向ですが、静的型システムあなたが説明している正確な問題を彼らに与えます。この問題の解決策は、マップを使用して関数にパラメーターを渡すほど値ではないと思います。不変のマップ(値)を使用する方が安全です。
グレンペターソン

28

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

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

IWindowダイアログボックスのインターフェイスを備えたGUIフレームワークのようなもので、IButtonコントロールのインターフェイスを追加できます。を除いて、彼らはあなたにButton実装する良いクラスを決して与えませんでしたIButton。そのため、独自の作成が必要です。

コア機能を提供する幅広い基本クラスを持つ抽象化されたフレームワークはより再利用可能であり、それらの抽象化されたクラスにフレームワークを使用している人がアクセスできる場合に最適に機能します。

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


4
この答えをありがとう。私は今、質問答えを理解したように感じます:)
MetaFight

2
+1私はあなたの答えを本当に感謝し、この質問に興味深い情報の魅力的な層を追加します。しかし、アンドレアス・Fの答えは、ヒッキー氏の意図の中心に近いと思われるので、代わりに受け入れました。
グレンペターソン

@GlenPetersonは問題ありません、彼も同様に成功していると思います。
-Reactgular

1
まあ、これと受け入れられた答えは、わずかに異なるが、同様に興味深い解釈を2つ強調しています。このことについて話すとき、ヒッキー氏が考えていたのはどれか..
デビッドカウデン

インターフェースを再利用することはできませんが、古いクラスを変更せずにインターフェースを拡張(および貴重なバージョン番号を付与)できます。また、多くのインターフェイスから継承して、新しいクラスに新しいジョブを追加したり、古い再コンパイルされたクラスに新しい継承を追加したりできます。また、新しいジョブ用にこのインターフェイスを実装するクラスを拡張することもできます。
cl-r

14

彼のプレゼンテーション(The Value of Values)のスライド13はこれを理解するのに役立つと思います。

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


  • メソッド は必要ありません
    • コードなしで値を送信でき
      ますが、問題ありません

私の理解では、ヒッキーは、あなたが私に送った値を2倍にする必要がある場合、私は単に次のようなコードを書くことを示唆しています

    MyValue = Double(YourValue)

ご覧のとおり、送信した値の種類に関係なく、上記のコードは同じです- 完璧な再利用のようなものです。

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

    Doublable MyValue = YourValue.Double()

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

ああ、問題があります。YourValue.Double動作しなくなり、再利用できなくなります。上記のスライドを読んだことによると、これはHickeyが「すべてのインターフェイスがあなたの再利用を殺す!」と言ったときの意味についてです。

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

期待されるメソッドが欠落している場合、意味論的には、目的の操作はオブジェクトにとって完全に理にかなっていますが、問題があります。プレゼンテーションで述べたように、値はメソッドを必要とせず(「コードなしで値を送信でき、問題ありません」)、一般的な方法で値を処理するコードを記述できます。


サイドノート:コードなしの値を渡すという概念は、どういうわけかOOPのFlyweightパターンを思い出させます。

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

私が見たフライウェイトの使用法は、通常、コード(メソッド、インターフェイス)をオブジェクトから取り除き、コードなしの値として周囲に物を渡すという同じアプローチに従いました。

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


5
ジェネリックはその問題をほとんど処理します。倍増は、一部のオブジェクトでは意味がありますが、他のオブジェクトでは意味がありません。Go言語には、暗黙的なインターフェイスの実装(アヒルのタイピングの形式)があるため、これらすべてのインターフェイスを心配する必要はありません。一方、メソッドシグネチャによってヒットされるオブジェクトを知る必要があります。そうしないと、予期しない結果が生じる可能性があります。常にトレードオフがあります。
ロバートハーベイ

1
興味深いテイク。いい答えだ!
maple_shaft

2
フライウェイトパターンは、リッチが言っていることではありません。記事の2番目の文にあるように、フライウェイトパターンの目的はメモリを節約することです。リッチのアプローチはそれを追求していません。

5
MyValue = Double(YourValue)YourValueが文字列、アドレス、ユーザー、関数、またはデータベースの場合は意味がありません。それ以外の場合、欠落しているメソッドの引数は強力です。OTOHアクセサーメソッドを使用すると、さまざまな制約を適用して、Valuesを有効にし、適切な操作のみを使用して新しいValueを生成できます。後でアドレスをユーザーと会社から分離することにした場合、アクセサメソッドは、コードのすべてのクライアントを壊さないことを意味します。そのため、短期的には時々それを妨げる場合でも、長期的に再利用することができます。
グレンペターソン

4
(一方、Javaランドでは、クラス、インターフェース、フレームワークの爆発は悪夢であることに同意します。Javaで最も単純な「エンタープライズ」ソリューションはコードの混乱です。したがって、これから貴重な教訓を得ることができます。必ずしも動的型付けのものと一致せず、質問&答え、)
アンドレスF.

2

(つまり、私の)理想的な世界では、クラスとインターフェースは常に振る舞いを記述しますが、実際には、ほとんどの場合、実際にデータを記述するだけです。昨日だけ、誰かBankAccountが称賛されるだけのいわゆるクラスを構築するビデオを見ましたint(実際、それはint、として残されていたはずの再利用を「殺します」int、すべて「良い」デザインの名の下に。データの複雑な表現を継続的に再発明することに費やされるコード、汗、涙の量は驚異的です。データを有意義な方法で使用していない場合は、そのままにしてください。

さて、これはリッチヒッキーがお風呂で赤ちゃんを放り出して、価値のある国(名詞の王国の隣人)に住むべきだと言うことに満足している段階です。一方で、OOPは賢明に採用された場合、再利用(そして重要なことに発見可能性、関数型プログラミングに欠けていることがわかります)を促進できます。この緊張を最もうまく捉えるOOP原則を探しているなら、http://c2.com/cgi/wiki?TellDontAsk(もちろんDemeterの親co)


発見可能性とはどういう意味ですか?これに似てますか?

1
はい、私はそれが多くの要点に触れていると思います。それは微妙な点ですが、発見可能性はバランスをとる行為であり、物事を透明にしすぎることは、悪いS / N比を得るためにも望ましくありません。
CurtainDog
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.