Apa yang dimaksud Rich Hickey ketika dia berkata, "Semua kekhususan [antarmuka / kelas / tipe] ini membunuh Anda!"

41

Dalam konferensi goto yang dipikirkan oleh Rich Hickey, keynote conference " The Value of Values " pada 29 menit dia berbicara tentang overhead bahasa seperti Java dan membuat pernyataan seperti, "Semua antarmuka membunuh penggunaan kembali Anda." Apa yang dia maksud Benarkah?

Dalam pencarian saya untuk jawaban, saya telah menemukan:

  • Prinsip Pengetahuan Paling Tidak AKA Hukum Demeter yang mendorong antarmuka API kedap udara. Wikipedia juga mencantumkan beberapa kerugian.

  • Imperial Clothing Crisis Kevlin Henney yang berpendapat bahwa penggunaan, bukan penggunaan kembali adalah tujuan yang tepat.

  • Pembicaraan " Stop Writing Classes " Jack Diederich yang menentang over-engineering secara umum.

Jelas, apa pun yang ditulis dengan cukup buruk tidak akan berguna. Tetapi bagaimana antarmuka API yang ditulis dengan baik mencegah kode tersebut tidak digunakan? Ada beberapa contoh sepanjang sejarah tentang sesuatu yang dibuat untuk satu tujuan lebih banyak digunakan untuk sesuatu yang lain . Tetapi di dunia perangkat lunak, jika Anda menggunakan sesuatu untuk tujuan yang tidak dimaksudkan, biasanya rusak.

Saya sedang mencari satu contoh bagus dari antarmuka yang bagus untuk mencegah penggunaan kode yang sah tetapi tidak disengaja. Apakah itu ada? Saya tidak bisa membayangkannya.

GlenPeterson
sumber
1
Belum menonton / membaca barang-barang (saya sudah menambahkan "Stop Writing Classes" ke daftar to-watch saya :)), tetapi mungkin mereka berdebat dari sudut pengetikan dinamis vs statis? ...lagi?
Andres F.
oO Antarmuka antarmuka pemrograman aplikasi
Thomas Eding
Terima kasih atas tautannya! Saya tidak menemukan pembicaraan Jack Diederich sangat mencerahkan (perhatikan bagaimana ia gagal menjawab pertanyaan asli penonton dengan meyakinkan .. "eh, ya, mungkin dalam kasus itu ...". Saya memang sepertinya dia sedang memperdebatkan Pemrograman Fungsional tanpa bahkan menyadarinya;)), tetapi "Imperial Clothing Crisis" sangat bagus dan berwawasan luas.
Andres F.
1
MPO adalah bahwa orang yang tidak percaya pada penggunaan kembali tidak memecah hal-hal menjadi unit yang cukup kecil. Suatu hal besar yang dibangun untuk satu tujuan tertentu tidak dapat digunakan kembali. Namun, hal-hal kecil biasanya memiliki tujuan yang cukup kecil sehingga tujuan kecil berguna dalam lebih dari satu konteks.
Amy Blankenship
1
@AmyBlankenship Saya menemukan "Imperial Clothing Crisis" yang terkait di atas bersifat berwawasan luas. Penulis menganggap "menggunakan kembali" idola palsu (sesuatu yang belum terbukti berguna dalam praktiknya, dan juga kebanyakan orang bahkan tidak memahaminya meskipun mereka menggunakan kata itu). Dia juga tidak menganggap perpustakaan "digunakan kembali"; Anda menggunakan perpustakaan, Anda tidak menggunakannya kembali . Dia juga mempertimbangkan merancang sesuatu untuk digunakan kembali "pedang bermata dua"; sesuatu yang biasanya dianggap orang sebagai situasi menang-menang tetapi sebenarnya tidak: ketika Anda merancang sesuatu untuk digunakan kembali, itu selalu kompromi (misalnya, Anda mungkin kalah dalam kesederhanaan)
Andres F.

Jawaban:

32

Belum menonton presentasi lengkap Cupang Kaya, tetapi jika saya memahaminya dengan benar, dan menilai dari apa yang dia katakan tentang tanda 29 menit, dia sepertinya berdebat tentang jenis pembunuhan yang menggunakan kembali. Dia menggunakan istilah "antarmuka" secara longgar sebagai sinonim untuk "nama tipe", yang masuk akal.

Jika Anda memiliki dua entitas { "name":"John" }tipe Person, dan { "name": "Rover" }tipe Dog, di Java-land mereka mungkin tidak dapat beroperasi kecuali mereka berbagi antarmuka atau leluhur yang sama (seperti Mammal, yang berarti menulis lebih banyak kode). Jadi antarmuka / jenis di sini adalah "membunuh penggunaan ulang Anda": meskipun Persondan Dogterlihat sama, satu tidak dapat digunakan secara bergantian dengan yang lain, kecuali Anda menulis kode tambahan untuk mendukungnya. Catatan Hickey juga bercanda tentang proyek-proyek di Jawa yang membutuhkan banyak kelas ("Siapa di sini yang telah menulis aplikasi Java hanya menggunakan 20 kelas?"), Yang tampaknya merupakan konsekuensi dari hal di atas.

Namun, dalam bahasa "berorientasi nilai", Anda tidak akan menetapkan tipe pada struktur itu; mereka hanya nilai yang kebetulan berbagi struktur yang sama (dalam contoh saya, mereka berdua memiliki namebidang dengan nilai String) dan karenanya dapat dengan mudah dioperasikan, misalnya mereka dapat ditambahkan ke koleksi yang sama, diteruskan ke metode yang sama, dll.

Singkatnya, semua ini tampaknya menjadi sesuatu tentang kesetaraan struktural vs jenis / antarmuka kesetaraan eksplisit . Kecuali saya melewatkan sesuatu dari bagian-bagian video yang belum saya tonton :)

Andres F.
sumber
2
BTW, pembicaraan Jack Diederich "Stop Writing Classes" tampaknya tidak terkait dengan topik ini, dan lebih banyak tentang YAGNI dan "jangan menulis kode sampai Anda membutuhkannya, dan kemudian hanya menulis kode sederhana".
Andres F.
9
ERROR: Object doesn't have a property called "name"seringkali merupakan hasil dari value-orientedbahasa, dan masalah lainnya adalah ketika Anda tidak ingin lagi memanggil properti itu name. Selamat mencoba refactoring karena kemungkinan ada ratusan objek dengan properti nametetapi tidak semua Personatau Dog.
Reactgular
2
@MathewFoscarini Ya, saya tidak harus setuju dengan itu, itu hanya interpretasi saya tentang apa yang saya pikir Hickey katakan :) Saya suka tipe dan pengetikan statis; Saya baru mulai tidak menyukai Jawa. Dan ketidaksukaan saya tidak terkait dengan interfacetetapi untuk kekacauan itu adalah proyek Java yang khas.
Andres F.
1
Java adalah bahasa pemrograman untuk mereka yang lebih suka berpikir terlalu banyak. Ini adalah salah satu dari sedikit bahasa yang memungkinkan pengembang untuk dengan mudah menyembunyikan upayanya untuk merekayasa proyek secara berlebihan.
Reactgular
"Dalam bahasa 'berorientasi nilai' Anda tidak akan menetapkan tipe pada struktur itu" - Saya pikir Anda perlu mengatakan "Dalam dinamis 'berorientasi nilai' ..." Haskell dan Scala berorientasi nilai, tetapi sistem tipe statisnya memberi mereka masalah yang Anda jelaskan. Saya pikir solusi untuk masalah ini bukan nilai-nilai seperti menggunakan peta untuk meneruskan parameter ke fungsi. Menggunakan peta (nilai) yang tidak berubah hanya lebih aman.
GlenPeterson
28

Dia kemungkinan merujuk pada fakta dasar bahwa sebuah antarmuka tidak dapat dipakai. Anda tidak dapat reusemenggunakan antarmuka. Anda hanya dapat mengimplementasikan kode yang mendukungnya, dan ketika Anda menulis kode untuk antarmuka tidak ada penggunaan kembali.

Java memiliki sejarah menyediakan kerangka kerja banyak API yang menggunakan antarmuka sebagai argumen, tetapi tim yang mengembangkan API tidak pernah menerapkan berbagai kelas untuk digunakan kembali dengan antarmuka tersebut.

Ini seperti kerangka kerja GUI yang memiliki IWindowantarmuka untuk kotak dialog, dan kemudian Anda dapat menambahkan IButtonantarmuka untuk kontrol. Kecuali, mereka tidak pernah memberimu Buttonkelas bagus yang mengimplementasikan IButton. Jadi, Anda tinggal membuat sendiri.

Kerangka yang diabstraksi yang memiliki berbagai kelas dasar yang menyediakan fungsionalitas inti lebih dapat digunakan kembali, dan yang bekerja paling baik ketika kelas-kelas yang diabstraksi dapat diakses oleh mereka yang menggunakan kerangka kerja.

Pengembang Java mulai melakukan hal ini di mana lapisan API mereka hanya terbuka interfaces. Anda bisa mengimplementasikan antarmuka itu, tetapi Anda tidak pernah bisa menggunakan kembali kelas dari pengembang yang mengimplementasikan antarmuka itu. Ini semacam gaya jubah dan belati pengembangan API.

Reactgular
sumber
4
Terima kasih atas jawaban ini. Saya sekarang merasa seperti saya memahami pertanyaan dan jawabannya :)
MetaFight
2
+1 Saya sangat menghargai jawaban Anda dan menambahkan lapisan informasi menarik yang menarik untuk pertanyaan ini. Tetapi saya pikir jawaban Andreas F. cenderung lebih dekat ke jantung dari apa yang dimaksud Tuan Hickey, jadi saya menerima jawabannya.
GlenPeterson
@ GlenPeterson tidak masalah, saya pikir dia mungkin akan tandai juga.
Reactgular
1
Nah ini dan jawaban yang diterima menyoroti dua interpretasi yang sedikit berbeda, tetapi sama-sama menarik. Saya ingin tahu yang mana yang dipikirkan Tn. Hickey ketika berbicara tentang ini ..
David Cowden
Anda tidak dapat menggunakan kembali antarmuka, tetapi Anda dapat memperluasnya (dan memberikan nomor versi yang berharga) tanpa mengubah kelas lama. Anda juga dapat mewarisi dari banyak antarmuka untuk menambahkan pekerjaan baru untuk kelas baru, atau menambahkan warisan baru di kelas lama yang dikompilasi ulang. Anda juga dapat memperluas kelas yang mengimplementasikan antarmuka ini untuk pekerjaan baru.
cl-r
14

Saya pikir slide 13 di presentasinya ( Nilai Nilai ) membantu untuk memahami ini:

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


Nilai-nilai

  • Tidak perlu metode
    • Saya dapat mengirimkan Anda nilai tanpa kode
      dan Anda baik-baik saja

Pemahaman saya adalah, Hickey menyarankan bahwa jika saya perlu, katakanlah, gandakan nilai yang Anda kirimkan kepada saya, saya cukup menulis kode yang terlihat seperti

    MyValue = Double(YourValue)

Anda lihat, kode di atas sama, tidak peduli apa pun nilai yang Anda kirim - semacam penggunaan kembali yang sempurna .

Sekarang, bagaimana ini akan terlihat seperti dalam bahasa yang memiliki objek dan antarmuka?

    Doublable MyValue = YourValue.Double()

Oh tunggu! bagaimana jika YourValuetidak diterapkan Doublable? bukan karena itu tidak dapat digandakan, itu mungkin saja tapi ... bagaimana jika tidak ada metode Double ? (Bagaimana jika ada metode yang disebut katakan TwiceAsMuch?)

Uh oh kita punya masalah. YourValue.Doubletidak akan berfungsi, tidak dapat digunakan kembali lagi. Per bacaan saya tentang slide di atas, ini adalah tentang apa yang dimaksudkan Hickey ketika dia berkata, "Semua antarmuka itu membunuh Anda!"

Anda lihat, antarmuka berasumsi bahwa objek dilewatkan "bersama dengan metode mereka", bersama dengan kode yang beroperasi pada ini. Untuk menggunakan objek, orang perlu memahami cara menjalankan kode itu, metode apa yang harus dihubungi.

Ketika metode yang diharapkan hilang, ada masalah, meskipun secara semantik , operasi yang diinginkan masuk akal untuk suatu objek. Seperti yang dinyatakan dalam presentasi, nilai tidak memerlukan metode ("Saya bisa mengirimkan Anda nilai tanpa kode dan Anda baik-baik saja"), memungkinkan untuk menulis kode yang berurusan dengan mereka secara umum.


Catatan: gagasan untuk memberikan nilai yang kurang kode, entah bagaimana, mengingatkan saya pada pola Flyweight di OOP.

objek yang meminimalkan penggunaan memori dengan berbagi data sebanyak mungkin dengan objek serupa lainnya; ini adalah cara untuk menggunakan objek dalam jumlah besar ketika representasi berulang yang sederhana akan menggunakan jumlah memori yang tidak dapat diterima ... Objek kelas terbang adalah objek nilai definisi . Identitas instance objek tidak ada konsekuensinya oleh karena itu dua instance Flyweight dengan nilai yang sama dianggap sama ...

Penggunaan kelas terbang yang pernah saya lihat biasanya mengikuti pendekatan yang sama dengan menghilangkan kode (metode, antarmuka) dari objek dan mengedarkan barang-barang sekitar, juga, nilai-nilai tanpa kode , berharap bahwa menerima kode memiliki cara yang diperlukan untuk mengoperasikannya.

Ini terasa seperti pada slide, "nilai tidak perlu metode. Saya bisa mengirimkan Anda nilai tanpa kode dan Anda baik-baik saja".

agas
sumber
5
Generik akan menangani masalah itu. Penggandaan masuk akal pada beberapa objek, tetapi tidak pada objek lain. Dalam bahasa Go, ada implementasi antarmuka implisit (bentuk pengetikan bebek), sehingga Anda tidak perlu khawatir semua antarmuka itu. Di sisi lain, Anda agak harus tahu objek mana yang akan terkena tanda tangan metode Anda; jika tidak, Anda mungkin mendapatkan hasil yang tidak terduga. Selalu ada pengorbanan.
Robert Harvey
1
Pengambilan yang menarik. Jawaban yang bagus!
maple_shaft
2
Pola kelas terbang bukan yang dibicarakan oleh Rich. Sebagaimana kalimat kedua dari artikel tersebut menyatakan, tujuan dari pola kelas terbang adalah untuk menghemat memori. Pendekatan Rich tidak berusaha melakukan itu.
5
MyValue = Double(YourValue)tidak masuk akal jika Nilai Anda adalah String, Alamat, Pengguna, Fungsi, atau Database. Jika tidak, argumen metode-hilang Anda adalah kuat. OTOH, metode pengaksesor memungkinkan Anda menegakkan berbagai kendala sehingga Nilai Anda valid, dan hanya operasi yang masuk akal yang digunakan untuk menghasilkan Nilai baru. Jika Anda kemudian memutuskan untuk memisahkan Alamat dari Pengguna dan Perusahaan Anda, metode accessor berarti Anda tidak melanggar semua klien kode Anda. Jadi mereka dapat membantu menggunakan kembali dalam jangka panjang bahkan jika mereka kadang-kadang menghambatnya dalam jangka pendek.
GlenPeterson
4
(Di sisi lain, saya setuju bahwa di Jawa-tanah, ledakan kelas, antarmuka dan kerangka kerja adalah mimpi buruk. Solusi "enterprisey" paling sederhana di Jawa adalah kekacauan kode. Jadi saya mengambil pelajaran berharga dari ini pertanyaan & jawaban, tanpa harus setuju dengan hal-hal pengetikan dinamis)
Andres F.
2

Dalam kelas dunia yang ideal (dan saya) interface dan akan selalu menggambarkan perilaku, tetapi kenyataannya adalah bahwa terlalu sering mereka akhirnya hanya menggambarkan data. Baru kemarin saya menonton video seseorang membangun BankAccountkelas yang disebut tidak lebih dari yang dimuliakan int(memang itu jauh lebih tidak berguna daripada int, sehingga 'membunuh' penggunaan kembali yang saya miliki seandainya dibiarkan begitu saja sebagai int), semua atas nama desain 'baik'. Jumlah kode, keringat, dan air mata yang terbuang untuk menciptakan kembali representasi data yang berbelit-belit sangat mengejutkan; jika Anda tidak menggunakan data dengan cara yang berarti maka biarkan saja.

Sekarang, ini adalah tahap di mana Rich Hickey puas untuk membuang bayi keluar dengan air mandi dan mengatakan bahwa kita semua harus tinggal di tanah nilai (tetangga ke kerajaan kata benda). Saya pikir, di sisi lain, bahwa OOP dapat dan memang mempromosikan penggunaan kembali (dan yang penting dapat ditemukan kembali, yang saya temukan kurang dalam pemrograman fungsional) ketika dipekerjakan dengan bijaksana. Jika Anda mencari prinsip OOP yang paling baik menangkap ketegangan ini, saya pikir itu mungkin http://c2.com/cgi/wiki?TellDontAsk (yang tentu saja merupakan sepupu dekat Demeter)

CurtainDog
sumber
Apa yang Anda maksud dengan kemampuan menemukan? Apakah ini mirip dengan ini ?
1
Ya, saya pikir itu menyentuh banyak poin utama. Ini adalah hal yang halus tetapi dapat ditemukan adalah tindakan penyeimbang, membuat hal-hal yang terlalu transparan juga tidak diinginkan karena Anda akan mendapatkan sinyal buruk terhadap rasio kebisingan.
CurtainDog