Nasıl bir nesne yöntemi içinde Nesne özelliklerine erişmek?

19 Cevap java

"Saf" veya alıcı / ayarlayıcı yöntemi değil bir nesne yöntemi içinde bir nesnenin özelliklerine erişmek için "doğru" yolu nedir?

Ben nesnenin dışından bir alıcı / ayarlayıcı kullanmanız gerektiğini biliyorum, ama içinde sadece yapardın:

Java:

String property = this.property;

PHP:

$property = $this->property;

ya da yapardı:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Benim Java biraz kapalı olup olmadığını beni affet Java programlanmış bu yana, bu bir yıl oldu ...

EDIT:

Bu insanlar sadece özel veya korunan değişkenler / özellikleri bahsediyorum varsayarak görünüyor. Ben Ö.Ö. öğrendim ben kamu (ve aslında herhangi bir değişken / özellik kamuoyuna asla söylendi) olsa bile her bir özellik için alıcılar / ayarlayıcıları kullanmak öğretildi. Yani, ben gidip almak yanlış bir varsayım kapalı başlangıç ​​olabilir. Bu soruya cevap insanlar belki kamu özelliklere sahip olması gerektiğini söyleyerek ve bu anlaşılmaktadır belki olarak tartışılması gerektiğini, ancak bu, ben neden bahsettiğini ben öğretildi ne aykırı olan, alıcı ve ayarlayıcıları gerek yoktur ve iyi. Gerçi muhtemelen farklı bir soru için iyi bir konu var ...

19 Cevap

Bu dini savaş potansiyeline sahiptir, ama bir alıcı / ayarlayıcı kullanıyorsanız, siz de dahili olarak kullanmak gerekir gibi geliyor bana - her ikisini de kullanarak (örneğin birisi bir pasör için kod ekler yolda bakım sorunlara yol açacağı { [(0)]} özelliği ayarlandığında her zaman çalıştırmak için, ve mülkiyet w /) o setter çağrıldığını o dahili olarak ayarlanır ediliyor.

Tutarlı kalması için önemli gibi Şahsen ben hissediyorum. Eğer alıcı ve ayarlayıcıları varsa, bunları kullanın. Erişimci yükü bir sürü var ben doğrudan bir alana ulaşmak istiyorsunuz tek zamandır. Eğer gereksiz yere kodunuzu şişkinlik konum gibi hissedebilirsiniz, ama kesinlikle gelecekte baş ağrısı bir sürü kaydedebilirsiniz. Klasik bir örnek:

Daha sonra, o alan çalışma biçimini değiştirmek isteyebilirler. Belki on-the-fly hesaplanması gerektiği ya da belki yedekleme deposu için farklı bir tür kullanmak istiyorum. Doğrudan özelliklerine erişme iseniz, böyle bir değişiklik, bir kabarma Foop kod bir çok şey zarar verebilir.

Ben duygu alıcılar ve belirleyiciler, ince ve iyi olmasıdır kadar oybirliği ile oldukça şaşırdım. Ben Allen Holub tarafından kışkırtıcı makale "Getters And Setters Are Evil" öneririz. Verilen başlık şok değeri için, ama yazar geçerli puan yapar.

Eğer her özel alan için alıcı ve ayarlayıcıları varsa Esasen, siz halk olarak iyi bu alanları yapıyoruz. Çok bu oltalarını çağıran her sınıfa dalgalanma etkileri olmadan özel bir alanın türünü değiştirmek için üzüntülü olurdu.

Dahası, görüş kesinlikle OO noktadan, nesnelerin kendi (umarım) tek sorumluluk karşılık mesajları (yöntemleri) yanıt olmalıdır. Alıcılar ve belirleyiciler büyük çoğunluğu oluşturan nesnelerin için mantıklı değil; Pen.dispenseInkOnto (Yüzey) Pen.getColor () benim için daha mantıklı.

Alıcılar ve belirleyiciler de, bazı veriler için nesneyi sormak için sınıfı kullanıcıları teşvik hesaplama yapmak ve daha sonra nesnenin diğer bazı değerini ayarlamak, iyi prosedürel programlama olarak da bilinir. Sen daha iyi sadece size ilk etapta gittiğini ne yapmak nesneyi anlatmak için hizmet ediyorum; Ayrıca, Information Expert deyim olarak da bilinir.

Benzeri UI, sebat, ve - Alıcılar ve belirleyiciler, ancak, gerekli katmanların sınırında kötülükler vardır. Böyle C + + 'ın arkadaşı anahtar kelime, Java'nın paket korumalı erişim,. NET'in dahili erişim, ve Friend Class Pattern onlara ihtiyacınız sadece o kim için alıcılar ve belirleyiciler görünürlüğünü azaltmaya yardımcı olabilir gibi bir sınıfın iç yapısına, kısıtlı erişim.

Bu özelliği nasıl kullanıldığına bağlıdır. Örneğin, bir isim özelliğine sahip bir öğrenci nesnesi var söylüyorlar. Sen zaten alınmamış ise, veritabanından adını çekmek için Get yöntemi kullanabilirsiniz. Bu şekilde veritabanına gereksiz aramalar azaltmaktadır.

Şimdi size kaç kez isim adı olmuştur sayar nesne özel bir tamsayı sayaç var diyelim. Bunu geçersiz sayılmasını üretecektir çünkü nesnenin içinden Get yöntemi kullanmak değil isteyebilirsiniz.

Ben sadece denize buraya gidiyorum?

Belki ;)

Başka bir yaklaşım aslında (önbelleğe / db / etc) ve sayısı artar bunun için bir kamu sarıcı almak edersiniz / özel bir koruma yöntemi kullanmak olacaktır:

PHP:

public function getName() {
$this->incrementNameCalled();
return $this->_getName();
}

protected function _getName() {
return $this->name;
}

ve daha sonra nesnenin kendisinden:

PHP:

$name = $this->_getName();

Bu şekilde hala (belki burada önbelleğe alınmış verileri kullanılmış olup olmadığını bir bayrak gönderme gibi) başka bir şey için o ilk argümanını kullanabilirsiniz.

PHP sihirli yöntemler __get ve __set dahil olmak üzere bu işlemek için yollar, sayısız sunmaktadır, ama ben açık alıcı ve ayarlayıcıları tercih. İşte sebebi:

  1. Doğrulama (bu konuda ve alıcılar) ayarlayıcıları yerleştirilebilir
  2. Intellisense açık yöntemlerle çalışır
  3. Bir özellik okunur olup olmadığını soru yok, sadece, yalnızca yazma veya okuma-yazma
  4. Sanal özellikleri (yani, hesaplanan değerler) alınıyor düzenli özellikleri olarak aynı görünüyor
  5. Kolayca sonra belgesiz gider, aslında her yerde tanımlanan asla bir nesne özelliği ayarlayabilirsiniz

Eğer o nesnenin bir özelliğine erişmek için bir nesne içinde bir alıcı kullanmak neden ben, burada noktayı eksik olmalı?

Onun sonuca alırsak alıcı bir alıcı aramalısınız hangi bir alıcı aramak gerekir.

Ben sadece bir anlamsız, savurgan egzersiz özellikle (sadece geri sonra doğrudan zaten özelliğine erişecek) o nesnenin başka bir yöntemini çağıran gibi görerek, bir özellik doğrudan bir nesne yöntemi erişimi içeride derim (ya da ben soruyu yanlış anlamışsın .)

Bazı yorumlar belirtildiği gibi: Bazen gerekir bazen olmamalıdır. Özel değişkenler hakkında büyük bir kısmı size bir şey değiştirmek zaman kullanılan tüm yerleri görmek mümkün olmasıdır. Lütfen alıcı / ayarlayıcı gereken bir şey yaparsa, onu kullanın. Farketmez eğer siz karar verin.

Tersi durumda sizin alıcı / ayarlayıcı kullanın ve biri alıcı / ayarlayıcı değişikliği eğer alıcı ve ayarlayıcı o kadar şey dağıtırsa görmek için dahili olarak kullanılan tüm yerleri analiz etmek zorunda olduğunu yapılabilir.

Peki, bu karar size alınır C # 3.0 gayrimenkullerin varsayılan uygulama ile görünüyor; Eğer (muhtemelen özel) mülkiyet setter kullanarak özelliğini ayarlamak zorunda.

Bunu yaparken zaman değil ben şahsen sadece özel üye arkasında kullanmak nesnesi, önbelleğe / tembel yükleme söz konusu olduğunda başlatılıyor veya olduğu gibi, bir daha az arzu durumuna düşmesine sebep olur.

Ben yetiştirdim olduğum için ben yanlış olabilir, ama dışarıda kod alıcılar / belirleyiciler tarafından erişmesi gerekir ki ben, onlar, daima özel veya korunan benim Java clases kullanıcı kamu malıdır ASLA. Bu mainteance / modifikasyon amaçlar için daha iyi. Ve içeride sınıf kodu için ... alıcı bir yöntemdir önemsiz olup olmadığını ben doğrudan özelliğini kullanın, ama kolayca kod eklemek çünkü ben daima ben isterseniz olayları yangın setter yöntemleri kullanın

Ben belirleyiciler / alıcıları okumak kolay kodumu yapılan kullanarak bulduk. Ben de diğer sınıfların yöntemleri kullanmak ve ben verileri değiştirmek eğer özellik saklayacak zaman verir denetimi gibi.

Kamu veya korumalı özelliklere sahip özel alanlar. Değerlere erişim özellikleri geçmesi gerektiğini ve bir zamanlar bir yöntem daha fazla kullanılması gerektiği takdirde yerel bir değişkene kopyalanır. Ve bunu tamamen tweaked uygulamanın dinlenme SADECE, dışarı sarsıldı, ve aksi takdirde onların gelişmişlerdir özellikleri geçerek değerlerini erişimde bir darboğaz haline geldiği için optimize (Ve o HİÇ asla olmayacak, ben garanti) bile başlamalıdır özellikleri doğrudan destek değişkenleri dokunmak başka bir şey icar düşünün.

Hatta tasarım zamanında destek değişkenleri göremiyorum beri. NET geliştiricileri bu zorlamak için otomatik özelliklerini kullanabilirsiniz.

Tarafından "saf" siz "en kapsüllenmesini" demek, sonra ben genellikle sınıfın kendisi içinde this.field sonra kullanın ve özel olarak tüm alanları beyan, ama alt sınıflar da dahil olmak üzere diğer tüm sınıflar, erişim örnek devlet alıcılar kullanıyorsanız.

Ben özellik düzenleme olmaz ise ben gibi kendisine sadece mülkiyet, kamu ve söz edeceğim bu durumda böyle başka bir nesnenin içinde bir MySQLi nesnesi olarak özel bir durum olmadığı sürece ben bir get_property() public bir yöntem kullanacağız $obj->object_property.

Nesnenin içinde her zaman benim için $ this-> özellik bulunuyor.

I cmcculloh tarafından cevabını, ancak en doğru Greg Hurlman tarafından cevap gibi görünüyor. Eğer getgo bunları kullanarak ve / veya onlarla birlikte çalışma için kullanılan başladı eğer alıcı / ayarlayıcıları her zaman kullanın.

Bir kenara, ben şahsen alıcı / ayarlayıcıları kullanarak okuma ve daha sonra hata ayıklamak için daha kolay kod yapar bulabilirsiniz.

Duruma göre değişir. Bu her şeyden daha bir stil sorunu var, ve hiçbir sabit bir kural yoktur.

'Saf' OO yolu hem önlemek ve bir "Sorma söyle" yaklaşımı kullanmaktır. Bunun yerine nesnenin değerini alma ve doğrudan onunla bir şey yapıyor, bir parametre olarak örneğin nesnesini kullanın

  doSomethingWithProperty( this.property ) ;

Özellik yerel bir tür, örneğin neredeydi Bu herhangi bir post-koşullarını ya bağımlı değişmezleri korumak sağlayacaktır çünkü int, bir erişim yöntemi kullanın. Ayrıca, herhangi bir ön-şart veya bağımlı değişmezleri korumak için ayarlayıcı yöntemi kullanmalısınız.

Ben nadiren programlama alıcılar / belirleyiciler için ihtiyacı hissediyorum, o gerçekten ne yaptığınızı bağlıdır ...

I will sometimes use getters/setters if the member variable is far away.
Ex. Instead of Player.Position.X I'd use

Player.getX()

Side note: Özel üye değişkenler kamu yerine erişmek için daha uzun sürer

ben bile nesne içindeki erişimci yöntemleri kullanmak için onun daha iyi söyleyebilirim. İşte hemen aklıma gelen noktalar şunlardır:

1) Bu nesnenin dışında yapılan girişler ile tutarlılık sağlama yararına yapılmalıdır.

2) Bazı durumlarda, bu accessor yöntemler sadece alana erişim daha yapıyor olabilir; Onlar bazı ek işlemler (nadir olsa da) yapıyor olabilir. Bu durumda, alanı doğrudan erişerek bu işlem, bu girişler sırasında yapılması gereken her zaman, ek işleme ve program ters gidebileceğini kaçırmış olur