Gibi kod:
public Thing[] getThings(){
return things;
}
Erişim yönteminiz doğrudan dahili veri yapısını döndürmekten başka bir şey yapmadığı için çok mantıklı değil. Siz de öyle olduğunuzu beyan Thing[] things
edebilirsiniz public
. Bir erişim yönteminin arkasındaki fikir, istemcileri dahili değişikliklerden yalıtan ve arayüzün izin verdiği gizli yöntemler dışında gerçek veri yapısını manipüle etmelerini engelleyen bir arayüz oluşturmaktır. Tüm müşteri kodunuz kırıldığında keşfettiğiniz gibi, erişim yönteminiz bunu yapmadı - sadece boşa giden kod. Bence bir çok programcı böyle kod yazma eğilimindedir çünkü bir yerde her şeyin erişim yöntemleri ile kapsüllenmesi gerektiğini öğrendiler - ama açıkladığım nedenlerden dolayı. Erişim yöntemi herhangi bir amaca hizmet etmediğinde bunu sadece "formu takip etmek" için yapmak sadece gürültüdür.
Kapsüllemenin en önemli hedeflerinden bazılarına ulaşan önerilen çözümünüzü kesinlikle tavsiye ederim: Müşterilere, onları sınıfınızın dahili uygulama ayrıntılarından yalıtan ve dahili veri yapısına dokunmalarına izin vermeyen sağlam, gizli bir arayüz sağlamak karar verdiğiniz yolların uygun olmasını bekleyin - "en az gerekli ayrıcalık yasası". CLR, STL, VCL gibi büyük popüler OOP çerçevelerine bakarsanız, önerdiğiniz desen tam olarak bu nedenle yaygındır.
Bunu hep yapmalı mısın? Şart değil. Örneğin, asıl işçi sınıfınızın bir bileşeni olan ve "önden bakan" olmayan yardımcı veya arkadaş sınıflarınız varsa, bu gerekli değildir - bu çok fazla gereksiz kod ekleyecek bir aşırıya kaçmadır. Ve bu durumda, hiç bir erişim yöntemi kullanmazdım - açıklandığı gibi anlamsız. Veri yapısını yalnızca onu kullanan ana sınıfa dahil bir şekilde beyan edin - çoğu dil bunu yapmanın yollarını destekler - friend
veya ana işçi sınıfı ile aynı dosyada beyan eder.
Teklifinizde görebildiğim tek dezavantajı , kodlamak için daha fazla iş olması (ve şimdi tüketici sınıflarınızı yeniden kodlamanız gerekecek - ama yine de bunu yapmak zorundasınız / zorundasınız.) Ama bu gerçekten dezavantaj değil - doğru yapmanız gerekir ve bazen bu daha fazla iş gerektirir.
İyi bir programcıyı iyi yapan şeylerden biri, ekstra işin ne zaman ve ne zaman değmez olduğunu bilmeleridir. Uzun vadede ekstra koymak şimdi gelecekte büyük temettüler ile ödeyecek - bu projede değilse, o zaman diğerleri üzerinde. Doğru şekilde kodlamayı öğrenin ve sadece öngörülen formları robotik olarak takip etmekle kalmayın, başınızı bu konuda kullanın.
Dizilerden daha karmaşık koleksiyonların, yalnızca dahili veri yapısına erişmek için üçten fazla yöntem uygulamayı gerektiren ek sınıf gerektirebileceğini unutmayın.
Tüm veri yapısını bir kapsayıcı sınıf aracılığıyla açığa çıkarıyorsanız, IMO, yalnızca daha güvenli bir arabirim - bir "sarmalayıcı sınıfı" sağlamak değilse, bu sınıfın neden hiç kapsüllenmediğini düşünmeniz gerekir. Kapsayıcı sınıfın bu amaç için mevcut olmadığını söylüyorsunuz - belki de tasarımınızla ilgili doğru olmayan bir şey var. Sınıflarınızı daha gizli modüllere ayırmayı ve katmanlamayı düşünün.
Bir sınıfın açık ve gizli bir amacı olmalı ve artık bu işlevselliği desteklemek için bir arayüz sağlamalıdır. Birbirine ait olmayan şeyleri bir araya toplamaya çalışıyor olabilirsiniz. Bunu yaptığınızda, her değişiklik uyguladığınızda işler bozulacaktır. Sınıflarınız ne kadar küçük ve ihtiyatlısa, bazı şeyleri değiştirmek o kadar kolay olur: LEGO düşünün.
get(index)
,add()
,size()
,remove(index)
, veremove(Object)
. Önerilen tekniği kullanarak, bu ArrayList'i içeren sınıfın yalnızca iç koleksiyona delege etmek için beş genel yöntemi olmalıdır. Ve bu sınıfın programdaki amacı büyük olasılıkla bu ArrayList'i kapsüllemek değil, başka bir şey yapmaktır. ArrayList sadece bir ayrıntı. [...]