Referans ve PHP dizeleri üzerinden kötü bir fikir yöntemleri çağırıyor?

3 Cevap php

Ben her zaman dizeleri üzerinden onları başvurarak yöntemlerini çağırarak hakkında endişe ettik.

Temelde benim şimdiki senaryoda, ben veri modeli nesneleri (örn. SomeDataMapper :: GetAll (1234)) bir dizi oluşturmak ve geri dönmek için statik veri mapper yöntemleri kullanın. Modeller Active Record tasarım deseni izleyin. Bazı durumlarda, orada döndürülen kayıtların yüzlerce olabilir, ve ben tek seferde belleğe her şeyi koymak istemiyorum. Yani, aşağıdaki gibi, kayıtlar arasında sayfasına bir yineleyici kullanıyorum

$Iterator = new DataMapperIterator('SomeDataMapper', 'getAll', array(1234));

while ($Iterator->hasNext()) {
  $data = $Iterator->next();
}

Bunu yapmanın iyi bir yolu var mı? Bu mapper sınıfın adını ve yöntemi dizeleri olarak geçmek kötü bir fikir mi? Ben bu fikri diğer dillere taşınabilir olmadığını merak. Bu Ruby ve Python gibi diller için genellikle doğrudur? Eğer öyleyse, herkes için iyi bir alternatif tavsiye edebilir?

Bilginize, gelecekte insanların refernce için, ben böyle yöntemini çağırın:

$method = new ReflectionMethod($className, $methodName);
$returnValue = $method->invokeArgs(null, $parameters);

3 Cevap

Bir nesne örneği oluşturmak için dizeleri kullanma - Bu aslında fabrika deseni bir sürümüdür.

Ancak, veri belleği kontrol etmek için bir yineleyici kullanarak tasarım fikri soru - bu gerçekten bir yineleyici amacı değil. Biz sadece isim karışıklığı var, ama sürece ben muhtemelen böyle bir şey görmeyi tercih ederim.

$pager = new DataMapperPager( 'SomeDataMapper', 'someMethod', array(1234) );
$pager->setPageNum( 1 );
$pager->setPageSize( 10 );
$rows = $pager->getResults();

foreach ( $rows as $row )
{
   // whatever
}

Tabii ki, DataMapperPager :: getResults () Eğer istediğimiz bir yineleyici ya da ne olursa olsun geri dönebilirler.

Bunu yapmanın kabul edilebilir bir yoldur. Python ve Ruby de onu destekleyecek ve böylece taşınabilir olmalıdır. PHP, Ruby ancak bunun için biraz daha var gibi Python gibi kolayca yapabilirsiniz. Python en az, (yani sınıfı başvurmak için çalışıyoruz nereye kadar aynı dosyada daha düşük bulunmuştur.), Başvuran konum belirli sınıfı henüz ithal edilmiş ne de dosyada henüz görmemiştir zaman için yararlıdır

Ruby bir dizeden bir sınıf nesnesi Başlarken: http://infovore.org/archives/2006/08/02/getting-a-class-object-in-ruby-from-a-string-containing-that-classes-name/

PHP gerçekten fonksiyonları geçen başka bir şekilde desteklemiyor. PHP tüm dinamik yöntem çağırma fonksiyonları bir "geri" dediğimiz almak - Bu konuda belgeler için http://us.php.net/manual/en/language.pseudo-types.php#language.types.callback bkz. Göreceğiniz gibi, onlar sadece dize veya farklı kullanım alışkanlıkları dizeleri diziler konum, bu yüzden uzak değiliz.

Bu geçici bir çözüm tasarım desenleri, ancak vardır. Örneğin, sizin mapper sınıflarının tüm uygulamak gerekir DataMapper arayüz tanımlamak olabilir. Sonra, bunun yerine dize gibi sınıf ve yöntemi geçen, sizin yineleyici mapper örneği geçebileceği ve arayüz gerektirdiğinden dolayı doğrudan arabirim yöntemleri diyebiliriz.

pseudocode:

interface DataMapper
{
   public function mapData($data);
}

class DataMapperIterator ...
{
  public function __construct(DataMapper $mapper, ...)
  {
   ...
  }
  ...
  public function next()
  {
    ... now we can call the method explicitly because of interface ...
    $this->mapper->mapData($data);
  }
}

class DataMapperImplemenation implements DataMapper
{
  ...
  public function mapData($data)
  {
    ...
  }
 ...
}

Her zaman bir sembol arama olacak - - dizeleri geçti ile ismiyle yöntemlerini çağırarak sadece performans ceza optimize edilmiş olarak üretilen baytkodu olamayacağını muhtemelen var, korkunç değil ama ben bu kadar fark olacağını sanmıyorum.