Benim test-uygulama için iyi bir PHP tasarımı (deseni?) Nedir?

2 Cevap php

Ben bir simple sınıf (PHP5) yazmak istiyorum ki 'koşmak' alt sınıflarından bir bilinmeyen miktarda olabilir. Bu alt sınıfları en iyi 'çek' olarak tercüme edilir; hepsi az ya da çok aynı şeyi yapmak ve bir cevap (doğru / yanlış) verecektir. Sistem başlatma çek olarak düşünün.

Zamanla yeni çekler (alt sınıfları) bir dizine eklenecek ve ana sınıfı çağrıldığında otomatik olarak çalıştırılması gerekir. Diğerleri çek yazmak olabilir ama ana sınıfı tarafından dikte fonksiyonları takip etmek zorunda kalacak.

What would be a clean yet simple way to build this? I found the Factory pattern and combined with interface it seems a good starting point. However I am not sure, and I would appreciate advice on this.

EDIT: the provided answers here all work, however the answer by Gordon gives additional possibilities of batches and stacking, something I did not think of at the time of asking, but am now rather happy about.

2 Cevap

Bir Toplu gibi işlevleri oluşturmak istiyorsanız, Command Pattern kullanın.

Aşağıda Desenin çok basit bir uygulamasıdır. Fikir çağırmak istediğiniz tüm sınıflar için birleşik bir arayüze sahip olmaktır. Her sınıf toplu bir operasyon kapsüller:

interface BatchCommand
{
    public function execute();
    public function undo();
}

Arabirimini uygulayan bir sınıf, tüm alt sınıflar komutanı olacak:

class BatchCommander implements BatchCommand
{
    protected $commands;

    public function add(BatchCommand $command)
    {
        $this->commands[] = $command;
    }
    public function execute()
    {
        foreach($this->commands as $command) {
            $command->execute();
        }
    }
    public function undo()
    {
        foreach($this->commands as $command) {
            $command->undo();
        }
    }
}

Basit bir komut bu gibi görünebilir:

class FileRename implements BatchCommand
{
    protected $src;
    protected $dest;

    public function __construct($src, $dest)
    {
        $this->$src;
        $this->dest;
    }

    public function execute()
    {
        rename($this->src, $this->dest);
    }

    public function undo()
    {
        rename($this->dest, $this->src);
    }
}

Daha sonra bu gibi kullanabilirsiniz:

$commander = new BatchCommander;
$commander->add(new FileRename('foo.txt', 'bar.txt'));
$commander->add(/* other commands */);
$commander->execute();

BatchCommander bir BatchCommand kendisi olduğu için, kolayca böylece, örneğin, çok esnek bir ağaç yapısını oluştururken, diğer Kümelerle bir araya ait toplu yığabilirsiniz

$batch1 = new BatchCommander;
$batch1->add(/* some command */);
$batch1->add(/* some other command */);

$batch2 = new BatchCommander;
$batch2->add(/* some command */);
$batch2->add(/* some other command */);

$main = new BatchCommander;
$main->add($batch1);
$main->add($batch2);
$main->execute();

Lütfen Giriş / Test bağlamda, bu grup kavramsal bir test paketi içine tek testleri ait olabilir anlamına gelir. Ve sen başka içine bir paketi istifleme, test suit test paketleri oluşturabilirsiniz.

Tabii ki, aynı zamanda örnekleme kontrol ve dosya yolunda dosyalar üzerinden çalışan bütün BatchCommands init sahip BatchCommander bir dosya yolu verebilir. Ya da kontrol komutları oluşturmak için kullanmak o bir fabrika örneği geçmektedir.

Sen execute ve undo yöntem adları için sahip değilsiniz. İsterseniz check olarak adlandırın. Eğer ihtiyacınız yoksa undo dışarı bırakın. Temel fikir rağmen hala aynı kalır: böyle bakmak ne olursa olsun komuta edilecek tüm sınıfları için bir arayüz. Uyarlamak için çekinmeyin.

Biraz daha farklı bir usecase sahip alternatif bir Chain of Reponsibility modelidir. Bu çok yarar olacağını görmek için Check it out.

Burada sorun, sınıfın adını bilmeniz gerekir çünkü, sen örneğini ve çalıştırmak hangi sınıfları bulmak nasıl sanırım.

Ben dizindeki her *. Php dosya yüklemek ve basit bir adlandırma kuralı kullanmanızı öneririz. Örneğin, dosya (eksi uzantısı) adı sınıfın adıdır. Sonra sadece:

 // foreach $file in glob("*.php"):
    $classname = basename($file, ".php");
    $instance = new $classname(); 
    $result = $instance->runCheck();

runCheck() her sınıf sağlaması gerekir gerçek bir yöntem olduğu.

Siz belirli bir sırayla kontrolleri çalışan hakkında bir şey söylemedi, ama her dosya için bir nn_ önek ekleyerek ve bunları sırayla yük tarafından giderildiği olabilir. Örneğin 05_CheckFoo.php.