Bu yanlış belirleyiciler ve alıcılar kullanarak değil gerçekten var mı?

7 Cevap php

Ben tür yeni PHP değilim. JAVA gibi programlama dilleri, diğer türleri nedense ben her değişken için belirleyiciler ve alıcılar kullanarak bir sorunum yok, ama çok esnek olduğu için muhtemelen PHP programlama olduğumda bu tür zaman kaybı gibi geliyor. Sadece sınıf kamu çoğu zaman ve bu gibi onları manipüle gibi niteliklerini ayarlamak için basit hissediyor. Şey gibi bunu yapmak zaman yanlış bir şey yapıyor ve OO ilkelerine karşı gidiyorum gibi hissediyorum olmasıdır.

Bu yanlış belirleyiciler ve alıcılar kullanarak değil gerçekten var mı? Neden veya neden değil? Siz bunu çoğu zaman ne yaparsınız?

7 Cevap

Bu örneğin, bir alt sınıfta bilgisayarlı özelliği yapmak için - - Eğer API müşterilerine kırarım özellik erişimcisi'olması kullanarak ile değil ana sorun öğrenmek eğer hiç daha sonra bir özellik için bir alanı değiştirmek gerekiyor olmasıdır. Yayımlanmış bir kütüphane için, bu kabul edilemez; içsel bir, iş sadece oldukça çok şeyler sabitleme.

Özel kod ya da küçük uygulamalar için, sadece kanat bunun için uygun olabilir. Bir IDE (veya metin editörü) Eğer accessor klişe üretmek izin ve kod katlama kullanarak bunu gizler. Bu belki mekanik oldukça kolay alıcı ve ayarlayıcıları kullanarak yapar.

Ruby metaprogramming aracılığıyla yapar, C # otomatik uygulanan özelliklere sahiptir - bazı programlama dilleri varsayılan alan + alıcı + setter sentezlemeye özelliklere sahip olduğunu unutmayın. Ve Python yerine onunla ön rahatsız zorunda ihtiyacı sınıfta niteliği encapsulate icar, öznitelik erişim geçersiz sağlayarak tamamen sorunu sidesteps. (Bu iyi gibi yaklaşımdır.)

Alıcılar veya belirleyiciler noktası hala alanını değiştirmek ya da almak istediğiniz yerine everyplace tek bir yerde alan sizin değişikliklere mantığı ekleyebilirsiniz olmasıdır. Ayrıca alanı ile ne sınıf düzeyinde kazanç kontrolü.

Biz burada değil, PHP ile ilgili kesinlikle C # hakkında konuşuyor, Java, vb (derleyici bunları optimize nerede), ben alıcılar ve belirleyiciler sadece vekil için özel bir alanın değerini ihtiyaç kaynakların israfı olarak görüyorum ve başka bir şey yapmak.

Benim Kurulum, ben, iki berbat sınıfları ve beş kamu alanları ile başka bir (neredeyse exactly java tuhaftır kodu gibi görünüyordu) alanını vekalet beş alıcı / ayarlayıcı çiftleri tarafından saklanmış beş özel alanlar ile bir yapılan ve bir örneğini oluşturduktan sonra sonunda sözde memory_get_usage (). Alıcı / ayarlayıcıları ile komut 59708 bellek bayt ve kamu alanları ile komut dosyası 49244 bayt kullanmıştır.

Böyle bir web sitesi çerçeve olarak herhangi bir önemli boyutu, bir sınıf kitaplığı bağlamında, bu yararsız alıcılar ve belirleyiciler bellek için çok büyük bir kara deliğe kadar ekleyebilirsiniz. Ben refactored zaman (i seçim olsaydı onların tercihidir, benim değil. Ben bunun için kullanmak olmaz değil ama PHP bize herhangi aşılmaz kısıtlamalar empoze değil, söyledikten) PHP benim işveren için bir çerçeve gelişmekte olan ve yerine alıcılar / belirleyiciler kamu alanlarını kullanmak için sınıf kitaplığı, bütün yerin en az istek başına% 25 daha az bellek kullanarak sona erdi.

__ (), __ Set olsun () ve __ call () 'sihirli' yöntemleri gerçekten arayüz değişiklikleri ele için parlayacak. Eğer bir alıcı / ayarlayıcı (veya bir alana bir alıcı / ayarlayıcı) bir alan göç gerektiğinde herhangi bir bağımlı kod süreci şeffaf yapabilirsiniz. Bir yorumlanmış bir dil ile, hatta Eclipse PDT veya NetBeans tarafından sağlanan kod duyarlılık için oldukça iyi desteği ile bir alan veya yöntemin tüm kullanımlarını bulmak biraz zor, yani sihirli yöntemler sağlanması için yararlı olduğu yeni, eski arabirimi hala delegeler işlevsellik.

Yerine alıcılar / belirleyiciler alanları kullanarak geliştirilen bir nesne var ve 'tarla' uygunsuz ya da artık doğru kullanımını tarif, ya da çünkü biz, 'fieldWithBetterName' için 'tarla' olarak adlandırılan bir alanını yeniden adlandırmak istiyorsanız söyleyin sadece düz yanlış. Ve biz bir alıcı kullanarak başlangıçta bilinmemektedir çünkü tembel yük veritabanından değeri 'field2' adlı bir alanını değiştirmek istedim ki ...

class Test extends Object {
    public $field;
    public $field2;
}

olur

class Test extends Object {
    public $fieldWithBetterName = "LA DI DA";
    private $_field2;

    public function getField2() {
        if ($this->_field2 == null) {
            $this->_field2 = CrapDbLayer::getSomething($this->fieldWithBetterName);
        }
        return $this->_field2;
    }

    public function __get($name) {
        if ($name == 'field')) {
            Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
            return $this->fieldWithBetterName;
        }
        elseif ($name == 'field2') {
            Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
            return $this->getField2();
        }
        else return parent::__get($name);
    }
}
$t = new Test;
echo $t->field;
echo $t->field2;

(Bir yan not olarak, bu biraz ben __ get () ve __ set var hemen hemen her şeyi (bildirilmemiş fields erişilen bir istisna atar) beyanı için kullanılacak sadece bir temel sınıf 'Object uzanır')

Sen __ () çağrısı ile geriye gidebilirsiniz. Bu örnek oldukça kırılgan, ama temizlemek zor değil:

class Test extends Object {
    public $field2;

    public function __call($name, $args) {
        if (strpos($name, 'get')===0) {
            $field = lcfirst($name); // cheating, i know. php 5.3 or greater. not hard to do without it though.
            return $this->$field;
        }
        parent::__call($name, $args);
    }
}

Alıcı ve PHP setter yöntemleri ayarlayıcı bir şey yapmak için varsa iyi, ya da alıcı tembel yük bir şey, ya da bir şey oluşturulur, ya da her ne olmuştur sağlamak için vardır, ama onlar gereksiz ve savurgan eğer onlar vekaleten başka bir şey yapmazsak Özellikle arayüz değişiklikleri yönetmek için yukarıda olanlar gibi birkaç teknikleri ile alan,.

Herhalde bu bir çok upvotes almak için gitmiyorum, ama şahsen alıcılar ve hatta daha çok belirleyiciler benim için bir kod kokusu gibi hissediyorum. Tasarımlar davranış, veri odaklı değil, tahrik edilmelidir. Tabii ki, bu sadece bir fikir olduğunu. Eğer başka bir nesnenin belirli bir veri alanına bağlıdır bir nesne varsa bu çok sıkı bağlama olduğunu. Bunun yerine çok daha az kırılgan verilerinin daha o nesnenin davranışı bağlı olmalıdır.

Ama evet, alıcılar ve ayarlayıcıları gibi özelliği doğrudan bu sebeple bir alanda bir bağımlılık bir adım vardır. Daha az kırılgan ve nesneler arasındaki kaplin gevşetir.

Eğer sihirli işlevleri __ set / __get kullanmayı düşündünüz mü? Onları kullanarak kolayca sadece 2 fonksiyonları tüm alıcı / ayarlayıcı fonksiyonu birleştirebilirsiniz!

/ Aslında get / set işlevi sınıfını kullanmadan set almak taklit etmek için bir yol var, böylece kodunuzu derli toplu kalır:

$person->name = 'bob';
echo $person->name;

this class Ben kodlanmış bir göz atın.

Bu sınıf kullanırken Genellikle, tüm korumalı özellikleri (ya da özel) beyan ederim. Eğer bir mülk üzerinde bir davranış eklemek isterdim durumunda, strtolower demek () + ucfirst () "name" özelliği, yapmanız gereken istediğiniz tüm sınıfta bir korumalı set_name () fonksiyonu beyan ve davranış otomatik olarak aldı almalısınız. Aynı get_Name () ile gerçekleştirilebilir.

// Somewhere in your class (that extends my class).
protected function set_name($value) { $this->name = ucfirst(strtolower($value)); }
//

// Now it would store ucfirst(strtolower('bob')) automatically.
$person->name = 'bob';

P.S. Another cool thing is you can make up non-existing fields such as

echo $person->full_name;

(sürece get_full_name () fonksiyonu var gibi) gibi alanları kalmadan.

Eğer zaman komut dosyası çok bu değişken erişmek ve yoru sınıf güncellemek eğer bu Yüklü eğer sınıf geliştirmek zaman, bu değişken kullanan tüm dosyaları güncellemek zorunda çünkü genellikle belirleyiciler ve oltalarını kullanmalıdır.

Bunu neden İkincisi ana nedeni sınıf yapısı değişebilir, çünkü doğrudan değişken erişmek gerektiğini ve bu veri differently.While bu veri nasıl oluşturulur hakkında bakım gerekir sınıf veri alıyorsanız providen edilebilir. Sınıf umurumda var Bu veri İşleme yüzden sadece ne alırsınız önemsemeliyiz.