【问题标题】:PHP design pattern for conditional instantiation of classes [closed]用于类的条件实例化的 PHP 设计模式 [关闭]
【发布时间】:2019-05-02 14:01:14
【问题描述】:

我正在寻找以下场景中的最佳实践(使用 Laravel,但这不相关):我有一个方法 strokePet,它取决于请求的有效负载,将实例化 DogStrokerCatStroker班级。 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 的习惯? (我知道这可能会因为过于模糊而被标记。)

【问题讨论】:

  • 拥有一个接口(或父类,甚至可以是抽象的)有助于在您开始添加功能后保持代码整洁(因为您可以执行诸如 $x instanceof PetStroker 之类的操作)。至于设计模式:我建议在工厂模式中实现它,例如。创建提到的抽象类 PetStroker 并给它一个静态方法PetStroker::Create($pet),它可以返回 CatStroker 或 DogStroker 或任何你想要的。

标签: php oop design-patterns


【解决方案1】:

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

在您的情况下,工厂方法可能类似于:

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
}

然后您可以使用它来检索正确的实现,对调用者隐藏选择逻辑。

【讨论】:

    猜你喜欢
    • 2013-06-23
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多