Rich Hickey, “Arayüzlerin / sınıfların / türlerin bütün bu özelliği, yeniden kullanımınızı öldürür!” Derken ne demek istedi?


41

Rich Hickey’in 29. dakikada “ Değerlerin Değeri ” konulu açılış konuşmasında , Java gibi bir dilin tepesinden bahsediyor ve “Tüm bu arayüzler yeniden kullanımınızı öldürüyor” gibi bir ifade veriyor. Ne demek istiyor? Bu doğru mu?

Cevapları araştırmamda, aşağıdakileri geçtim:

  • En Az Bilgi Prensibi AKA Hava geçirmez API arayüzlerini teşvik eden Demeter Kanunu . Wikipedia da bazı dezavantajları listeler.

  • Kevlin Henney'nin kullanılmasının, yeniden kullanılmamasının savunulan İmparatorluk Kıyafetleri Krizi uygun amaçtır.

  • Jack Diederich'in genel olarak aşırı mühendislik karşıtı olan "Yazmayı Durdurma Sınıfları " konuşması.

Açıkça, yeterince kötü yazılmış herhangi bir şey işe yaramaz. Peki, iyi yazılmış bir API'nin arayüzü bu kodun kullanılmasını nasıl önler? Tarih boyunca , bir amaç için başka bir şey için daha fazla kullanılan bir şeyin yapılmış örnekleri vardır . Ancak yazılım dünyasında, amaçlanmadığı bir amaç için bir şey kullanırsanız, genellikle kırılır.

Bazı kodların meşru fakat istenmeden kullanılmasını önleyen iyi bir arayüz örneği için iyi bir örnek arıyorum. Bu var mı? Ben hayal edemiyorum.


1
Bunları izlemedim / okumamıştım (izleme listeme "Sınıf Yazmayı Durdur" u da ekledim :)), ama belki dinamik ve statik bir yazım açısıyla mı tartışıyorlar? ...tekrar?
Andres F.

oO Uygulama programlama arayüzü arayüzleri
Thomas Eding

Bağlantılar için teşekkürler! Jack Diederich'in konuşmasını özellikle aydınlatıcı bulmadım (izleyicinin orijinal sorularına ikna edici bir şekilde nasıl cevap veremediğini izleyin .. "ah, evet, belki de bu durumda ...". İşlevsel Programlama olmadan tartışıyor gibiydi.) farkına bile varmakla;)) ama "İmparatorluk Kıyafet Krizi" çok iyi ve anlayışlı.
Andres F.

1
MPO, yeniden kullanıma inanmayan insanların işleri yeterince küçük birimlere bölmemeleridir. Belirli bir amaç için yapılmış büyük bir şey tekrar kullanılamaz. Bununla birlikte, küçük şeyler genellikle küçük amacın birden fazla bağlamda faydalı olması için yeterince küçük bir amaca sahiptir.
Amy Blankenship

1
@AmyBlankenship Ben yukarıda bağlantılı "İmparatorluk Giyim Kriz" anlayışlı buldum. Yazar, sahte bir idolü “yeniden kullanma” (pratikte faydalı olduğu kanıtlanmamış bir şey olarak kabul eder) ve aynı zamanda çoğu insan kelimesini kullansalar bile anlamıyor bile. Ayrıca “yeniden kullanma” kütüphanelerini de dikkate almaz; Eğer kullanmak kütüphane, sen yok yeniden onu. Ayrıca "iki ucu keskin bir kılıcı" yeniden kullanmak için bir şeyler tasarlamayı düşünüyor; İnsanların genellikle kazan-kazan durumu olarak gördüğü ama gerçekte olmayan bir şey: yeniden kullanım için bir şey tasarladığınızda, bu her zaman bir uzlaşmadır (örneğin sadelik içinde kaybedebilirsiniz)
Andres F.

Yanıtlar:


32

Rich Hickey sunumunun tamamını izlemedim, ama onu doğru anlarsam ve 29 dakikalık işaret hakkında söylediklerini değerlendirirsek, yeniden kullanım türlerini öldürmeyi tartışıyor gibi görünüyor . “Arayüz” terimini gevşek bir şekilde “adlandırılmış tür” ile eşanlamlı olarak kullanıyor, bu mantıklı.

İki varlık varsa { "name":"John" }Çeşidi Personve { "name": "Rover" }Çeşidi DogJava topraklarda, muhtemelen ortak bir arayüz veya atası (gibi paylaşamaz birlikte çalışan sürece Mammal, daha fazla kod yazma aracı). Bu yüzden buradaki arayüzler / tipler "yeniden kullanımınızı öldürüyor": aynısını görseniz Personve Doggörseniz bile , bunu desteklemek için ek bir kod yazmazsanız biri diğerine göre kullanılamaz. Not Hickey ayrıca Java'da birçok sınıfa ihtiyaç duyan projeler hakkında şakalar yapar ("Burada kim sadece 20 sınıf kullanarak bir Java uygulaması yazdı?"), Bu da yukarıdakilerin bir sonucu gibi görünüyor.

Ancak “değer odaklı” dillerde, bu yapılara tipler atamazsınız; bunlar sadece aynı yapıyı paylaşan değerlerdir (benim örneğimde her ikisinin de namebir String değeri olan bir alanı vardır) ve bu nedenle kolayca birlikte çalışabilirler, örneğin aynı koleksiyona eklenebilirler, aynı yöntemlere geçtiler, vb.

Özetle, bütün bunlar yapısal eşitlik ve açık tip / arayüz eşitliği hakkında bir şey gibi görünüyor . Videonun bölümlerinden henüz bir şey kaçırmadıysam, henüz izlemedim :)


2
BTW, Jack Diederich'in "Sınıf Yazmayı Durdur" konulu konuşması bu konuyla ilgisiz görünüyor ve YAGNI hakkında daha fazla şey ifade ediyor ve "ihtiyacınız olana kadar kod yazmıyor ve sonra yalnızca basit kod yazıyor".
Andres F.

9
ERROR: Object doesn't have a property called "name"genellikle value-orienteddillerin sonucudur ve diğer sorun, artık o özelliği aramak istemediğiniz zamandır name. Yenilemede iyi şanslar çünkü bir özelliğe sahip yüzlerce nesne var nameama hepsi değil Personya da Dog.
Tepki

2
@MathewFoscarini Evet, buna kesinlikle katılmıyorum, bu sadece Hickey’in söylediklerini yorumlamam; :) Türleri ve statik yazmayı seviyorum; Java'dan hoşlanmaya yeni başladım. Ve sevmediğim şey, interfaces ile değil, tipik Java projesi olan karışıklıkla ilişkili .
Andres F.

1
Java, fazla düşünmeyi tercih edenler için programlama dilidir. Bir geliştiricinin bir projeyi yeniden inşa etme girişimlerini kolayca gizlemesine izin veren birkaç dilden biridir.
Tepki

"'Değer odaklı' dillerde bu yapılara türler atamazsınız" - "Dinamik" değer odaklı "demeniz gerektiğini düşünüyorum. Haskell ve Scala değer odaklı, ancak statik tip sistemde onlara açıkladığınız kesin sorunu verir. Bu sorunun çözümünün, parametreleri işlevlere aktarmak için haritalar kullanmak kadar değer olmadığını düşünüyorum. Değişmez haritaları (değerler) kullanmak sadece daha güvenlidir.
GlenPeterson

28

Muhtemelen bir arayüzün başlatılamamasının temel gerçeğinden bahsediyor. reuseBir arayüz olamaz . Yalnızca onu destekleyen kodu uygulayabilirsiniz ve bir arabirim için kod yazdığınızda yeniden kullanım yoktur.

Java, bir argüman olarak ara yüz alan birçok API (ler) in çerçevelerini sağlama geçmişine sahiptir, ancak API'yi geliştiren ekip , bu arayüzlerle tekrar kullanmanız için hiçbir zaman geniş bir sınıf aralığı uygulamamaktadır .

IWindowBir iletişim kutusu için bir arayüze sahip olan bir GUI çerçevesi gibidir ve ardından IButtonkontroller için arayüzler ekleyebilirsiniz . Dışında, size asla Buttonuygulayan iyi bir sınıf vermediler IButton. Yani kendi yaratıcılığını kendin yarattın.

Çekirdek işlevsellikler sağlayan geniş bir temel sınıf yelpazesine sahip soyutlanmış çerçeveler daha tekrar kullanılabilir niteliktedir ve bu soyutlanmış sınıfları çerçeveyi kullananlar için erişilebilir olduğunda en iyi şekilde çalışır.

Java geliştiricileri bu şeyi API katmanlarının yalnızca ortaya çıkardığı yerlerde yapmaya başladı interfaces. Bu arabirimleri uygulayabilirsiniz, ancak bu arabirimleri uygulayan geliştiricinin sınıflarını hiçbir zaman yeniden kullanamazsınız. Bir çeşit pelerin ve hançer API geliştirme tarzı gibi.


4
Bu cevap için teşekkür ederim. Şimdi soruyu ve cevabı anladığımı hissediyorum :)
MetaFight

2
+1 Cevabınızı gerçekten takdir ediyorum ve bu soruya büyüleyici bir ilginç bilgi katmanı ekliyor. Fakat Andreas F.'in cevabının muhtemelen Bay Hickey'in ne anlama geldiğinin merkezine yakın olduğunu düşünüyorum, onun yerine onun yerine kabul ettim.
GlenPeterson

@GlenPeterson sorun değil, bence o da markanın üstünde olabilir.
Reactgular

1
Peki, bu ve kabul edilen cevap, birbirinden biraz farklı, ancak aynı derecede ilginç, yorumların altını çizer. Bu konuda konuşurken Bay Hickey'in aklında olanları merak ediyorum ..
David Cowden 22

Arabirimi yeniden kullanamazsınız, ancak eski sınıfları değiştirmeden genişletebilir (ve değerli sürüm numarası verebilirsiniz). Ayrıca, yeni sınıflar için yeni iş eklemek için birçok arayüzden miras alabilir veya eski yeniden derlenmiş sınıflarda yeni devralma ekleyebilirsiniz. Ayrıca, bu arabirimi uygulayan sınıfı yeni iş için genişletebilirsiniz.
cl-r,

14

Bence sunumunda 13 no'lu slayt ( Değerlerin Değeri ) bunu anlamaya yardımcı olur:

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


Değerler

  • Yapma ihtiyaç yöntemleri
    • Sana kod olmadan değerler gönderebilirim
      ve sen iyisin

Anladığım kadarıyla Hickey, bana gönderdiğiniz değeri iki katına çıkarmam gerekirse, basitçe şöyle bir kod yazmam gerektiğini söylüyor

    MyValue = Double(YourValue)

Görüyorsunuz, yukarıdaki kod aynı, ne tür bir değer yolladığınızın önemi yok - mükemmel bir yeniden kullanım .

Şimdi, bunun nesneleri ve arayüzleri olan dilde nasıl görüneceği?

    Doublable MyValue = YourValue.Double()

bekle! Ya YourValueuygulamıyorsa Doublable? iki katına çıkamayacağı, mükemmel olabileceği söylenemez ama ... ya da hiçbir yöntem yoksa Double? (ya denilen bir yöntem varsa TwiceAsMuch?)

Ah, bir sorunumuz var. YourValue.Doubleçalışmayacak, tekrar kullanılamaz . Yukarıdaki slaytı okuduğumda, bu, "Tüm bu arayüzler yeniden kullanımınızı öldürür!" Dediğinde Hickey'nin ne demek istediği ile ilgilidir.

Görüyorsunuz, arayüzler nesnelerin "metotlarıyla birlikte" etraflarında geçirildiğini varsayıyorlar ve bunlar üzerinde çalışan kodlarla. Nesneleri kullanmak için, o kodu nasıl çağıracağınızı, hangi yöntemi çağıracağınızı anlamanız gerekir .

Beklenen yöntem eksik olduğunda, bir sorun vardır, her ne kadar anlamsal olsa da , istenen işlem bir nesne için mükemmel bir anlam ifade eder. Sunumda belirtildiği gibi, değerler metotlara ihtiyaç duymaz ("Size kod olmadan kodları gönderebilirim ve iyisin"), bunlarla ilgili kodları genel bir şekilde yazmanıza olanak tanır.


Yan not: kodsuz değerlerin etrafında dolaşılması kavramı bana bir şekilde OOP'daki bir Flyweight modelini hatırlatıyor .

diğer benzer nesnelerle mümkün olduğu kadar veri paylaşarak bellek kullanımını en aza indiren bir nesne; Basit bir tekrarlanan gösterimin kabul edilemez miktarda bellek kullanması durumunda, nesneleri büyük sayılarla kullanmanın bir yoludur ... Flyweight nesneleri, tanım değer nesnelerine göredir . Nesne örneğinin kimliği sonuçsuzdur, bu nedenle aynı değerde iki Flyweight örneği eşit olarak kabul edilir ...

Kolay düzeltme Genellikle görülen nesne kodu (yöntemleri, arayüzler) sıyırma gibi, iyi, yaklaşık etrafında malzeme geçen aynı yaklaşım takip ziyaretinde kullanımları kod az değerler , kodunu aldıktan bu üzerinde çalışmak için gerekli araçlara sahip olmasıdır bekliyor.

Bu, slaytta olduğu gibi hissettiriyor, "değerler yöntemlere ihtiyaç duymuyor. Size kod olmadan değerleri gönderebilirim ve iyisin".


5
Jenerikler hemen hemen bu problemi hallederdi. İki katına çıkarma, bazı nesnelere mantıklı geliyor, ancak bazılarına anlam ifade etmiyor. Go dilinde, örtük bir arabirim uygulaması (bir tür ördek yazma) vardır, bu nedenle endişelenecek tüm bu arabirimlere sahip değilsiniz. Diğer taraftan, yöntem imzanızla hangi nesneye vurulacağını bilmek zorundasınız; Aksi takdirde beklenmeyen sonuçlar alabilirsiniz. Her zaman tradeofflar vardır.
Robert Harvey

1
İlginç bir almak. İyi cevap!
maple_shaft

2
Flyweight modeli, Rich'in bahsettiği şey değil. Maddenin ikinci cümlesinde belirtildiği gibi, uç ağırlık kalıbının amacı hafızayı korumaktır. Rich'in yaklaşımı bunu yapmak istemiyor.

5
MyValue = Double(YourValue)Değeriniz bir Dize, Adres, Kullanıcı, İşlev veya Veritabanı ise mantıklı gelmez. Aksi takdirde, eksik-yöntem argümanı güçlüdür. OTOH, erişimci yöntemleri, Değerlerinizin geçerli olması ve yeni Değerler üretmek için yalnızca mantıklı işlemlerin kullanılması için çeşitli kısıtlamaları uygulamanıza izin verir. Daha sonra Adresi Kullanıcı ve Şirketinizden ayırmaya karar verirseniz, erişim yöntemleri, kodunuzun tüm istemcilerini kırmamanız anlamına gelir. Böylece bazen kısa vadede engelleseler bile uzun vadede tekrar kullanımlarına yardımcı olabilirler.
GlenPeterson

4
(Diğer taraftan, Java ülkesinde sınıfların, arayüzlerin ve çerçevelerin patlamasının kabus olduğuna katılıyorum. Java’daki en basit "enterprisey" çözümü bir kod karmaşası. soru ve cevap, dinamik tipleme çalışmalarına mutlaka katılmadan)
Andres F.

2

Bir (yani benim) ideal dünya sınıflarında ve arayüzlerinde her zaman davranışı tarif ederdi, ama gerçek şu ki, çoğu zaman gerçekten sadece verileri tanımlamaya başlıyorlar. Sadece dün, birinin BankAccountyüceltilmekten başka bir şey olmayan sözde bir sınıf inşa etmesini izledim int(gerçekten de bir şeyden çok daha az işe yaramazdı int, bu yüzden tekrar bıraktığım yeniden kullanımı 'öldürüyor' int), hepsi 'iyi' tasarım adına. Verilerin katlanmış temsillerini sürekli olarak yeniden icat etmek için harcanan kod, ter ve gözyaşı miktarı şaşırtıcıdır; Verileri anlamlı bir şekilde kullanmıyorsanız, lütfen bırakın.

Şimdi, Rich Hickey'in bebeği banyo suyuyla atmaktan memnun olduğumuz ve değerlerin ülkesinde yaşayacağımızı (isim krallığının komşusu) söyleyen aşama budur. Bence, OOP'nin, ustaca kullanıldığında yeniden kullanımı (ve fonksiyonel programlamada eksik bulduğum keşfedilebilirliği) destekleyebileceğini ve desteklediğini düşünüyorum. Bu gerilimi en iyi yakalayan bir OOP ilkesi arıyorsanız, bunun http://c2.com/cgi/wiki?TellDontAsk (elbette Demeter'in yakın bir kuzeni) olabileceğini düşünüyorum.


Keşfedilebilirlik ile ne demek istiyorsunuz? O benzer mi bu ?

1
Evet, bunun ana noktaların çoğuna değdiğini düşünüyorum. Bu ince bir nokta ama keşfedilebilirlik dengeleyici bir hareket, şeyleri fazla şeffaf yapmak da istenmeyen bir durum çünkü parazit oranı için kötü bir sinyal alacaksınız.
CurtainDog
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.