Neden dizi yerine nesne döndürülsün?


84

WordPress'te çok iş yapıyorum ve çok daha fazla işlevin dizilerden çok nesne döndürdüğünü fark ettim. Özellikle bir dizi istemediğiniz sürece veritabanı sonuçları nesne olarak döndürülür. Hatalar nesne olarak döndürülür. WordPress'in dışında çoğu API size bir dizi yerine bir nesne verir.

Sorum şu, neden diziler yerine nesneler kullanıyorlar? Çoğunlukla bu çok fazla önemli değil, ancak bazı durumlarda nesneleri yalnızca işlemekle kalmayıp aynı zamanda kafamı dolaştırmak için daha zor buluyorum. Bir nesneyi kullanmanın performans nedeni var mı?

Ben kendi kendini yetiştiren bir PHP programcısıyım. Bir liberal sanat diplomam var. Bilgisayar biliminin temel bir yönünü kaçırıyorsam beni affet. ;)


5
Nesnelerin dezavantajları konusunda merak ediyorum , kullanamama count()veya array_*()üzerlerinde işlev görememe (en azından anahtar => değer verisinin depolanması / döndürülmesi ile ilgili olarak). Kimse bahsetmiyor gibi mi yoksa bir şey mi özlüyorum?
Wesley Murch

8
Sayılabilir veya Yineleyici arabirimleri uygulanarak nesneler sayılabilir ve yinelenebilir hale getirilebilir. Check out php.net/manual/en/book.spl.php de.
simshaun

SPL kuruluysa ve nesne sınıfınız için sayılabilir arabirimi uygularsanız, count()bir nesneyi çağırabilirsiniz .
Güneydoğu

2
Çoğu durumda, bir dizi bir nesne koleksiyonu veya dizilerle kolayca taklit edilemeyen bir tür koleksiyon döndürmediğiniz için bir anlam ifade etmez. Sadece bir dizi başka değeriniz olduğunda ve hiçbir ekstra anlambiliminiz olmadığında, o zaman Tanrı aşkına bir dizi döndürün - ancak bunun nadiren böyle olduğunu göreceksiniz.

8
@delnan ve diğerleri: Lütfen @Dennis'in normal (tamsayı-indeks) dizilerden değil, ilişkili dizilerden (sözlükler, aka. Haritalar) bahsettiğini unutmayın . Bunlar PHP'nin temel bir özelliğidir ve dinamik sınıflarla ( stdClass) aşağı yukarı aynı amaca hizmet eder . Bu sorunun "Öncelikle
OOP'de

Yanıtlar:


63

Genel olarak nesneleri tercih etmemin nedenleri şunlar:

  • Nesneler yalnızca verileri değil aynı zamanda işlevselliği de içerir.
  • Nesnelerin (çoğu durumda) önceden tanımlanmış bir yapısı vardır. Bu, API tasarımı için çok kullanışlıdır. Ayrıca, özellikleri genel, korumalı veya özel olarak ayarlayabilirsiniz.
  • nesneler, nesne yönelimli geliştirmeye daha iyi uyar.
  • Çoğu IDE'nin otomatik tamamlamasında yalnızca nesneler için çalışır.

İşte okunacak bir şey:


3
ilk bağlantı iyi görünmüyor? Demek istediğim işe yarıyor, ancak farklı bir aritleye götürüyor
Geo

24

Bu muhtemelen birkaç yıl boyunca büyük bir yazılım projesi üzerinde çalışana kadar derinlemesine anlayacağınız bir şey değildir. Pek çok yeni bilgisayar bilimi bölümü size tüm doğru sözcüklerle (kapsülleme, verilerle işlevsellik ve sürdürülebilirlik) bir cevap verecektir, ancak çok azı tüm bunlara sahip olmanın neden iyi olduğunu gerçekten anlayacaktır.

Birkaç örnek üzerinden geçelim.

  • Diziler döndürülmüşse, ya tüm değerlerin önceden hesaplanması gerekir ya da daha karmaşık değerleri oluşturabileceğiniz çok sayıda küçük değerin döndürülmesi gerekir.

WordPress gönderilerinin bir listesini döndüren bir API yöntemi düşünün. Bu gönderilerin hepsinin yazarları, yazarların isimleri, e-posta adresleri, hatta biyografileriyle profilleri bile vardır.

Bir dizideki tüm gönderileri geri gönderiyorsanız, kendinizi bir dizi gönderi kimliği döndürmekle sınırlamanız gerekir:

[233, 41, 204, 111]

veya şuna benzer devasa bir dizi döndürmek:

[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': 'bill@bill.com', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]

Bir kimlik listesi döndürmenin ilk durumu sizin için çok yararlı değildir çünkü o zaman bu gönderi hakkında biraz bilgi almak için her kimlik için bir API çağrısı yapmanız gerekir.

İkinci durum, ihtiyaç duyduğunuzdan çok daha fazla bilgi çekecek ve çok daha fazla iş yapacak (özellikle bu alanlardan herhangi birinin oluşturulması çok karmaşıksa).

Öte yandan bir nesne, ihtiyacınız olan tüm bilgilere erişiminizi sağlayabilir, ancak bu bilgiyi henüz gerçekten çekmemiş olabilir. Alanların değerlerinin belirlenmesi, bir nesne kullanılırken tembel olarak (yani, değere ihtiyaç duyulduğunda ve önceden değil) yapılabilir.

  • Diziler, amaçlanandan daha fazla veri ve yetenek ortaya çıkarır

Döndürülen büyük dizi örneğine geri dönün. Artık birisi muhtemelen post dizisi içindeki her bir değeri yineleyen ve yazdıran bir uygulama oluşturabilir. API, bu post dizisine yalnızca bir ekstra öğe eklemek için güncellenirse, uygulama kodu, muhtemelen olmaması gereken bazı yeni alanları yazdıracağından kırılacaktır. API tarafından döndürülen post dizisindeki öğelerin sırası değişirse, bu durum uygulama kodunu da bozacaktır. Yani bir dizi döndürmek, bir nesnenin yaratmayacağı her tür olası bağımlılığı yaratır.

  • İşlevsellik

Bir nesne, size yararlı işlevsellik sağlamasına izin verecek bilgileri içinde tutabilir. Örneğin bir gönderi nesnesi, önceki veya sonraki gönderileri döndürecek kadar akıllı olabilir. Bir dizi bunu sizin için asla yapamaz.

  • Esneklik

Yukarıda bahsedilen nesnelerin tüm faydaları daha esnek bir sistem oluşturmaya yardımcı olur.


10

Sorum şu, neden diziler yerine nesneler kullanıyorlar?

Muhtemelen iki sebep:

  • WordPress oldukça eski
  • diziler daha hızlıdır ve çoğu durumda daha az bellek kullanır
  • serileştirmek daha kolay

Bir nesneyi kullanmanın performans nedeni var mı?

Hayır. Ancak başka birçok iyi neden, örneğin:

  • mantığı nesnelerde (yöntemler, kapatmalar vb.) saklayabilirsiniz.
  • bir arayüz kullanarak nesne yapısını zorlayabilirsiniz
  • IDE'de daha iyi otomatik tamamlama
  • tanımsız dizi anahtarları için uyarı almazsınız
  • sonunda herhangi bir nesneyi diziye kolayca dönüştürebilirsiniz.

OOP ! = AOP :)

(Örneğin Ruby'de her şey bir nesnedir. Önceden PHP prosedür / betik diliydi.)


7

WordPress (ve oldukça fazla sayıda diğer PHP uygulaması), teknik nedenlerden ziyade kavramsal nedenlerle diziler yerine nesneleri kullanır.

Bir nesne (stdClass'ın sadece bir örneği olsa bile) bir şeyin temsilidir. WordPress'te bu bir gönderi, yorum veya kullanıcı olabilir. Öte yandan bir dizi, bir şeyler koleksiyonudur. (Örneğin, bir gönderi listesi.)

Tarihsel olarak, PHP çok iyi nesne desteğine sahip değildi, bu nedenle diziler erken dönemde oldukça güçlü hale geldi. (Örneğin, sadece sıfır dizinli olmaktan ziyade keyfi anahtarlara sahip olma yeteneği.) PHP 5'te mevcut nesne desteği ile, geliştiriciler artık anahtar-değer depoları olarak dizileri veya nesneleri kullanmak arasında bir seçim yapabilirler. Şahsen, nesnelerin ve dizilerin sağladığı 'varlıklar' ve 'koleksiyonlar' arasındaki sözdizimsel farkı sevdiğim için WordPress yaklaşımını tercih ediyorum.


5

Sorum şu, neden (Wordpress) diziler yerine nesneler kullanıyorlar?

Bu gerçekten iyi bir soru ve cevaplaması kolay değil. Yalnızca Wordpress'te stdClassnesneleri kullanmanın yaygın olduğunu varsayabilirim çünkü varsayılan olarak kayıtları stdClassnesne olarak döndüren bir veritabanı sınıfı kullanıyorlar . Alıştılar (8 yıl ve üzeri) ve hepsi bu. Basit gerçeğin arkasında çok fazla düşünce olduğunu sanmıyorum.

ilişkilendirilebilir diziler için sözdizimsel şeker - Zeev Suraski , PHP 3'ten beri standart nesne hakkında

  • stdClassnesneler dizilerden gerçekten daha iyi değildir. Hemen hemen aynılar. Bu, dilin ve stdClassnesnelerin bazı tarihsel nedenlerinden dolayı gerçekten sınırlıdır ve aslında çok temel anlamda yalnızca bir tür değer nesneleridir .
  • stdClassnesneler, bir dizinin girdi başına yaptığı gibi üyeleri için değerleri depolar. Ve bu kadar.
  • Yalnızca PHP meraklıları stdClassözel üyelerle nesne oluşturabilir . Bunu yapmanın - varsa - pek bir faydası yoktur.
  • stdClassnesnelerin herhangi bir yöntemi / işlevi yoktur. Yani bunun Wordpress'te kullanımı yok.
  • Bununla karşılaştırıldığında array, bir liste veya yarı yapılandırılmış verilerle uğraşmak için çok daha az yararlı işlevler vardır.

Ancak, dizilere alışkınsanız, sadece çevirin:

$array = (array) $object;

Ve önceden bir nesne olan verilere bir dizi olarak erişebilirsiniz. Ya da tam tersi seversin:

$object = (object) $array;

Bu, sayılar gibi yalnızca geçersiz üye adlarını düşürür. Bu yüzden biraz dikkatli ol. Ama sanırım büyük resmi anladınız: Diziler ve nesnelerle ilgili olduğu sürece çok fazla fark yok stdClass.

İlişkili:


4
  1. Kod bu şekilde daha havalı görünüyor
  2. Referans ile geçen nesneler
  3. Nesneler dizilerden daha güçlü yazılmıştır, dolayısıyla hatalara eğilimlidir (veya mevcut olmayan üyeyi kullanmaya çalıştığınızda size anlamlı bir hata mesajı verir)
  4. Günümüzde tüm IDE'lerin otomatik tamamlama özelliği vardır, bu nedenle tanımlanmış nesnelerle çalışırken IDE sizin için çok şey yapar ve işleri hızlandırır
  5. Easilly, mantığı ve verileri aynı kutuda kapsülleyin ; burada dizilerle, verileri dizide depolayın ve ardından işlemek için farklı bir işlev kümesi kullanın.
  6. Kalıtım, Neredeyse ancak benzer olmayan işlevselliğe sahip benzer bir diziye sahip olsaydınız, nesnelerle yapacaksanız daha fazla kodu çoğaltmanız gerekirdi.

Muhtemelen düşündüğüm başka bir sebep daha


"# Nesneler referans olarak geçer": Bu yanlış. Nesneler bir PHP değişken başvurusu olarak geçmez. Asla yapmadılar.
hakre

@hakre - php4'te misin? veya lütfen ne demek istediğinizi açıklayın.
Itay Moav -Malimovka

Bu wordpress yakın zamana kadar PHP 4 değildi, ancak PHP 4 veya PHP 5'te nesneler referans olarak geçmiyor: "PHP5 OOP'nin sık sık bahsedilen anahtar noktalarından biri" nesnelerin varsayılan olarak gönderimlerle aktarılmasıdır " . Bu tam olarak doğru değil. Bu bölüm, bazı örnekler kullanarak bu genel düşünceyi düzeltir. " Nesneler ve referanslar
hakre

@hakre - Ne demek istediğinizi anlıyorum, ancak tüm amaçlar için, dil yalnızca referansları iletiyormuşsunuz gibi davranıyor.
Itay Moav -Malimovka

4

Nesneler, dizilerin olabileceğinden çok daha güçlüdür. Bir sınıfın örneği olarak her nesnenin ekli işlevleri olabilir. İşlenmesi gereken verileriniz varsa, işlemeyi yapan bir işleve ihtiyacınız vardır. Bir dizi ile, o dizide bu işlevi çağırmanız ve bu nedenle mantığı kendiniz verilerle ilişkilendirmeniz gerekir. Bir nesneyle bu ilişkilendirme zaten yapılmıştır ve artık onu önemsemenize gerek kalmaz.

Ayrıca OO bilgi gizleme ilkesini de göz önünde bulundurmalısınız. Veritabanından geri gelen veya veritabanına giden her şey doğrudan erişilebilir olmamalıdır.


Wordpress, sınıfın nesnelerini döndürür StdClass. Bu nesnelerin vurguladıklarınızla ortak hiçbir yanı yoktur. Örneğin işlevleri yoktur ve kalıtımları yoktur. Ve Wordpress durumunda, tüm sınıf değişkenleri herkese açıktır.
hakre

Evet bu doğru. Sanırım bu durumda, diğerlerinin de belirttiği gibi, sadece ne tercih ettiğinize bağlı. WordPress ile ilgilenmiyorum ama muhtemelen tüm veritabanı çağrılarını kapsıyorlar ve bu nedenle geri dönüş için herhangi bir özel sınıf sağlayamıyorlar. Ama cevabım genel olarak oldu ve bence yapımcılar tarafından benzer değerlendirmeler yapıldı ... Ya da sadece yazı tura attılar.
Güneydoğu

Ca.'dan stdClassberi varsayılan olarak nesneleri döndüren bir veritabanı yardımcı sınıfı kullanırlar . 8 yıl. Bir dizi almak istiyorsanız, onu elde etmek için isteğe bağlı bir parametre ayarlamanız gerekir.
hakre

3

Nesneleri iade etmenin birkaç nedeni vardır:

  1. Yazmaktan $myObject->propertydaha az "ek" karakter gerektirir$myArray['element']

  2. Nesne veri ve işlevsellik döndürebilir; diziler yalnızca veri içerebilir.

  3. Zinciri etkinleştirin: $myobject->getData()->parseData()->toXML();

  4. Daha kolay kodlama: IDE otomatik tamamlama, nesne için yöntem ve özellik ipuçları sağlayabilir.

Performans açısından diziler genellikle nesnelerden daha hızlıdır. Performansa ek olarak, dizileri kullanmanın birkaç nedeni vardır:

  1. Dizi _ * () işlev ailesi tarafından sağlanan işlevsellik, bazı durumlarda gerekli kodlama miktarını azaltabilir.

  2. Count () ve foreach () gibi işlemler diziler üzerinde gerçekleştirilebilir. Nesneler bunu sunmaz ( Yineleyici veya Sayılabilir uygulamadıkları sürece ).


2

Genellikle performans nedenlerinden dolayı olmayacak. Tipik olarak, nesneler dizilerden daha pahalıdır.

Bir çok API için, muhtemelen bir depolama mekanizması olmanın yanı sıra başka işlevler sağlayan nesnelerle ilgisi vardır. Aksi takdirde, bu bir tercih meselesidir ve bir diziye karşı bir nesneyi döndürmenin gerçekten bir faydası yoktur.


PHP5'te, diziler ve nesneler arasındaki performans farkı marjinaldir.
Justin ᚅᚔᚈᚄᚒᚔ

2

Bir dizi, yalnızca bir değer dizinidir. Oysa bir nesne sizin için sonucu üretebilecek yöntemleri içerir. Elbette, bazen bir nesnenin değerlerine doğrudan erişebilirsiniz, ancak "bunu yapmanın doğru yolu" bir nesnenin yöntemlerine (o nesnenin değerleri üzerinde çalışan bir işlev) erişmektir.

$obj = new MyObject;
$obj->getName();   // this calls a method (function), so it can decide what to return based on conditions or other criteria

$array['name'];   // this is just the string "name". there is no logic to it. 

Bazen bir nesne değişkenine doğrudan erişiyorsunuz, bu genellikle hoş karşılanmıyor, ancak yine de oldukça sık oluyor.

$obj->name;   // accessing the string "name" ... not really different from an array in this case.

Ancak, MyObject sınıfının 'ad' adında bir değişkeni olmadığını, bunun yerine bir ad ve soyad değişkenine sahip olduğunu düşünün.

$obj->getName();  // this would return first_name and last_name joined.
$obj->name;  // would fail...
$obj->first_name; 
$obj->last_name; // would be accessing the variables of that object directly.

Bu çok basit bir örnek, ancak bunun nereye gittiğini görebilirsiniz. Bir sınıf, bağımsız bir mantıksal varlık içinde bu değişkenler üzerinde çalışabilen bir değişkenler koleksiyonu ve işlevler sağlar. Bu varlığın bir örneğine nesne denir ve bir dizinin sahip olmadığı mantıksal ve dinamik sonuçları sunar.


1

Çoğu zaman nesneler dizilerden daha hızlı olmasa da hızlıdır, PHP'de gözle görülür bir fark yoktur. ana sebep, nesnelerin dizilerden daha güçlü olmasıdır. Nesne odaklı programlama, nesneler oluşturmanıza ve yalnızca verileri değil, aynı zamanda bunların içindeki işlevselliği de depolamanıza olanak tanır; örneğin PHP'de MySQLi Sınıfı, prosedürel yaklaşım yerine bir dizi dahili işlev kullanarak işleyebileceğiniz bir veritabanı nesnesine sahip olmanıza olanak tanır.

Yani asıl neden, OOP'nin mükemmel bir paradigma olmasıdır. OOP kullanmanın neden iyi bir fikir olduğu hakkında bir makale yazdım ve konsepti açıklayarak buraya bir göz atabilirsiniz: http://tomsbigbox.com/an-introduction-to-oop/

Küçük bir artı olarak, bir nesneden veri almak için daha az yazarsınız - $ test-> data, $ test ['data'] 'dan daha iyidir.


1

Kelime basımına aşina değilim. Buradaki birçok cevap, nesnelerin gücünün işlevsel kod içerme yeteneği olduğunu göstermektedir. Bir işlev / API çağrısından bir nesneyi döndürürken, yardımcı işlevler içermemelidir. Sadece özellikler.

Nesneleri döndürmenin gücü, API'nin arkasında yatan her şeyin kodunuzu kırmadan değiştirebilmesidir.

Örnek: Anahtar / değer çiftlerine sahip bir veri dizisi elde edersiniz, anahtar DB sütununu temsil eder. DB sütunu yeniden adlandırılırsa, kodunuz bozulur.


1

Bir sonraki testi php 5.3.10'da çalıştırıyorum (Windows):

for ($i = 0; $i < 1000000; $i++) {
    $x = array();
    $x['a'] = 'a';
    $x['b'] = 'b';
}

ve

for ($i = 0; $i < 1000000; $i++) {
    $x = new stdClass;
    $x->a = 'a';
    $x->b = 'b';
}

Http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961 adresinden kopyalandı

İşlevi 10 eşzamanlı kullanıcı ve 10 kez çağırmak (ortalama elde etmek için) sonra

  • Diziler:% 100
  • Nesne:% 214 -% 216 (2 kat daha yavaş).

AKA, Nesne hala ağrılı yavaş. OOP her şeyi düzenli tutar, ancak dikkatli kullanılmalıdır.

Hangi Wordpress uygulanıyor? Her iki çözüm de nesneleri, dizileri ve nesne ve dizileri kullanıyor , Sınıf wpdb daha sonrasını kullanıyor (ve bu Wordpress'in kalbidir).


Karşılaştırmayı PHP 5.4'te görmelisiniz. Nesnelerin performansı olağanüstüdür ve bazen Dizilerden bile daha hızlıdır.
Sanket Sahu

0

OOP'nin kutulama ve kutudan çıkarma ilkesini izler. Java ve C # gibi diller bunu yerel olarak desteklerken, PHP desteklemez. Bununla birlikte, PHP'de bir dereceye kadar başarılabilir, ancak dilin kendisi onu destekleyecek yapılara sahip olmadığı için anlamlı değildir. PHP'de kutu türlerine sahip olmak zincirlemeye yardımcı olabilir, her şeyi nesneye yönelik tutabilir ve yöntem imzalarında tip ipucu vermeye izin verir. Olumsuz tarafı, genel gider ve artık "örnek" yapısını kullanarak yapabileceğiniz fazladan kontrolünüz olduğu gerçeğidir. Bir tür sistemine sahip olmak, PDT gibi intellisense veya kod yardımına sahip geliştirme araçlarını kullanırken de bir artıdır. Yöntem için google / bing / yahoo'ya ihtiyaç duymak yerine, nesnede bulunur ve bir açılır menü sağlamak için aracı kullanabilirsiniz.


0

Nesneler hakkında yapılan noktalar, genellikle veri ve davranış oldukları için geçerli olmalarına rağmen, Martin Fowler'in "Kurumsal Uygulama Mimarisi Kalıpları" nda , transfer yaptığınız bu tür bir cenario için geçerli olan en az bir model vardır. bir sistemden (API'nin arkasındaki uygulama) ve diğerinden (uygulamanız) veriler.

Onun Veri Aktarım Nesnesi - yöntem çağrıların sayısını azaltmak amacıyla süreçler arasında veri taşıyan bir nesne.

Öyleyse soru API'lerin bir DTO mu yoksa bir dizi mi döndürmesi gerektiğiyse, eğer performans maliyeti ihmal edilebilirse, o zaman daha sürdürülebilir olan seçeneği seçmeniz gerektiğini söyleyebilirim ki bunun DTO seçeneği olduğunu iddia ediyorum ... ama tabii ki siz de Sisteminizi geliştiren ekibin becerilerini ve kültürünü ve seçeneklerin her biri için dil veya IDE desteğini göz önünde bulundurmalısınız.

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.