Arayüz adları bir “I” önekiyle mi başlamalı?


73

Daha iyi bir programcı olmak için Robert Martin tarafından " Temiz Kod " u okudum . Şimdiye kadar hiçbiri gerçekten çığır açmazken, uygulamaları tasarlama ve kod yazma konusunda farklı düşünmeme neden oldu.

Kitabın yalnızca hem kabul etmediğim hem de özellikle arabirim adlandırma kuralları ile ilgili olarak anlam ifade etmeyen bir kısmı var. İşte doğrudan kitaptan alınan metin. Bunun kargaşasını bulduğum ve netleşmek istediğim yönünü cesaretlendirdim.

Arayüzleri süslemeden bırakmayı tercih ederim. Bir önceki I, bugünün mirasıyla dolu tomarlarda çok yaygındır, en iyi ihtimalle en çok dikkat dağıtıcı ve en kötüsü de çok fazla bilgidir. Kullanıcılarımın onlara bir arabirim verdiğimi bilmelerini istemiyorum .

Belki de sadece öğrenciyim çünkü ya da hiç profesyonel veya takım tabanlı bir programlama yapmadığım için ama kullanıcının bir arayüz olduğunu bilmesini isterim. Bir arayüz uygulamak ve bir sınıfı genişletmek arasında büyük bir fark var.

Öyleyse benim sorum, “Kodun bir kısmının bir arayüz bekliyor olduğu gerçeğini neden gizlemeliyiz?

Düzenle

Bir cevaba cevap olarak:

Türünüz bir arabirim veya bir sınıfsa, işletmeniz, kodunuzu kullanan birinin işi değil. Bu nedenle, bu üçüncü taraf kodunda kodunuzun ayrıntılarını sızdırmamalısınız.

Belirli bir türün bir arabirim mi yoksa bir üçüncü şahıs koduna mı sınıf olduğunun ayrıntılarını neden "sızdırmamalıyım"? Üçüncü taraf geliştiricinin, bir arabirim uygulayacaklarını veya bir sınıfı genişleteceklerini bilmek için kodumu kullanan önemli değil mi? Farklar sadece aklımda olmaları için yaptığım kadar önemli değil mi?


3
Senin fikrine katılıyorum. Çok fazla bilginin gizlenmesinin çok yardımcı olmadığı bir nokta var. Bununla birlikte, bu kılavuza uysanız bile, IDE veya bir eklenti kullanarak türü anlatabileceksiniz.
NoChance

3
Bu soru aslında "Macar notasyonu" sorusu olarak bilinir, pek çok argüman bulmanız ve MS olmayan çoğu geliştiricinin bu anahtar kelime altında bırakmasının nedeni budur. Macar gösterimi değişkenler için çoğunlukla yaygındı, ancak esas olarak türler için aynıydı.
thiton

2
Önceki başlık düzenlemesi çok kötüydü. Bu soru genel olarak Macar gösterimi ile ilgili değildir , çünkü kendisiyle ilişkili olabilecek bir sözleşmeden bahseder. HN'nin göreceli değerleri burada tamamen önemsizdir; Soru özellikle arayüzler ve sınıflar ile ilgiliydi ve anlamsal farklılıkların özel bir adlandırma kuralını haklı çıkarmak için yeterince önemli / ilginç olup olmadığıyla ilgiliydi.
Aaron

Ynt to know whether they will be implementing an interface or extending a class: evet, ancak kodunuzun çoğu kullanıcısı onu arayacak, uygulayamayacak veya genişletmeyecek ve gerçekten de onun ne olduğunu önemsemediler.
david.pfx

Buna değer, ben büyük ölçüde "Ben" önekini tercih ediyorum. Aynı sebeple soyut derslerde de “Özet” ön eki kullanıyorum. Sınıfın / arayüzün tüketicileri için bir fark yaratmaz, ancak örneklerini sağlaması gerekenlere büyük bir fark yaratabilir ve ayrıca kodunuzu okuyan diğer geliştiriciler için çok daha kolay hale getirir. Bu, daha fazla bilgi için vaka bazında IDE'ye danışmak yerine, bir bakışta neyle uğraştıklarını görebilecekleri anlamına gelir. Angular'ı kullanmaya yeni başladım ve bu sözleşmeyi izlememelerini gerçekten sinir bozucu buluyorum!
Dan King,

Yanıtlar:


66

Düşünmeyi bırakırsanız, bir arayüzün gerçekten soyut bir sınıftan anlamsal olarak farklı olmadığını göreceksiniz:

  • Her ikisinde de yöntemler ve / veya özellikler var (davranış);
  • Hiçbirinde özel olmayan alanlar (veriler) olmamalıdır;
  • Hiçbiri doğrudan başlatılamaz;
  • Birinden türetmek, türetilmiş tür de soyut olmadığı sürece, sahip olduğu herhangi bir soyut yöntemi uygulamak anlamına gelir.

Aslında, sınıflar ve arayüzler arasındaki en önemli farklar şunlardır:

  • Arayüzlerin özel verileri olamaz;
  • Arayüz üyeleri erişim değiştiricilere sahip olamaz (tüm üyeler "genel" dir);
  • Bir sınıf birden fazla arayüz uygulayabilir (genellikle sadece bir temel sınıftan miras alabilmenin aksine).

Sınıflar ve arayüzler arasındaki tek anlamlı anlamlı ayrım, (a) özel veriler ve (b) tip hiyerarşisi etrafında döndüğü için - ikisi de bir arayan için en ufak bir fark yaratmaz - genellikle bir türün bir arayüz olup olmadığını bilmek gerekmez Bir sınıf. Görsel gösterime kesinlikle ihtiyacınız yok .

Ancak, dikkat edilmesi gereken bazı köşe davaları vardır. Özellikle, yansıma, durdurma, dinamik proxy'ler / karışımlar, bayt kodlu dokuma, kod oluşturma veya ortamın yazma sistemiyle veya kodun kendisiyle doğrudan bulaşmayı içeren herhangi bir şey kullanıyorsanız - o zaman çok yararlı ve bazen derhal bilmeniz gerekir. Bir arayüz veya bir sınıfla uğraşırken yarasa olun. Kodunuzun gizemli bir şekilde başarısız olmasını istemiyorsunuz çünkü bir arayüz yerine bir sınıf eklemeye çalıştınız.

Tipik olarak, vanilya, öğütülmüş işletme iş mantığı kodu, ancak, soyut sınıflar ve arayüzler arasındaki farkların, reklamların yayınlanmasına gerek kalmayacak çünkü hiçbir zaman devreye girmeyecekler.

Bunların hepsi söyleniyor, Iyine de C # arayüzlerimi önekleme eğilimindeyim çünkü Microsoft tarafından kullanılan ve savunulan .NET kuralları. Kodlama sözleşmelerini yeni bir geliştiriciye açıklarken, neden kendi "özel" kurallarımıza sahip olduğumuzu açıklamak yerine Microsoft kurallarını kullanmak çok daha az güçtür.


Bu arıza için teşekkür ederim. "Sınıflar ve arayüzler arasındaki anlamlı farklar ..." için +1 ...
Charles Sprayberry

23
+1 "Bütün bunlar söyleniyor, yine de C # arayüzlerimi önekleme eğilimindeyim, çünkü bu, Microsoft tarafından kullanılan ve savunulan .NET sözleşmesidir". Bu C # için benim için yeterli bir sebep. Bu ortak standardı takip ederek, diğer .NET programcılarının arayüzü tanımlaması daha olasıdır.
Robotsushi

4
Hem Java hem de C # yazan bir kişi olarak "Bütün bunlar söyleniyor, C # arabirimlerimi zaten I ile öneklemeye meyilliyim çünkü bu, Microsoft tarafından kullanılan ve Microsoft tarafından savunulan .NET sözleşmesidir" ifadesinin anlaşılamaması. hangi dilde çalıştığımı hatırlamama yardımcı oluyor,
Aidos 3:12

3
.NET'teki (Java'da değil) bir başka fark, birçok .NET dilinin arayüzlerin statik yöntemler içermesine izin vermemesidir, bu nedenle Ibir arayüzün kesilmesi, bir sınıfın arayüzle ilişkili statik yöntemleri tutması için iyi bir ad verebilir (örn. Enumerable<T>.Emptyveya Comparer<T>.Default).
supercat,

Benim bir endişem var. C ++ 'ta bir başlık açarsanız ve class Foozaten genişlediğini görürseniz, genişletilip genişletilmediği veya uygulanıp uygulanmadığı class Barhemen belli değildir class Bar. Şimdi sen gidip bakmak zorundayız class Baro değiştirmeye tamam karar vermek başlığındaki class Foouzatmak class Baz. Ayrıca, "ön temel sınıf" ihlal ediliyorsa veya edilmiyorsa, I öneki açık bir görsel ipucu verir - böylece her başlık açtığınızda bir sağlık kontrolü alırsınız.
jsj,

14

Birçok yönden tutarlılık, sözleşmeden daha önemlidir. Adlandırma şemalarınızda tutarlı olduğunuz sürece, çalışmak zor olmayacak. İsterseniz önek ile bir arabirim oluşturur, ya da sadece adını değiştirmeden bırakırsanız, bir stil seçip ona sadık kalmanız benim için önemli değil!


2
Tutarlılık için +1> kongre. C # ile bir I önek ve Java ile olmazdı. Farklı görevler farklı sözleşmelere
ihtiyaç duyar

2
Ben şahsen tercih etmemi tercih ederken +1 arayüzlerimde.
jk.

13

Kitap çok güzel şeylerle dolu, ancak yine de arayüz adına "I" eklerdim.

public interface ILogVarsayılan bir uygulamaya sahip olduğunuzu hayal edin public class Log.

Şimdi, anlamaya karar verirseniz public interface Log, birdenbire Log sınıfını public class LogDefaulto satırlarda veya başka bir şeyle değiştirmeniz gerekir . Fazladan bir karaktere sahip olmaktan yedisine gittin - elbette israf.

Teori ve pratik arasında genellikle ince bir çizgi vardır. Teoride bu gerçekten iyi bir fikir, ancak pratikte o kadar iyi değil.


Bu ayrıca .NET belgelerinde
levininja

30
"Varsayılan bir ortak genel sınıf Log uygulamasıyla ILog ortak arabiriminiz olduğunu hayal edin." - Öyleyse varsayılan uygulamanız için kötü bir adınız var. Ne yapar Log? Konsola giriş yap. Syslog'a mı? Hiçbir yere? Bunlar çağrılmalıdır ConsoleLog, SyslogLogve NullLogsırasıyla. LogSomut bir sınıf için iyi bir isim değil çünkü somut bir isim değil.
Sebastian Redl,

7
Şahsen bu kesinlikle ITheClassName'i görmekten nefret ediyorum, sadece sebepsiz yere bir arabirim mi oluşturuyorsunuz, sadece TheClassName'in tepesinde gürültü olması. Arayüz bir amacı vardır Eğer ITheClassName daha olsam daha iyi bir isim vermek mümkün olmalıdır
Richard Tingle

Sınıfın adı bir kez kullanılır (başlatılır), arabirimin adı her yerde kullanılır. Arabirimdeki harfi sınıf adına kaydetmek için bir harf eklemek yanlış ekonomidir (karakterlerin).
sergut

@RichardTingle Ama bu kadar yaygın kullanımı basitçe olduğunu düşünüyorum MyClassbir sahiptir mockable varyasyonu doğru? Yani sık sık esasen kamu yöntemler yapmak için arayüzleri kullanın olduğunu gerçekten test için izin veren bir tarzda kamu. (Bu iyi mi kötü söyleyerek, ancak arayüzleri için motivasyon basitçe 1-to-1 açıklıyor bağımlılıkları kolayca mockable olan sınıfları yapmak için sık sık olduğunu anlamadan Değil MyClassiçin IMyClasseşleştirmeleri.)
ruffin

8

Bu, arayüzü uygulamak veya bir sınıfı genişletmekle ilgili değil. Sıkı durumlarda, ne yaptığını zaten biliyorsun.

Bununla birlikte, üçüncü taraf kodu (örnek uygulama için başka bir modül) verilerinizi manipüle ettiğinde, bu kod, bir arayüz veya bir sınıf sunuyorsanız önem vermemelidir.

Bu soyutlamanın bütün meselesi. Bu üçüncü taraf koduna belirli bir tipte bir nesne sunuyorsunuz. Bu tipte arayabileceğiniz bazı üye fonksiyonu vardır. Bu yeterli.

Türünüz bir arabirim veya bir sınıfsa, işletmeniz, kodunuzu kullanan birinin işi değil. Bu nedenle, kodunuzun ayrıntılarını bu üçüncü taraf koduna sızdırmamalısınız.

Bu arada, arayüzler ve sınıflar sonunda referans türleridir. Ve önemli olan da bu. Demek adlandırma kurallarının vurgulaması gereken şey bu.


@Mat> Evet, bu benim hatamdı ve ben onu düzelttim.
deadalnix

5

Çoğu cevap, programlama dilinin Java veya C # olduğunu varsayar, burada arayüzler / soyut sınıflar için bir kavram (veya anahtar kelime) vardır. Bu gibi durumlarda, iyi bir IDE'de, bir sınıfın hangi public interface IMyClasstiple uğraştığı ve yazmanın gereksiz bir çoğaltma olduğu hemen görülür . Yazmayacağınız gibi public final FinalMyClass- her anahtar kelimeyi sınıf ismine koymayı hayal edin.

Bununla birlikte, C ++ 'a göre bence, durum başlık dosyasına dalmak ve sınıfın soyut bir sınıf olup olmadığını bulmak için herhangi bir sanal yöntemi olup olmadığına bakmak zorunda olduğu için durum biraz farklıdır. Bu durumda, yazı için açıkça bir argüman görebiliyorum class AbstractMyClass.

Yani cevabım şöyle olurdu: Bu programlama diline bağlıdır.

Güncellenme 2016: 2 yıllık C ++ deneyimi sonra muhtemelen sınıf adlarının önüne geçmenin kötü bir uygulama Abstractolduğunu düşünürdüm, ancak mantıklı olabileceği kadar karmaşık olan kod tabanları olduğunu söyleyebilirim.


Bunun soruyu yanıtladığından emin misin? Diğer cevapları okumak ve puanlarınızı açıklığa kavuşturmak isteyebilirsiniz.
david.pfx

C ++ kesinlikle herhangi bir anahtar kelime olmasa bile arayüzlere sahiptir. Her üye işlevinin salt sanal olduğu ve üye değişkenlerinin olmadığı bir sınıfa ne denir?

@ david.pfx: "Arabirim adları bir" Ben "ön ekiyle mi başlamalı?" sorusuna tam olarak cevap verdiğimi düşünüyorum. Eğer detaylandırmamın yeterince net olmadığını düşünüyorsanız, geliştirmek için mutluyum - hangi kısımlar sizin için açık değil?
Ela782

2
@JohnGaughan: Arayüzleri olduğundan emin! Ama benim açımdan mesele, anahtar kelime ile ilgili olduğu. C ++ bir yok, öyleymiş değil o / o bir arayüz ya da değil ilgilenen olursa IDE / kullanıcı tarafından görülebilir. Ancak Java'da hemen görünür.
Ela782

1
En yüksek oy alan cevabı okuyun ve sizinkini karşılaştırın. SO'da yenisiniz ve bu ne tür cevapların oy aldığını öğrenmek için bir fırsat. Durduğu gibi, seninki olmayacak. Daha fazla iş, daha fazla açıklama, daha fazla değer, sadece olabilir. Pes etme!
david.pfx

4

Kullanmakta olduğunuz dilin deyimlerini takip edin.

Her dilin kendi deyimleri ve kodlama kuralları vardır. Örneğin, C # 'da, I ile arayüzlerin önekini koymak aptalcadır. Go, öyle değil.


+1 Kullanmakta olduğunuz dilin deyimlerini takip edin. Açıkçası, kitap yazarı bir Java geliştiricisidir. .NET / C #: ILog Java: Günlük Ama dezavantajı: ILog arabirimini uygulayan bir Log sınıfım olmasını istediğimde .... MyLog, LogDefault, LogBase, ...? Çirkin değil mi? Daha çirkin: LogImpl ....: D
hfrmobile

0

(Java) kodumda, bu sözleşmeyi arayanlara maruz kaldığım API'lerde yapma eğilimindeyim:

  • İşlevsellik, arayüzler vasıtasıyla ve asla sınıflar tarafından sağlanmaz.
  • İşlevsel olmayan parçalar sınıflardır.

İşlevsel olmayan, ben hepsi, numaralandırma ve istisnalar (örneğin XML seri veya ORM köprü olarak hareket sınıfları gibi) saf veri yapıları gibi şeyler ifade edemez arayüzleri olmak (iyi yapabilirsiniz saf veri sınıfları için , ancak bu derslerin veri tutma dışında yaptığı hiçbir şey olmadığı için çok az kazanç için çok iş var ).

Sözleşmelerin isimlendirilmesi açısından, ara yüzler aktör isimlerine (örneğin FooBarWatcher) veya sıfatlara (örneğin FooBarWatchable) ve hem saf veri sınıflarına hem de sayımlarına aktif olmayan isimlerle eşleştirilir (örn. FooBarStatus); IDE, API tüketicisine özel adlandırma kuralları olmadan rehberlik edebilir. İstisnalar zamanki Java kurallarını (izleyin FooBarException, FooBarError, FooBarFaulttabii ki).

Ayrıca sadece kendi kurallarımı çiğnememeyi sağlamak için arayüzleri kendi paketlerine ve hatta kendi kütüphanelerine koyacağım. (Bu ayrıca, kodu WSDL belgeleri gibi harici kaynaklardan alırken yapıyı yönetmeme yardımcı olur.)


Ayrıca Iarayüzlere asla önek koymadım. Of Tabii bir arayüz! Bir API'de (veya SPI'de)!
Donal Fellows
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.