Bu işlev çok fazla parametre var mı?

10 Cevap php

Sonunda, bu işlevi var. Ben bu normal olup olmadığını bilmiyorum.

function user_registration($user_name, $user_email , $user_pass , $address , 
    $city , $postalcode  , $country  , $phone , $mobilephone)

Nasıl ve neden bu artırabilir?

10 Cevap

Sen tüm değişkenler birlikte güzel paketlenmiş, ya da sadece bir "Kullanıcı" class yapmak ve belirleyiciler ile tüm özellikleri eklemek ve özel bir yöntemle sonunda doğrulama yapmak ile bir dizi geçebileceği ya:

class User {

  public function setName($name) {
    $this->name = $name;
  }

  [...]

  public function register() {

    //Validate input
    if (empty($this->name))
      $this->errors[] = "ERROR, Username must not be emtpy";

    //Add the user to the database
    //Your SQL query
    return empty($this->errors);
  }

}

$user = new User();
$user->setName("Peter");
$success = $user->register();

if (!$success)
  echo "ERRORS OCCURED: ".print_r($user->errors, true);

Bir dizi gibi - bir çözüm sadece birkaç veri parçaları içerebilir bir parametre, sahip olacaktır.

Sizin fonksiyonu bu şekilde tarif edilebilir:

function user_registration(array $data) {
    // work with $data['name']
    // and $data['email']
    // ...
}

Ve bunu şöyle derim:

user_registration(array(
    'name' => 'blah',
    'email' => 'test@example.com', 
    'pass' => '123456',
    // and so on
));


Nice things are :

  • Ekleyebilir / kolayca "parametreleri" kaldır
  • "Parametreler" istediğiniz sırayla geçirilebilir

O kadar kötü değil şeyler şunlardır:

  • Hiçbir ipucu IDE yazarken
  • Dokümantasyon Hayır (like phpDoc)

Ben şahsen çok fazla parametre vardır sanmıyorum. Fonksiyonlar tanımı bakarak bu bir dizi denir eğer çok açık olmaz, hangi girdi olarak ne gerek açıktır.

"Değilse kırdı bunu düzeltmek yok!"

Bir şekilde bu işleve parametre olarak bir dizi geçmek ve bu dizideki tüm bilgi koymak için:

function user_registration(array $user_info)
{
   // process $user_info;
}

(Değil kararlı bir kural olarak) başparmak genel bir kural olarak, sormak zorunda zaman "bu işlev çok fazla parametre var mı?" - Cevap yes. Sizin sezgi size beynin henüz atlatmanın mümkün olmamıştır şey anlatıyor.

Bu özel durumda, akla gelen ilk şey kullanıcı cred.s ilk kontrol edilmelidir (kullanıcı adı zaten mevcut mu? Yeterli pw karmaşık) ve kullanıcı bilgilerini muhtemelen bir nesne kullanarak ya da ayrı ayrı ilave edilmesi gerektiğidir dizi.

Herhangi bir parametre olmadan Fonksiyonu (yöntemi) en iyisidir. Bir parametrenin içine ile fonksiyon 2 parametre fonksiyonu daha iyidir. 2 parametrelerle işlevi böylece 3 parametreleri ile fonksiyonu daha iyidir.

@ Florianh kod geliştirilebilir nasıl mükemmel bir çözüm vermiştir. Bu yorum ile, ben bir sistem tasarım açısından "neden" kısmına değinmek istiyoruz.

Nesne yönelimli bir bakış açısıyla, diğer nesneleri özelliklerini işlemek gerekir. Nitelikleri "halk" olarak tanımlanan asla nedeni budur. Onlar olmalıdır "özel" örn:

private var $name;

Bunun nedeni, diğer amaçlar, bu değişken işlemek ne zaman, nesnenin doğru çalışma riski olmasıdır. Yöntem, diğer taraftan, halka tanımlanabilir:

public function register() 

Buna göre, özniteliklerin manipülasyon uygun yöntemlerle olur. Bir yöntem olup, aynı zamanda özellikleri üzerinde operasyonların doğruluğunu değerlendirmek için de kullanılabilir.

{[(3 kullanarak Get methods ve bir niteliğin saving yeni bir değer kullanarak bir niteliğin reading akım değeri: gerçekleşebilir iki işlem vardır )]}.

İyi bir uygulama, her sınıf niteliği için bir get yöntemi uygulamak olacaktır. Değiştirilebilir her nitelik, hem de uygun bir dizi yöntem olmalıdır.

Sonuçta: Bazen bir get / set yöntemi (showData () gibi) uygulamak değil daha iyidir. Belirli bir sınıf içinde alıcılar ve belirleyiciler kullanım muhtemelen düşük bir performansa yol açabilir çünkü bu. Ancak bu değiştirme veya sınıf uygularken yanlış bilgileri kaydetmek için çalışıyor ve bunun sonucunda risk sınıfının bütünlüğünü koyarak, dikkatli olunması gerektiği anlamına gelir.

Şimdi, bunun yerine bir telefon ve cep numarası hem de yalnızca bir telefon numarasını kullanmaya karar olduğu gerçeğini göz önünde bulundurun. Cep telefonu numarası artık kullanılmayan olduğunda, ana program hala aynı kalır. Yapmanız gereken tek şey değişimdir / bir yöntemi kaldırmak. Alıcılar ve ayarlayıcılar kullanmanın avantajı, bir adaptability artış ve maintainability olduğunu.

Ben gibi tuşları dizi yapmak

$fields = array('field1', 'field2');
function register (array $values, array $keys)
{
    $data = array();
    foreach ($keys as $one)
    {
        if (isset($values[$one])) $data[$one] = $values[$one];
    }
    // or you can use array functions like array_flip and after - array intersect
}

Eğer argüman isimlerine baktığınızda, size ancak üç farklı grupta toplanabilir olduğunu fark edemez:

User Data:    $user_name, $user_pass
Address Data: $address, $city, $postalcode, $country
Contact Data: $user_email, $phone, $mobilephone

Sonuç olarak, uygulamak Introduce Parameter Object olabilir:

Genellikle birlikte geçirilecek eğilimi parametrelerin belli bir grup görüyorum. Çeşitli yöntemler bir sınıf veya çeşitli sınıflara ya, bu grubu kullanabilirsiniz. Sınıfları Böyle bir grup veri yığın olduğunu ve bu verilerin bütün taşıyan bir nesne ile değiştirilebilir. Bu arada, sadece grup nesneleri içine verileri bu parametreleri açmak için faydalıdır. Bu parametre listelerinin boyutunu azaltır, çünkü bu üstlenmeden yararlıdır, ve uzun parametre listeleri anlamak zordur. Yeni nesne üzerinde tanımlı erişiciler ayrıca yine daha kolay anlamak ve değiştirmek için yapar, kodu daha tutarlı olun.

Siz de diziler halinde grup argümanları olabilir OOP yapmak istemiyorum ama daha sonra tüm tip yararları kaybedersiniz eğer. Ben sadece nesneleri kullanarak umursamıyorum üstlenecek. Yani, Refactoring uyguladıktan sonra sizinle bitireceğiz

function user_registration(User $user, Address $address, Contact $contact)

Bu parametre listesine baktığımızda bunu fark Adres ve İletişim muhtemelen ilk etapta Kanala ait yapmak gerekir, böylece sadece için işlevi imza değiştirmeyi düşünebiliriz

function user_registration(User $user)

ve sonra bu gibi diyoruz:

$user = new User('johndoe', 'secretsauce');
$user->setAddress(new Address('Doe Street', 'Doe Town', 12345, 'Neverland'));
$user->setContact('jdoe@example.com', '+123 12345', '+123 54321');
user_registration($user);

Biz muhtemelen de ve sonra sadece mutlaka nesne bir İtimatname içine kullanıcı adı ve şifre yapabilir

user_registration(new User($credentials, $address, $contact));

Ctor verileri gerektiren biz yeni kayıtlı kullanıcıların tüm bu bilgiler var emin olun. Biz olsa kullanıcıların kaydedilmesi için adres ve iletişim ihtiyacı olmadığını iddia olabilir, bu yüzden Setter injection Burada yeterince iyi olabilir:

$user = new User(new Credentials('johndoe', 'secretsauce'));
$user->setAddress(new Address('Doe Street', 'Doe Town', 12345, 'Neverland'));
$user->setContact(new Contact('jdoe@example.com', '+123 12345', '+123 54321'));
user_registration($user);

Ancak, user_registration, küresel kapsamda ayrı bir işlev olarak yanlış olduğunu. Tarafından GRASP's Information Expert principle, yöntemler sorumluluğunu yerine getirmek için en çok bilgiye sahip nesneler üzerinde olmalıdır. Bu artırır Cohesion azaltır ve Coupling. Başka bir deyişle:

$user = new User($credentials);
$user->setAddress($address);
$user->setContact($contact);
$user->register();

Kullanıcı sınıfı ile bir sorun şimdi şifre içermektedir olmasıdır. Şifre sadece hiç doğrulama hizmeti karşı kullanıcının kimliğini doğrulamak için gereklidir. Biz kullanıcı adı hakkında iddia olabilir, ancak şifre kesinlikle tüm User nesnesinin parçası olmamalıdır. Böylece gibi bir şey yapmalıyım

$user = new User;
$user->setAddress($address);
$user->setContact($contact);
$user->register($credentials);

register() çağrıldığında ve sadece kullanıcı depolama yeni bir kullanıcı ekleme temsilci kimlik bilgilerini kullanır. Ama gerçek kullanıcı örneği onları tutmaz.

Son olarak, aggregation, çeşitli örnekleri basitleştirmek için Kullanıcı oluşturulmasını saklanması için Simple Factory or Builder pattern eklemek isteyebilirsiniz. Yoksa Repository pattern ve move the register() yöntemi orada tanıtmak isteyebilirsiniz. Bu olsa, bu soru için kapsamı dışındadır.

Ben bunu bu şekilde yapmak istiyorum

fields=explode(",","name,surname,lastname,street,city,region,zip,country");
user_registration($fields);

Ben eminim, çünkü bu değişkenler $ _POST geliyor