Java arayüzleri uygularken Varsayılan vs Impl


34

Okuduktan sonra Paket isimleri tekil mi yoksa çoğul mu olmalı? Evcil hayvanlarımdan birini kapsayan bir tartışma hiç görmedim: arayüzlerin uygulamalarını adlandırma.

OrderÇeşitli şekillerde uygulanması amaçlanan bir arayüze sahip olduğunuzu varsayalım, ancak proje ilk oluşturulduğunda yalnızca ilk uygulama vardır. Sizin için gider misin DefaultOrderya OrderImplveya yanlış ikilemi önlemek için bazı başka varyantı? Ve daha fazla uygulama ortaya çıktığında ne yaparsınız?

Ve en önemlisi ... neden?

Yanıtlar:


59

İsimlerin anlam ifade etme şansı var. Bu fırsatı neden Impl ile birlikte atıyorsun?

Her şeyden önce, yalnızca tek bir uygulamanız olacaksa, arayüzü ortadan kaldırın. Bu adlandırma problemini yaratır ve hiçbir şey eklemez. Daha da kötüsü, siz ve diğer tüm geliştiriciler her zaman yalnızca arayüzü kullanmak için dikkatli değilseniz API'lerde tutarsız yöntem imzalarıyla sorunlara neden olabilir.

Bundan dolayı, her arayüzün iki veya daha fazla uygulaması olduğunu veya olabileceğini varsayabiliriz .

  • Şu an sadece bir tanesine sahipseniz ve diğerinin ne şekilde farklı olabileceğini bilmiyorsanız, Varsayılan iyi bir başlangıçtır.

  • Şu anda iki tane varsa, her birini amacına göre adlandırın.

    Örnek: Son zamanlarda, bir somut sınıf Context (veritabanına referansla) yaptık . Çevrimdışı olan bir içeriği temsil etmemiz gerektiğinin farkına varılmıştı, bu yüzden Context adı yeni bir arayüz için kullanıldı (eski API'ler için uyumluluğu korumak için) ve yeni bir uygulama oluşturuldu, OfflineContext . Bil bakalım asıl adı neydi? Bu doğru, ContextImpl (yikes).

    Bu durumda, DefaultContext muhtemelen iyi olur ve insanlar bunu alırdı, ancak olabileceği kadar açıklayıcı değil. Sonuçta, çevrimdışı değilse , nedir? Böylece gittik: OnlineContext .


Özel durum: Arabirimlerde "I" ön ekini kullanma

Arayüzlerde I öneki kullanılarak önerilen diğer cevaplardan biri . Tercihen, bunu yapmanız gerekmez .

Bununla birlikte, özel uygulamalar için her iki arayüze de ihtiyacınız varsa, ancak sık sık kullanılacak olan bir birincil somut uygulamanız da var ve bunun için temel ad sadece bir arayüze vermek için çok basit, o zaman eklemeyi düşünebilirsiniz. Arayüze "ben" (yine de, senin ve takımın için hala doğru oturmuyorsa, sorun değil).

Örnek: Birçok nesne bir "EventDispatcher" olabilir. API'lerin iyiliği için bunun bir arayüze uyması gerekir. Ancak, ayrıca temsilcilik için temel bir olay memuru da sağlamak istersiniz . DefaultEventDispatcher iyi olurdu, ama uzun biraz, ve sık sık onun adını göreceğiz eğer, sen olabilir taban adı kullanmayı tercih EventDispatcher'ı beton sınıfı için ve uygulamak IEventDispatcher özel uygulamalara ilişkin:

/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
  /* default event dispatcher */
}

/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
  /* default event dispatcher. */
}

3
Sağlam cevap için +1. Impl kullanmamak arkasındaki mantık gibi.
Gary Rowe

2
+1 kesinlikle katılıyorum. Arabirimi, temsil ettiği etki alanı konseptinden uzağa adlandırmak, noktayı tamamen kaçırmaktadır.
rupjones

9
"sadece bir uygulamaya sahip olacaksanız", önceden yalnızca bir uygulamaya sahip olacağınızı nereden biliyorsunuz? "her arayüzün iki veya daha fazla uygulaması olabilir veya olabilir" ... iki uygulama yapmadan önce, önce hiçbiriniz yok, siz bir tane var, sonra iki tane var, demek istediğim bir an olabilir, sadece bir uygulama var, sadece ikincisini uygulamadan önce.
Tulains Córdova

2
@NickC Ben anlambilim hakkında pedantinc değilim (bir şairim ve ben bile bilmiyordum). İngilizce anadilim değil, bu yüzden bilgiçlik edemiyorum. Hatalı mantıktan bahsediyordum. Dekuplaj için arayüzleri kullanıyorsunuz. Bu, belirli sayıda uygulama gerektirmez.
Tulains Córdova

4
if you will only ever have one implementation, do away with the interface- Bileşeni test etmek istemediğiniz sürece, bu durumda MockOrder, OrderStub veya benzeri oluşturmak için bu arayüzü korumak isteyebilirsiniz.
JBRWilkinson

15

Arayüz kullanım durumuna göre isimlendirmeye karar verdim.

Arayüz ayırma için kullanılıyorsa , Impluygulamaları seçiyorum .

Arayüzün amacı davranışsal soyutlama ise , uygulamalar somut olarak yaptıklarına göre adlandırılır. Arayüz adını çoğu zaman buna eklerim. Arayüz denirse Validatorkullanırım FooValidator.

Bunun Defaultçok kötü bir seçim olduğunu düşünüyorum. İlk olarak, kod tamamlama özelliklerini kirletir, çünkü adlar her zaman onunla başlar. Diğer bir şey, varsayılanın zaman içinde değişebilir olmasıdır. Öyleyse, ilk önce varsayılan olan, kullanımdan kaldırılan bir özellikten bir süre sonra olabilir. Bu yüzden ya varsayılanlar değiştikten hemen sonra sınıflarınızı yeniden adlandırmaya başlarsınız ya da yanıltıcı adlarla yaşarsınız.


8

Ben (arayüz muhtemelen çoğu durumda gerekli değildir özellikle de), ancak tartışma uğruna ben ek bir diğer alternatif daha dışarı atacağım Nicole'ün yanıta katılabilir OrderImplve DefaultOrdergizle gibi statik bir fabrika yöntemi arkasındaki uygulanmasını: Orders.create(). Örneğin:

public final class Orders {
  public static Order create() {
    return new Order() {
      // Implementation goes here.
    };
  }
}

Bu yaklaşımla, uygulama Anonim iç sınıf olabilir, ya da sahip özel bir sınıf olabilir Defaultveya Impladına ya tamamen başka bir şey adlandırılabilir. Hangisi seçim yapılıyorsa, arayanın ilgilenmesi gerekmez, bu yüzden ne zaman / sonra değiştirmeye karar verirseniz daha fazla esneklik elde edersiniz.

Uygulamada bu modelin bazı harika örnekleri , yöntemleri gizli uygulamalar döndüren java.util.Collectionsve java.util.concurrent.Executorsyardımcı sınıflardır. Etkili Java'nın da belirttiği gibi (Öğe 1'de), bu kalıp API'nin "Kavramsal ağırlığını" küçük tutmaya yardımcı olabilir.


İlginç bir ek vaka için +1: isimsiz uygulamalar.
Gary Rowe

1
Ayrıca Guava'da da yaygın olarak kullanılmaktadır .
Nicole,

3

Her zaman OrderImplbasitçe giderim çünkü Orderarayüzden hemen sonra alfabetik olarak görünür.


2
Ve özel işlemler için devam eden diğer uygulamaları nasıl ele alacaksınız?
Gary Rowe

1
İlk uygulama hakkında sordun. DomesticOrder, ForeignOrder veya ne olursa olsun uygulamaya başladığınızda, daha düşünceli ve alfabedeki konumlarına bakmadan adlandırılırlar.
Ben Hoffstein

Son derece - Bu yeni gereksinimi yansıtacak şekilde orijinal soruyu değiştirdim.
Gary Rowe

İyi bir fikir değil Birden fazla uygulama olacaksa.
Sadegh,

0

Arabirimi I (IWhatever) öneki ile isimlendirebilir ve daha sonra uygulama yapabilirsiniz.

Resmi Java kodu kuralları, arayüzler için bu tür bir adlandırmadan bahsetmez, ancak bu tür adlandırma tanıma ve gezinmeye yardımcı olur.


Neden bir I ile arayüze ön ek eklediniz? Navigasyonda tanınmaya yardımcı olmak mı?
Gary Rowe

@Gary: Ben ile arayüz tipleri önek Delphi dilinde iyi kurulmuş bir kongredir. Delphi sınıflarında T ile ön ek verilir. Bu nedenle, bir özel uygulama olarak TSomethingOrder ve TBullMarketOrder ile bir IOrder arayüzüne ve TOrder varsayılan uygulamasına sahip oluruz.
Marjan Venema

3
Bu geliştirmenin .NET geliştirmesinde de yoğun olarak kullanıldığını gördüm. Belki de Microsoft’un belgeleri ve örnekleri onu kullandığındandır.
Ben Hoffstein

5
@Renesis, Java içinde kullanmak için yararlı bir durum ortaya çıkmış görünüyor. Şahsen, bana farklılığı söylemek için IDE'ye güvenirdim, aksi takdirde Enums için E'ler, C'ler için sınıflar ve hepsi büyük ölçüde gereksiz olurdu.
Gary Rowe

0

Default bazı durumlarda mantıklı gelse de uygulamayı tanımlamanın daha faydalı olacağını düşünüyorum. Arayüz Yani eğer UserProfileDAOo zaman uygulamaları olabilir UserProfileSQLDAOya UserProfileLDAPDAOya da onun gibi bir şey.


0

eğer mümkünse, ismini ne / nasıl yaptığını söyleyin.

genellikle en kötü yaklaşım, kullanılması gerektiği şekilde adlandırmaktır.

Uygulama için temel sınıf olarak kullanılması gerekiyorsa, BaseX veya AbstractX kullanabilirsiniz (eğer soyutsa (ama ne yaptığını öğrenmeye çalışın, çünkü hiçbir şey yapmazsanız, onu yapmazsınız) Mümkün olan en basit işlevselliği sağlarsa ve böyle bir işlevsellik yeterli olduğunda doğrudan kullanılması (genişletilmemesi) bekleniyorsa, buna SimpleX veya BasicX diyebilirsiniz.

Başka bir uygulama sağlanmadıkça kullanılırsa, DefaultX olarak adlandırın


-2

Bu cevapların çoğu ne yapıldığını açıklıyor, ancak nedenini değil.

OO prensiplerine ne oldu? Impl bana bir sınıf ve nasıl kullanılacağı hakkında neler söylüyor? Nasıl yapıldığını değil, kullanımları anlama konusunda endişelenmelisiniz.

Bir Kişi arayüzü oluşturursam, PersonImpl nedir? Anlamsız. En azından DefaultPerson bana kimin kod verdiyse arayüz oluşturmaması gerektiğini söyledi.

Arayüzler polimorfizm için yazıyor ve bu şekilde kullanılmalı.


1
@NickC tarafından kabul edilen cevap, ne yapıldığına ve neden yapıldığına dair bazı ayrıntılara girer.
Gary Rowe,
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.