PHP OOP: argüman türü başına benzersiz bir yöntem?

3 Cevap php

Biraz homebrew ORM (akademik faiz) yazıyorum. Ben bir eğitim tatbikatı olarak TDD kavramına uygun çalışıyorum, ve ben sınıf geliştirmek gibi bu egzersizin bir parçası olarak ben API belgelerine yazıyorum.

Noktasında Case - Ben klasik "getCollection" tipi mapper sınıfı üzerinde çalışıyorum. Ben belirli bir kullanıcı için (blog mesajları diyelim) varlık X koleksiyonları almak, hem de sayısal değerler keyfi bir dizi dayalı koleksiyonlar edebilmek istiyorum. So - Eğer bunlardan herhangi biri gibi bir yöntem olabilir

$User = $UserMapper->load(1);
$ArticleCollection = $ArticleMapper->getCollection(range(10,20));
$ArticleCollection = $ArticleMapper->getCollection($User);
$ArticleCollection = $ArticleMapper->getCollection($User->getId());

Yani, getCollection yöntemi için belgeleri yazılı olarak - Ben bilgilendirme kısmı içinde @ param değişkeni bildirmek istiyorum. Her argüman türü için benzersiz bir yöntem olması daha iyidir, yoksa doğru iç yöntemi / sınıf delege argüman türüne dayalı bir yöntem olması kabul edilebilir mi?

3 Cevap

Bu doğru iç yöntemine temsil bir yöntem olması kabul edilebilir. Böyle belgelemek olabilir:

@param Array|User|Integer $argName optional explanation

ama sonra tekrar, bir yöntem herbiri engelleyen kimse yok

public function getCollectionByRange(array $range)
public function getCollectionByUser(User $user)
public function getCollectionByUserId($id)

Buna ek olarak, magic __call yöntemini kullanabilirsiniz to pretend the above methods exist and then capture method calls to them and delegate to your internal methods (ZF does that f.i. for finding dependant database rows). Sen Sınıf bilgilendirme kısmı yılında @method açıklama ile bu yöntemleri belge olacaktır. Ama sihirli yöntemler olan ve / veya doğrudan uygun yöntemleri çağırmadan üzerinde her zaman daha yavaş olduğunu akılda tutmak.

Eğer uygulama ve usecase için en mantıklı ne düşündüğünü kullanın.

Sen method overloading zamanında geçirilen parametre türünü denetleyerek (PHP ADA, Java, C # veya C + +, örneğin gibi diğer dillerde bilinen bu kavram desteklemiyor) gibi bir şey elde edebiliriz:

[...]
/**
 * @param  User|array|integer $user
 * @return array
 */
public function getCollection($user) {
    // perhaps a switch-case would be better here
    if ($user instanceof User) {
        // do what has to be done if you passed in a User object
    } else if (is_int($user) {
        // do what has to be done if you passed in a user id
    } else if (is_array($user)) {
        // do what has to be done if you passed in an array of user ids
    }
}
[...]

Bu sounds Eğer fonksiyon aşırı yükleme yapmak istiyorum, ancak PHP (hatta PHP5) Eğer yaptığınız gibi aşırı yüklenme yok değil gibi, Java söylüyorlar. Overloading section PHP kılavuzunda değil function overloading:

Note: PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.

Bu anlamına gelebilir:

class ArticleMapper {
   public function getCollection($param) {
      if (is_array($param)) { $this->getCollectionByArray($param); }
      if (is_int($param)) { $this->getCollectionByInt($param); }
      if (is_a($param, 'User')) { $this->getCollectionByUser($param); }
   }
   private function getCollectionByArray(array $param) { ... }
   private function getCollectionByInt($param) { ... }
   private function getCollectionByUser(User $param) { ... }
}

Bu benim göz bunu yapmak için iyi bir yol gibi görünüyor.