Java paketi düzey kapsamı yararlı mı?


11

Paket kapsamı fikrini anlıyorum ve bazen istediğimi bile düşündüm. Bununla birlikte, bunu kullanmayı denemek için ciddi bir niyetle yola çıktığımda, hizmet edeceğini düşündüğüm ihtiyaçlara uygun olmadığını keşfettim.

Benim asıl meselem her zaman kapsamını sınırlamak istediğim şeylerin asla aynı pakette olmamasıdır. Kavramsal olarak hepsi birbirine bağlı olabilir, ancak uygulama içindeki verilerin mantıksal bölünmesi, bunları daha büyük bir paketin ayrı alt paketleri olarak içerir.

Mesela bir Misyon modelim olabilir ve yalnızca MissionServices gibi diğer Misyon araçlarının bazı yöntemleri kullanmasını istiyorum. Ancak, paketlerim olarak Missions.models ve Missions.services ile sonlandırıyorum, bu yüzden MissionModel ve MissionService aynı paket kapsamı değil. Bu paketler, bu izinlere sahip olmak istemediğim çok sayıda şeyi içermeden, izinleri yükseltmek isteyeceğim şeyleri uygun bir şekilde içerdiği bir durum gibi görünmüyor; ve nadiren paket yönteminin kapsamını belirlemenin avantajını proje mimarimi her şeyi aynı pakete yerleştirecek şekilde değiştirmeyi haklı görüyorum. Genellikle Unsurlar veya kontrolün ters çevrilmesi, paket kapsamayı kısaca düşündüğüm herhangi bir soruna daha iyi bir yaklaşım olur.

Bunun genel olarak tüm Java geliştiricileri için geçerli olduğu düşünülüyor ya da yaptığım işin bir örneği. Paket kapsamı gerçek dünyada çok mu kullanılıyor? Kullanmanın iyi bir form olduğu düşünülen birçok durum var mı, yoksa modern gelişimde nadiren sömürülmek miras bir miras olarak görülüyor mu?

Paket özel kapsamının neden varsayılan olduğu hakkında bir şey sormuyorum, varsayılanlardan bağımsız olarak ne zaman kullanılması gerektiğini soruyorum. Neden varsayılan olduğu konusundaki tartışmaların çoğu, paket kapsamı gerçekten yararlı olduğunda gerçekten işe yaramaz, bunun yerine, yaygın olarak kullanılan diğer iki kapsamın neden varsayılan olmaması gerektiğini savunarak paket eleme işlemiyle kazanır. Buna ek olarak, sorum şu anki gelişme durumu hakkında . Özellikle, diğer araçların ve paradigmaların paket kapsamını daha az kullanışlı hale getirdiği noktaya kadar geliştirdik mi?


Düşünce deneyi: Paketleriniz olmasaydı Java programları nasıl olurdu? Büyük Java programlarına bakmamış veya üzerinde çalışmamış olabilirsiniz .
Robert Harvey

İçin kod bak java.util.Stringve java.util.Integer.


2
Yinelenen soruda en çok oylanan cevap, paket-özel için en önemli kullanımı kapsar ve neden yararlı olduğunu dolaylı olarak yanıtlar.

2
Kopyadan hiç ikna olmadım. Bu soru "Paket kapsamı ne için?" diğeri soruyor (diğer şeylerin yanı sıra) "Verilen paket kapsamı varsayılan, özel kapsam ne için?" Ayrıca dupe üzerinde kabul edilen cevap ve burada kabul edilen cevap tamamen farklı noktalar ortaya koymaktadır.
Ixrec

Yanıtlar:


2

java.util.*Paket boyunca kodun paket seviyesi korumayla yazıldığı durumlar vardır. Örneğin, bu bit java.util.String- Java 6'da bir kurucu :

// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

veya bu getChars yöntemi :

/** Copy characters from this string into dst starting at dstBegin. 
    This method doesn't perform any range checking. */
void getChars(char dst[], int dstBegin) {
    System.arraycopy(value, offset, dst, dstBegin, count);
}

Bunun nedeni, kod tasarımcılarının (ve java.util.*oldukça büyük bir kütüphane olarak düşünülebilmeleri), çeşitli güvenlik kaybı (diziler üzerinde aralık kontrolleri, diğer alanlara doğrudan erişim) pahasına daha hızlı performans elde etmek istedikleri yönündedir. arabirimden ziyade uygulamayı, sınıfın kamusal yöntemlerle değiştirilemeyeceği düşünülen bölümlerine 'güvensiz' erişim anlamına gelir).

Bu yöntemlere ve alanlara yalnızca java.utilpaketteki diğer sınıflar tarafından erişilmesini kısıtlayarak , aralarında daha yakın bağlantı kurulmasını sağlar, ancak bu uygulama ayrıntılarının dünyaya ifşa edilmesini de önler.

Bir uygulama üzerinde çalışıyorsanız ve diğer kullanıcılar için endişelenmeniz gerekmiyorsa, paket düzeyinde koruma endişelenmeniz gereken bir şey değildir. Tasarım saflığının çeşitli yönleri dışında, her şeyi yapabilir publicve bununla iyi olabilirsiniz.

Ancak, başkaları tarafından kullanılacak bir kütüphane üzerinde çalışıyorsanız (veya daha sonra yeniden düzenleme için sınıflarınızı çok fazla karıştırmaktan kaçınmak istiyorsanız), ihtiyaçlarınız için size verilen en katı korumayı kullanmalısınız. Genellikle bu demektir private. Bununla birlikte, bazen, kendinizi tekrar etmekten kaçınmak veya gerçek uygulamayı iki sınıfın birleştirilmesi ve uygulamaları pahasına biraz daha kolaylaştırmak için, uygulama ayrıntılarının bir kısmını aynı paketteki diğer sınıflara göstermeniz gerekir. Böylece paket seviye koruması.


1
Java.util'e baktım ve görüyorum. Ancak, ben de bir BÜYÜK kütüphane olduğunu fark. Günümüzde büyük kütüphanelerin alt paketleri kullanmadan nadiren yazıldığı anlaşılmaktadır; ve sınırlara götüren alt paket bölümleridir. Java.util yanlış olduğunu söylemiyorum, ama onlar sadece bir paket içinde oldukça sınırlı bir kapsülleme ile her şeyi doğru yapmak için güvenebiliyordu çünkü son derece iyi programcılar vardı çünkü onlar büyük bir paket ile kurtulmak gibi görünüyor ; Benim gibi benzer paketler üzerinde çalışabilecek ortalama geliştiricilere kötü davranma potansiyeline güvenerek çıplak hissediyorum.
dsollen

1
@dsollen Spring ve Hibernate veya benzeri büyük kütüphanelere girerseniz benzer şeyler bulacaksınız. Daha yakın bağlantıya ihtiyaç duyduğunuz zamanlar vardır. Başvuruları kodları gözden geçirme ve her şeyin doğru olduğundan emin olma fırsatı olmalıdır . Daha yakın bağlantıya ihtiyacınız yoksa veya diğer kodlayıcılara hiç güvenmiyorsanız, ortak alanlar veya paket veya korunan alanlar veya yöntemler her zaman uygun değildir. Ancak bu yararlı olmadığı anlamına gelmez.

Kısacası, günlük ihtiyaçlarım için daha kısıtlı paketler yapmaya ve optimizasyon seviyesinden (projelerin sadece% 95'inde bir israftır) endişelenmemeye cazip geleceğim. Bu yüzden takip sorum şu olur: Paket seviyesi kapsamı, yalnızca yaygın olarak kullanılan bazı büyük API'lerde kullanılan çok özel bir optimizasyon potansiyeli midir? IE sadece büyüklerin bu dereceye kadar korumaları gevşetmek gerekir, ya da istiyorum? Daha küçük kullanıcı tabanlarına sahip 'standart' API üzerinde bile çalışan iyi programcıların bunun için fayda bulması için nedenler var mı?
dsollen

Takip görevimi yeterince hızlı alamadım :) Anladığınız ve anladığınız şeyi anlıyorum, hiç tartışmıyorum. Dahası, geri kalan iyi programcılar için yararlılığı konusunda bir takip sorusu sormak, ancak bu kadar büyük API'lerde çalışmayacak olanlar. Özellikle, çoğunlukla gerçekten gerçekten ince ayar yapmanız gerektiğinde yapılan kapsülleme geliri pahasına bir optimizasyon mu ?
dsollen

2
@ dsollen performansla ilgili değil (uygulamayı göstermek için bir sebep olsa da) kapsülleme. Bunu için kod tekrarlamaktan kaçınmak için ne Integer.toString()ve String.valueOf(int)dünyaya maruz kalmadan kod paylaşabilir. java.utilSınıflar yerine tamamen kendi başlarına adalar bireysel sınıfları olmaktan daha işlevselliği daha büyük bir bütün sunmak amacıyla uyum içinde çalışmak - onlar paket düzeyinde kapsam belirleme yoluyla bir paket ve hisse uygulama işlevselliği bir arada.

5

Bazen, bir junit testinin dışarıdan erişilmemesi gereken bazı uygulama ayrıntılarına erişmesine izin vermek için özel veya korumalı yöntemlerin görünürlüğünü arttırır.

junit-testi, test altındaki öğe ile aynı pakete sahip olduğundan, bu uygulama ayrıntılarına erişebilir

misal

  public class MyClass {
    public MyClass() {
        this(new MyDependency());
    }

    /* package level to allow junit-tests to insert mock/fake implementations */ 
    MyClass(IDependency someDepenency) {...}
  }

Bunun "iyi" bir kullanım olup olmadığı tartışmalıdır, ancak pragmatiktir.


2
Testleri her zaman farklı bir pakete koyarım, aksi takdirde varsayılan kapsamda kimsenin aramasına izin vermeyen bazı anahtar yöntemleri bıraktım ...
soru

Bunu asla yöntemlerle yapmıyorum, ancak enjekte edilen bağımlılıklar için kullanmak güzel bir özellik. Örneğin, EJB'leri test ederken, enjekte edilen EntityManagers, uygulama zamanında uygulama sunucusu tarafından enjekte edileceği bir Mock nesnesiyle paket düzeyinde EM ayarlanarak alay edilebilir.
jwenting

Neden protectedpaket kapsamına yükseltilmeli ? protected zaten paket erişimi sağlıyor. Biraz garip bir tuhaflık, ama bence protected packagescope void doSomething()(aynı zamanda yeni bir anahtar kelime gerektirir) gibi bileşik kapsam bildirimleri istemiyorlardı .
tgm1024 - Monica

2

İnsanların paketlerin noktalı adlarını sanki alt paketlermiş gibi kullanma eğiliminde oldukları bir dünyada, özellikle varsayılan olarak, bu kadar kullanışlı değildir. Java'nın alt paket diye bir şeyi olmadığından, xyinternals'ın xy'ye ab'den daha fazla erişimi yoktur. Paket adları aynı veya farklıdır, kısmi eşleşme ortak hiçbir şeye sahip olmaktan farklı değildir.

Sanırım orijinal geliştiriciler bu sözleşmenin kullanılmasını hiç beklemiyorlardı ve Ada tarzı hiyerarşik paketlerin karmaşıklığını eklemeden işleri basit tutmak istediler.

Java 9 bunu ele alıyor, çünkü bir modüle birkaç paket koyabilir ve sadece bazılarını dışa aktarabilirsiniz. Ancak bu, paket kapsamını daha fazla gereksiz hale getirecektir.

İdeal bir dünyada, varsayılan kapsamı 'içeren bir modül varsa modül kapsamı, aksi takdirde paket kapsamı' olarak değiştirirler. Daha sonra dışa aktarılan arayüzleri bozmadan yeniden düzenlemeye izin vererek bir modül içindeki uygulamayı paylaşmak için kullanabilirsiniz. Ama belki de bunun geriye dönük uyumluluğu bozmasının veya başka türlü kötü olmasının bazı incelikleri vardır.


Java 9 yorumunu ilginç buluyorum. Ben paket herachies tanımak ve bir şekilde bazı üst paket (ek açıklamaları kullanarak?) Göre paket kapsamı tanımlamak için basit bir yeteneği güzel olurdu düşünüyorum.
dsollen

1
@dsollen, belki de, ama ilk eğilimim lastik ütülerle altın plaka yapmaya başlamamızdır. Bence açıklığa kavuşturmanın çok daha iyi bir ilk adımı (ki bu bir dereceye kadar güvenliği beraberinde getirir) gerçek bir paket kapsam anahtar kelimesi icat etmek olacaktır. Hatta "paket" olabilir :)
tgm1024 - Monica

2

Kohezyon tipi senin açıklayan gerçekten paket erişimi olacağı durumlara en iyi örnek değildir. Paket, bir arabirimde değiştirilebilir parçalar, modüller oluşturmak için kullanışlıdır.

İşte senaryonun kabaca bir örneği. Kodunuzun işlevsel uyum ve bileşenleştirme etrafında daha fazla olacak şekilde yeniden düzenlendiğini varsayalım. Belki 3 kavanoz gibi:

**MissionManager.jar** - an application which uses the Java Service Provider Interface to load some implementation of missions, possible provided by a 3rd party vendor.

**missions-api.jar** - All interfaces, for services and model
    com...missions
        MissionBuilder.java   - has a createMission method
        Mission.java - interface for a mission domain object
    com...missions.strategy
        ... interfaces that attach strategies to missions ...
    com...missions.reports
        .... interfaces todo with mission reports ....

   **MCo-missionizer-5000.jar** -  provides MCo's Missionizer 5000 brand mission implementation.
       com...missions.mco
                  Mission5000.java - implements the Mission interface.
       com...missions.strategy.mco
              ... strategy stuff etc ...

Mission5000.java'daki paket düzeyini kullanarak, başka hiçbir paketin veya MissionManager gibi bir bileşenin görev uygulamanızı birleştiremeyeceğinden emin olamazsınız. "M co" dan sadece "3. taraf" sağlanan bileşen aslında bir Misyonun kendi özel markalı uygulamasını yaratır. Mission Manager, MissionBuiler.createMission (...) 'u çağırmalı ve tanımlanan arabirimi kullanmalıdır.

Bu şekilde Mission uygulama bileşeni değiştirilirse, MissionManager.jar uygulayıcılarının api'yi atlamadığını ve MCo'nun uygulamasını doğrudan kullanmadığını biliyoruz.

Bu nedenle, rakip bir ürünle MCo-missionizer5000.jar dosyasını değiştirebiliriz. (Veya belki de Görev Yöneticisini test eden bir Mock)

Buna karşılık MCo, tescilli misyoner ticaret sırlarını saklayabilir.

(Bu, bileşenlerde de İstikrarsızlık ve Soyutluk fikirlerinin uygulanmasıyla ilgilidir .)


-1

Java'daki paket kapsamı hiyerarşik olarak tasarlanmadığından pek kullanışlı değildir. Paket kapsamını hiç kullanmayız ve tüm sınıfları herkese açık olarak tanımlarız.

Bunun yerine, paket hiyerarşisine ve önceden tanımlanmış paket adlarına dayalı olarak kendi erişim kurallarımızı kullanırız.

Eğer ayrıntılarla ilgileniyorsanız google "CODERU-Rules" için.

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.