Java ile C # arasında ilgili küçük bir fark var. Java'da her üye varsayılan olarak sanaldır. C # 'da her üye varsayılan olarak mühürlenir - arayüz üyeleri hariç.
Bununla ilgili varsayımlar, rehberi etkilemektedir - Java'da, her kamu türü, Liskov'un İkame Prensibi'ne [1] uygun olarak nihai olarak kabul edilmemelidir. Yalnızca bir uygulamanız varsa, sınıfı adlandırırsınız Parser
; Birden fazla uygulamaya ihtiyaç duyduğunuzu tespit ederseniz, sınıfı yalnızca aynı ada sahip bir arabirim ile değiştirir ve somut uygulamayı yeniden tanımlayıcı bir şeyle yeniden adlandırırsınız.
C # 'da ana varsayım, bir sınıf aldığınızda (isim ile başlamaz I
), istediğiniz sınıftır. Dikkat edin, bu hiçbir yerde% 100 kesinliğe yakın değildir - tipik bir karşı örnek, Stream
(gerçekten bir arabirim veya birkaç arabirim olması gereken) gibi sınıflar olabilir ve herkesin diğer dillerden kendi kılavuzları ve geçmişleri vardır. Base
Soyut bir sınıfı belirtmek için oldukça yaygın kullanılan sonek gibi başka istisnalar da var - tıpkı bir arayüzde olduğu gibi , türün polimorfik olması gerektiğini biliyorsunuz .
Ayrıca, arabirim soyut bir sınıfa başvurmak zorunda kalmadan, bu arabirim ile ilgili işlevsellik için I-olmayan isimden ayrılmasında hoş bir kullanılabilirlik özelliği de vardır (C # sınıfının çoklu kalıtım eksikliği nedeniyle zarar görebilir). Bu, IEnumerable<T>
arayüz Enumerable
olarak ve bu arayüz için geçerli olan yöntemlerin bir deposu olarak kullanılan LINQ tarafından popülerleştirildi . Arayüzlerin de metod uygulamaları içerebildiği Java'da bu gerekli değildir.
Sonuçta, I
önek C # dünyasında yaygın olarak kullanılır ve uzantı olarak .NET dünyası (.NET kodunun çoğu C # ile yazıldığından beri, genel arabirimlerin çoğu için C # kurallarına uymak mantıklı olur). Bu, neredeyse kesinlikle bu gösterimi izleyen kütüphaneler ve kodlarla çalışacağınız anlamına gelir ve gereksiz karışıklığı önlemek için geleneği benimsemeniz mantıklıdır - ön ekin kodunuzu daha iyi hale getireceğini ihmal etmemiz gibi değildir :)
Bob Amca'nın aklının böyle bir şey olduğunu varsayıyorum:
IBanana
Muz soyut kavramdır. Bundan daha iyi bir adı olmayan herhangi bir uygulayıcı sınıf olabilirse Banana
, soyutlama tamamen anlamsızdır ve arayüzü bırakıp sadece bir sınıf kullanmalısınız. Daha iyi bir ad varsa ( LongBanana
veya söyle AppleBanana
), Banana
arabirimin adı olarak kullanmamak için hiçbir neden yoktur . Bu nedenle, I
ön ekin kullanılması, kodun faydasız bir şekilde anlaşılmasını zorlaştıran işe yaramaz bir soyutlamanız anlamına gelir. Ve katı OOP her zaman arayüzlere karşı size kod koyacağına göre I
, bir türü öneki görmeyeceğiniz tek yer bir yapıcı olacaktır - oldukça anlamsız gürültü.
Bunu örnek IParser
arayüzünüze uygularsanız , soyutlamanın tamamen “anlamsız” bölgede olduğunu açıkça görebilirsiniz. Ya bir ayrıştırıcı (örneğin somut bir uygulaması hakkında spesifik bir şey var JsonParser
, XmlParser
...), ya da sadece bir sınıf kullanmalısınız. "Varsayılan uygulama" diye bir şey yoktur (bazı ortamlarda, bu gerçekten de, özellikle de COM anlamındadır), ya belirli bir uygulama vardır ya da "varsayılanlar" için soyut bir sınıf ya da uzantı yöntemi istiyorsunuz. Bununla birlikte, C # 'da, kod tabanınız zaten I
-prefix'i atlatmazsa, saklayın. Her zaman kodunu her gördüğünüzde zihinsel bir not alın class Something: ISomething
- birileri YAGNI’yi takip etmede ve makul soyutlamalar oluşturmada çok iyi değil demektir.
[1] - Teknik olarak, bu Liskov'un makalesinde özel olarak belirtilmemiştir, ancak orijinal OOP makalesinin temellerinden biridir ve benim Liskov okumamda buna meydan okumamıştı. Daha az katı bir yorumda (çoğu OOP dilinin kullandığı dil), bu, yerine koyma amaçlı (yani son olmayan / mühürlü) bir kamu türünü kullanan herhangi bir kodun, bu tür uygun herhangi bir uygulama ile çalışması gerektiği anlamına gelir.