OOP: Sınıf tabanlı tasarımın arayüz tabanlı tasarımdan daha iyi olduğu durumlar nelerdir?


10

JDOM'un web sitesini okuyordum .

JDOM API'si neden arayüzler yerine somut sınıflar olarak tanımlanıyor?

Jason Hunter, JDOM için arayüz tabanlı bir API'ya yönelik argümanları özetler:

Arayüzler ile her şey fabrika haline gelir, elemanlar sadece eklenmek yerine yeni belgelere aktarılmalıdır, uzun süreli serileştirme gibi özellikler garanti edilemez ve liste devam eder.

Aslında arayüzlerle başladık. Bazı akranlara yapılan yayın öncesi incelememizde somut dersleri denememiz gereken geri bildirimler aldık. Yaptık ve tasarım bunun için çok daha iyiydi.

Ben yeni başlayan bir tasarımcıyım. Şimdiye kadar duyduğum tüm tavsiyeler , somut sınıflarla tasarım kullanmaya karşı tavsiyede bulunuyor .

Bazı yerlerde somut sınıflar kullanmak uygun olabilir. Tasarımda somut sınıfların kullanılmasının iyi olduğu ortak sınıf problemleri var mı?



Ayrıca "Soyutlamalarınızı sınırlayın" serisine de göz atabilirsiniz: ayende.com/blog/153889/…
henginy

"Yaptık ve tasarım bunun için çok daha iyiydi." - nasıl daha iyiydi?
CodeART

Yanıtlar:


6
  • Kalıtım, sürdürülebilirlik konusunda büyük bir sorun olabilecek uygulamaya bağımlılıklar yaratır . Bunun sonucu, tanım gereği neredeyse hiç uygulama içermeyen veri aktarım nesnesiyle uğraşırken miras ve somut sınıfları güvenle kullanabilmenizdir . Bu bağımlılığı istediğinizde somut sınıfların mirasını da kullanabilirsiniz. Bu durumda hiyerarşinin üst kısmında ortak yöntemleri (genellikle yardımcı işlevler) içeren soyut bir sınıf kullanmak isteyebilirsiniz.
  • Somut bir sınıf hiyerarşisi kullanırken, Liskov İkame İlkesini uygulamayı unutmayın .
  • İstemciler için somut sınıfların kullanımıyla ilgili bir sorun yoktur (yani kullanılan sınıflar değil, kullanılan sınıflar).
  • IMHO değişecek şeyler olana kadar somut dersleri kullanabilirsiniz. Açık / kapalı İlke bağlama önlemek için arayüzleri kullanmak söylerdim, ama ilgili You Gonna Need It İlke değil mi size uygulanmasında değişiklik şey gerektiğinde ana kadar somut sınıflarını kullanmayı düşünebilirsiniz. Sorun şu ki, bir yerde bir şey ilk değiştiğinde sınıflarınızın her müşterisini değiştirmek zorunda kalacaksınız. Bir şey yapmak için sadece bir aracınız olsa da, somut sınıflar IMO'yu kullanabilirsiniz.

[EDIT] JDOM'un web sitesi örnek olarak java.io.File dosyasını alır, ancak bu bir java.io.File örneğini yalnızca Serializable gibi işleyebileceğinden kesinlikle arayüz tabanlı bir tasarımdır. Bu durumda sadece "yaratıcılar" somut sınıfı bilirdi


Etrafta yüzen "değer nesnesi" nin birbiriyle çelişen iki tanımı vardır. Sizinki, "veri aktarım nesnesi" olarak da bilinen daha az yaygın olanı gibi görünüyor.
Michael Borgwardt

@MichaelBorgwardt Thx bunu sadece "veri aktarım nesnesi" demek istemediğim için işaret ettiğiniz için: Cevabımı düzenlerim
Matthias Jouan

1
LSP herhangi bir alt tip ilişkisi, arayüz uygulaması ve kalıtım için önemlidir .

3

JDOM sitesinden:

Jason (Hunter) 2000 yılının başlarında Brett McLaughlin ile birlikte JDOM projesini kurdu

Yani, Java 1.3 piyasaya sürülürken. Java geliştirme söz konusu olduğunda olgunluk açısından hiçbir şey yoktu - en deneyimli geliştiricilerin Java'yı en iyi şekilde kullandıkları 4 yıl vardı. Yaygın olarak kullanılan IoC kapları, Hazırda Bekletme yok. Apache Struts yeni başlıyordu.

Bu Jason ve Brett'in sadece yanlış olduğunu söylemek. Birçok insan henüz "anlamadı". C ++ geçmişleri olsaydı, C ++ 'da arayüzlere ihtiyacınız yoktu (Peki, C ++' da vardı, ama gerçekten onlara ihtiyacınız yoktu, değil mi?), Neden heck onları Java'da kullanıyor? Peki, başkalarının sizi yönlendirebileceği birçok iyi neden var.

Hakkında kesinlikle yanlışlardı

arayüzler ile yapılabilecek her şey alt sınıflama ile yapılabilir

Java, sınıfların birden çok kalıtımına izin vermez, ancak birden çok arabirimin uygulanmasına izin verir. Bu gerçek bir fark yaratabilir.


3

Sorunuzla ilgili olarak, Yazılım Geliştirme'de bir sorunu çözmenin birkaç yolu olduğunu ve bazı geliştiricilerin sizinkinden farklı bir teknik kullandığı takdirde, bunun çözümün yanlış olduğu anlamına gelmediğini lütfen unutmayın.

Bu vakalardan biri "arabirimler" ve (taban) "sınıflar" dır. Her iki teknikte de aynı amaca ulaşılabilecek durumlar vardır.

İşleri daha karmaşık hale getirmek için, sadece bahsetmek gerekirse, arayüzlerin çeşitli kullanımları vardır:

  • biri "uygulama" olmadan bir "sözleşme" veya "şartname" tasarlamaktır
  • diğeri, sınıfların mevcut , yeni, sınıfa veya hiyerarşisine işlevsellik eklemek için
  • öncekini tamamlayıcı, farklı nesneler, teknolojiler arasında paylaşım erişimine izin vermek için, örnek: Enterprise Beans, CORBA, COM, WebServices
  • birden fazla mirası taklit etmek

Sorunuz ilk nokta için geçerlidir.

Yalnızca tek bir sınıf değil, bir sınıf hiyerarşisi geliştirmek istediğinizde ve bazı sınıfların bazı belirli özellikleri paylaşması amaçlandığında, bir arabirimle yapılabilse bile bir temel sınıfla başlamak isteyebilirsiniz.

Ve diğer senaryolar için arayüz bırakın.

Widget (denetimler) kitaplıkları buna iyi bir örnektir.

PHP, Delphi (Object Pascal), C # gibi arayüzleri ve sınıfları nasıl kullandıklarını diğer programlama dillerine bir göz atın öneririz.

Şerefe.


1

API tasarım kuralları gerçekten özel bir şeydir. Günlük kodunuzu nasıl tasarlamanız gerektiği konusunda bu SSS'den bir şey çıkarmanız gerektiğinden emin değilim.

Normal kodunuz için, arayüz veya soyut sınıf mirasını vanilya mirası IMO'sundan çok daha sık kullanacağınız hala doğrudur.

Bu kuralı iyi anlamak için kendinizi türetilmiş bir sınıfın üst sınıfına karşı değil, başka bir nesneye bağımlı olan bir nesnenin bakış açısına yerleştirmeniz gerekir. Somut bir uygulamadan ziyade bir soyutlamaya güvenmek neredeyse her zaman daha iyidir, çünkü uygulama ayrıntılarına değil, sözleşmelerine dayanarak bir dizi farklı sınıfı bağımlılık olarak kabul etmenize izin verir.

Bunun için ilk kullanımı birim testlerinde genellikle - Eğer gerçekten isterseniz birim testinde tam izolasyon sınıfınızı, üretimde kullanılacak gerçek uygulamalardan farklıdır senin bağımlılıkları sahte uygulamalara karşı böyle yapar.


0

Genellikle parametre olarak iletilen veya döndürülen herhangi bir şey için bir arabirim istersiniz, böylece sınıfı bağımlılıklarından ayırabilirsiniz.

Eğer bir sınıf arıyorsanız, normalde istisnalar akla gelmez. Ben bir Java geliştiricisi değilim, ama kesinlikle benzer dillerde, istisnalar için tanımlanan arayüzler gördüğümü sanmıyorum.

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.