用于类的条件实例化的PHP设计模式

用于类的条件实例化的PHP设计模式,php,oop,design-patterns,Php,Oop,Design Patterns,我正在以下场景中寻找最佳实践(使用Laravel,但这并不相关):我有一个方法strokePet,它将根据请求负载实例化DogStroker或CatStroker类。strokePet方法通过API端点调用 class PetController { public function strokePet($request) { if ($request->pet == 'dog') { $stroker = new DogStroker

我正在以下场景中寻找最佳实践(使用Laravel,但这并不相关):我有一个方法
strokePet
,它将根据请求负载实例化
DogStroker
CatStroker
类。
strokePet
方法通过API端点调用

class PetController
{
    public function strokePet($request)
    {
        if ($request->pet == 'dog') {
            $stroker = new DogStroker;
        else if ($request->pet == 'cat') {
            $stroker = new CatStroker;
        } 
        $stroker->stroke();
    }
}

class DogStroker
{
    public function stroke()
    {
        echo 'grr';
    }
}

class CatStroker
{
    public function stroke()
    {
        echo 'prr';
    }
}
创建
PetStroker
接口是否有任何优势,例如

interface PetStroker
{
    public function stroke();
}

或者是我在这里遗漏了一些设计模式,这些模式会使OOP更加地道?(我知道这可能会因为太模糊而被标记。)

我想您正在寻找。它允许为提供的输入封装对象选择,并返回仅实现给定接口的内容

在您的情况下,factory方法可以类似于:

public static function GetStroker($request) // or Create($pet), as suggested in comments
{
    if ($request->pet == 'dog') { return new DogStroker; }
    if ($request->pet == 'cat') { return new CatStroker; } 
    return new DefaultStroker; // or throw exception
}
然后,您可以使用它来检索正确的实现,对调用者隐藏选择逻辑。

一旦开始添加功能,拥有一个接口(或父类,甚至可以是抽象的)有助于保持代码干净(因为您可以执行诸如$x instanceof PetStroker之类的操作)。至于设计模式:我建议在工厂模式中实现这一点,例如,创建提到的抽象类PetStroker,并为其提供一个静态方法
PetStroker::create($pet)
,该方法要么返回CatStroker,要么返回DogStroker,要么返回您想要的任何东西。