Java ile yazılmış bir API'da dahili sınıflar nasıl kapsüllenir?


9

Bir kütüphane yazmalıyız. Doğal olarak, sadece çok küçük bir API'ye sahip olmalıdır (mümkün olduğunca küçük). Kütüphanenin içi biraz karmaşıktır. Bu nedenle, yapılandırmaya ihtiyaçları vardır.

Yapılandırma için şu anda iki yol görüyorum:

1. paketleri kullanın.

Artıları: Kütüphane düzgün bir şekilde yapılandırılabilir. Onun yerine her şey.

eksileri: sınıfların paket sınırları boyunca kullanımı genel sınıflara ihtiyaç duyar ve bu nedenle tüm kütüphanenin API'sini genişletir.

2. tek bir pakette, statik iç sınıflar kullanın.

artıları: sadece çok az kamuya açık şey (sınıf, yöntem vb.) gerekli.

eksileri: Sınıflar sadece onları yapılandırmak için gizlidir. Bu, çok fazla statik iç sınıfın kullanıldığı çok az kullanım durumundan biri olacaktır. Geliştiriciler buna alışkın değil ve onları göz ardı edebilir.


İyi yapılandırılmış bir kütüphanede küçük bir API'ye ulaşmanın daha iyi bir yolu var mı?

Düzenleme: Bahsetmeyi unuttum: bir Android kütüphanesi için. Bu nedenle, java9 yok.


İç sınıflarınızın neden statik olması gerekiyor?
David Arno

İç sınıflar kod birimlerini büyütmez mi? Yani birkaç iç sınıfı olan bir sınıf çok uzun olabilir.
Tulains Córdova

2
@ TulainsCórdova, iyi bir nokta, "iç" terimini "iç" olarak okuyorum, bence Java "paket-özel" diyor. Bir lib oluşturmanın normal yolu, birkaç ortak sınıf içeren ve diğer her şeyin dahili / paket-özel olduğu bir pakete sahip olmaktır.
David Arno

Merhaba @ frmarkus. Daha belirgin olmak ve "ne soruyorsunuz belirsiz" yakın oylardan kaçınmak için soru başlığınızı yeniden yazmaya çalıştım. Gerçek sorunuzun yanlış olduğunu düşündüğünüz takdirde yeniden düzenlemekten çekinmeyin.
Andres F.

1
@ TulainsCórdova: Evet, kod birimleri çok büyük (dosya başına 3 bin kod satırı). Bu, bu yapılanma yolunun bir başka önemli sorunudur.
Markus Frauenfelder

Yanıtlar:


1

2 ile ne yaptığınızı görüyorum. Sınıfları paket olarak ve paket olarak modül olarak kullanıyorsunuz, böylece kendinizi paketin içinde izole edebiliyorsunuz, ancak yine de sınıfları kullanarak paket içinde organize edebiliyorsunuz.

Bu çok zekice. Akıllıca sakının.

Bu, aynı kaynak dosyada (tercih edebileceğiniz) birden çok sınıfı sıkışmaya zorlar ve yolun fazladan büyük bir sözcüğü olur.

Bu, dışarıdan içeri girmek için yansıma kullanmadığınız sürece, paket içinde herhangi bir test kodu yazmaya zorlar.

Bunun dışında, bu işe yarayacak. Sadece tuhaf görünecek.

İnsanlar Hashtable'da EntrySet gibi kullanılan iç sınıflara daha alışkınlar . Özeldir, bu yüzden onu oluşturamıyorum ama genel bir arayüz uyguluyor, bu yüzden sadece arayüz aracılığıyla konuşuyorum ve benim için bir şey var.

Ama bir arayüz aracılığıyla bile konuşmamı istemediğiniz sınıfları tanımlıyorsunuz. Yani benim için arayüz yok. Bu, bakacak ve kafam karışacak bir şeyim olmadığı anlamına gelir (bana kaynak sağlamadığınız sürece).

Tahmin ettiğim en büyük sorun, API'yi koruyan bu kafa karıştırıcı yeni başlayanlar. Dokümanları ve yorumları onlara atabilirsiniz, ancak ikisini de okumadıklarında veya güvenmediklerinde yerini almayın.

Dilde bir eksikliği telafi eden başka bir model daha oluşturdunuz. Java'nın bir grup pakete erişim izni veren erişim değiştiricisi yoktur. Bir "modül" erişim değiştiricisinin önerildiğini duydum, ancak bunun belirtisi olmadığını gördüm.

Varsayılan erişim değiştirici (değiştirici yok), miras yoluyla gizlice girmekten sakıncası yoksa, bu durumda korunacağınız olasılıkla burada kullanacağınız şeydir.

Modifier        Class     Package   Subclass  World
public          Y         Y         Y         Y
protected       Y         Y         Y         N
no modifier     Y         Y         N         N
private         Y         N         N         N 

Gerçekten istediğiniz modül erişimidir. Bu şekilde testlerinizi bir pakette ve kodunuzu başka bir pakette tutabilirsiniz. Ne yazık ki Java'da yok.

Çoğu kişi sadece 1 yapar ve API'yı genişletir. Arayüzlerin doğru kullanımı, uygulamanın baskısını önler.

İstediğinizi 1'e kesmek daha çirkin. Çağrı yığınına bakın ve sizi aradığınız şey hoşunuza gitmeyen bir paketten olduğunda bir istisna atın. Vayyy.


3

Elbette kodunuzu paketlere ayırın. Sürdürülebilirliği geliştirmek için uzun bir yol kat edecektir.

Son kullanıcıların, yapmamaları gereken şeylere erişmesini engellemek için API'nizi arayüz ve uygulamaya ayırmanız gerekir.

Java arayüzleri açısından tüm API'yı tanımlayarak ve uygulama nesneleri üretmek için bazı fabrika sınıfları sağlayarak bunu tam anlamıyla yapabilirsiniz. JDBC bunu yapar.

Ya da kural yoluyla, internalpaketler oluşturarak ve bu paketleri uygulamaya bağlı olarak ve uyarı veya geriye dönük uyumluluk olmadan değişikliğe tabi olarak belgeleyerek yapabilirsiniz.


1
Ne yazık ki, bu tam bir gitmek. Bu birçok kamu sınıfına bırakılıyor. İpuçlarına sahip olabilirler (fabrika veya 'dahili'). Ama onlara ( tüm kamu sınıfına) ek aletler uygulamak zorundayım , bu sadece iyi değil.
Markus Frauenfelder

@frmarkus - Bence (1) erişim kontrollerinden çok fazla beklediğinizi veya (2) bir paketin sınıflarının başka bir paketin sınıflarına bağlı kalmasını gerektirmeyecek şekilde paket yapınızı yeniden düşünmeniz gerektiğini düşünüyorum paketi (her şeyi statik iç içe sınıflar olarak tutabiliyorsanız, bu zor olmamalıdır).
kdgregory
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.