Java'nın ortak alanları bu noktada sadece trajik bir tarihsel tasarım hatası mıdır? [kapalı]


17

Bu noktada Java ortodoksisi, nesne durumu için hiçbir zaman genel alanları kullanmamalıdır. (Mutlaka hemfikir değilim, ama bu benim sorumla ilgili değil.) Buna göre, bugün bulunduğumuz yerden Java'nın ortak alanlarının dil tasarımında bir hata / kusur olduğunu söylemek doğru olur mu? Yoksa bugün bile dilin yararlı ve önemli bir parçası olduklarının rasyonel bir argümanı var mı?

Teşekkürler!

Güncelleme: C #, Python, Groovy vb. Gibi daha zarif yaklaşımları biliyorum. Doğrudan bu örnekleri aramıyorum. Gerçekten sadece bir sığınakta derin bir insan olup olmadığını merak ediyorum, kamu alanlarının gerçekten ne kadar harika olduğunu ve kitlelerin nasıl sadece koyun vb.

Güncelleme 2: Açıkça statik nihai ortak alanlar, genel sabitler oluşturmanın standart yoludur. Daha çok nesne durumu (hatta değişmez durum) için kamusal alanları kullanmaya atıfta bulunuyordum. Ben sabitler için kamu alanları kullanmak gerekir, ancak devlet için değil bir tasarım kusuru gibi görünüyor düşünüyorum… bir dil kuralları kurallar tarafından değil, sözdizimi ile doğal olarak uygulanmalıdır.


2
Gerçekten de bir kusur olmalarının temeli nedir?
Aaron McIver

1
Şimdi Java'da sembolik sabit ifadeler oluşturmanın farklı bir yolu var mı?
Edward Strange

@Aaron Bir kusur olduklarını söylemiyordum, bu noktada bir kişinin asla kamusal alanları kullanmaması gerektiğini ortodoksluk olarak algıladığımı söylüyordum. Bu algı yanlış olabilir, ama gerçekten algıladığım şey bu.
Avi Flax

@Crazy Eddie Bu kullanımı unuttum, tarlaların daha yaygın kullanımını düşünüyordum, devlet. Soruyu düzenleyeceğim.
Avi Flax

Yanıtlar:


14

Alan son olduğu ve yalnızca uygulamada dahili olarak kullanıldığı sürece, diğer uygulamalar için bir API'de gösterilmediği sürece onları seviyorum . Bu, kodunuzu daha kısa ve daha okunabilir tutar.

Ortak alanları açığa çıkararak, uygulamayı da açığa çıkardığınız için API'daki ortak alanları göstermemelisiniz. getXXX()Bunun yerine bir yöntem olarak ortaya çıkarırsanız , API arabirimini değiştirmeden uygulamayı değiştirebilirsiniz. Örneğin, değeri uzak bir hizmetten değiştirebilir ve alabilirsiniz, ancak API'yi kullanan uygulamaların bunu bilmesi gerekmez.

Bu, değişmez sınıflardaki public finalalanlar için uygun bir tasarımdır .

Gönderen Etkili Java :

Madde 14: Ortak sınıflarda, ortak alanları değil erişimci yöntemlerini kullanın

... bir sınıf pakete özelse veya özel bir iç içe sınıfsa, veri alanlarını açığa çıkarmanın doğasında yanlış olan hiçbir şey yoktur. Bu yaklaşım, erişimci yöntemi yaklaşımından daha az karmaşa oluşturur.

Bir kamu sınıfının alanları doğrudan ortaya çıkarması asla iyi bir fikir olmasa da, alanların değişmez olması daha az zararlıdır.

Ayrıca bkz. Neden JavaBeans yerine değişmez POJO kullanmamalıyım?


Sadece bir API'da göstermemenin nedenleriniz nelerdir?
Steven Jeuris

2
@Steven: Çünkü ortak alanları açığa çıkararak uygulamayı da açığa çıkarırsınız. getXXX()Bunun yerine bir yöntem olarak ortaya çıkarırsanız , API arabirimini değiştirmeden uygulamayı değiştirebilirsiniz. Örneğin, değeri uzak bir hizmetten değiştirebilir ve alabilirsiniz, ancak API'yi kullanan uygulamaların bunu bilmesi gerekmez.
Jonas

@Jonas: Bunlar genelde sabitler için aday değiller.
Steven Jeuris

@Steven: İlk etapta sabitlerden değil , değişmez sınıflarda kamuya açık nihai alanlardan bahsediyorum . Örn : JavaBeans yerine neden değiştirilemez POJO kullanmamalıyım?
Jonas

@Jonas: Bu da güzel bir kullanım örneği! Belki cevabınızı açıklığa kavuşturmak için biraz güncellemeniz yararlı olabilir.
Steven Jeuris

9

Get / set yöntemi çiftlerinin kullanılması trajik tarihsel tasarım hatasıdır. Özellikleri ayrıntılı ve verimsiz bir şekilde uygulayan başka bir dil düşünemiyorum.


1
Doğru olsa da, bu soru noktasına biraz teğetseldir, yani (esasen) set / get yöntemleri ve kamu alanları arasında seçim yapıldığında, bazı durumlarda alanları tercih etmek için iyi nedenler var mı? Diğer dillerin soruna daha iyi çözümler sunması bana önemsiz geliyor.
Jules

5

Bence ortak alanlar, karmaşık bir sayı veya nokta gibi bir değer türü olan bir sınıf için uygundur, burada sınıf, C tarzı bir yapı gibi grup ilkel türlerinden biraz daha fazlasını yapar ve belki de birkaç işleç tanımlar.


2
java.awt.Pointve arkadaşlar biraz kabus.
Tom Hawtin - taktik

@ TomHawtin-tackline: Sorun , türdeki Pointbir değişkeninPoint bir konumu kapsüllemek veya bir kimliğin değişebilecek bir konuma sahip olması gerekip gerekmediğinin belirsiz olmasıdır. Kavramsal olarak, geçen Pointkodun dizilerin etrafındaki kod gibi olduğunu düşünürüm.
supercat

Yani bir alır Pointve değiştirirseniz, atıfta bulunulan nesnenin ekranda temiz bir şekilde güncellenmesini beklemeliyim? Hayır, sorun Pointdeğişebilir olmasıdır. Biz vardı String/ StringBufferama fikir elde etmek gibi görünmüyordu. / Dizilerin etrafından geçmenin de benzer sorunları var.
Tom Hawtin - tackline

5

Genel sabitleri tanımlamak hala yararlıdır. Örneğin

genel statik son int DAYS_IN_WEEK = 7;

Ancak yine de mümkünse enum'ları tercih edin . Örneğin

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

To basit yapı sınıfları simüle o da yararlıdır. Her şekilde, her yerde herkese açıkken, bir alan ve ayarlayıcı oluşturmak için bir neden yok.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Ama sonra tekrar, birçok yapı yapıları Java gibi bir dilde yer yok ...

1
@delnan: JavaBeans ile neredeyse aynılar, ancak JavaBeans çok daha ayrıntılı ve threadsafe değil. Bkz yerine JavaBeans değişmez POJOs kullanmamalısınız Neden?
Jonas

Android'e özgü bazı gözlemler: Enumların değerlendirilmesi intlerden daha yavaştır ve kaçınılmalıdır. Ayrıca, sıkı döngülerdeki ayarlayıcılar ve alıcılar tarafından sıkça erişilen alanlar da halka açık olmaktan yararlanabilir.
Nailer

2

IDE'ler yaygınlaşmadan önce, tüm alanlarınızı herkese açık hale getirmek, kavramların prototiplerini / kanıtlarını hızlı bir şekilde oluşturmak için güçlü bir araçtır.

Günümüzde, fare tıklamasıyla bir alıcı / ayarlayıcı çifti oluşturabildiğinizde, bunları kullanmak için çok az mazeret vardır.


4
Ancak 10 public finalalan 10 getXXX()yöntemden daha okunabilir .
Jonas

1
@Jonas Evet, ama buradaki son alanlardan bahsetmiyoruz. Herkese açık nihai alanlarınız da statikse sabittir ve bir constanahtar kelime yeterli olur; statik değilse, ciddi bir kapsülleme ihlalidir.
biziclop

3
@biziclop Wikipedia'ya göre : "Java'da bir anahtar kelime olarak ayrılmış olmasına rağmen, const kullanılmıyor ve hiçbir işlevi yok"
Avi Flax

@Avi Flax Evet, ancak sabitleri işaretlemek için kullanılabilir, böylece sabitleri kamusal alan olarak ilan etme gereği ortadan kalkar.
biziclop

2
Alıcı / ayarlayıcı çiftinin uygun olduğunu varsayarsak, yani. Genellikle değil.
David Thornley

2

Bu sübjektiftir, ancak benim düşüncem, tüm kamu / özel kavramının modası geçmiş ve geriye dönük olmasıdır.

Python'da genel / özel yoktur; temelde her şey herkese açıktır. Çok fazla soruna yol açmadı.

Java'da, "genel" olarak işaretleme günahını önlemek için her alan için anlamsız alıcılar / ayarlayıcılar oluşturma eğilimindesiniz. (IMHO eğer bunu yaparken kendinizi herkese açık olarak işaretlemeniz gerekir).


Python, adlara __ öneki ekleyerek işleri özel olarak işaretlemenize izin verir. Bu değişkenlere ve yöntemlere erişmenin hala yolları olduğu için% 100 özel değil, ancak C # 'da yansıma ile benzer şeyler yapabilirsiniz.
Adam Lear
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.