Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 哪种编程设计模式适合这个项目?_Php_Oop_Laravel_Design Patterns - Fatal编程技术网

Php 哪种编程设计模式适合这个项目?

Php 哪种编程设计模式适合这个项目?,php,oop,laravel,design-patterns,Php,Oop,Laravel,Design Patterns,您好,我正在寻找一些关于选择适合我当前项目的编程设计模式的指导 几个月来,我一直在努力寻找一个好的项目来正确地开始使用模式,而我刚刚开始的一个小项目似乎提供了一个完美的学习平台 基本上,我正在创建一个电报机器人,它将响应用户的命令。这不是我遇到的问题,而是如何最好地组织我的代码,以便添加新命令是干净且结构良好的 我不需要任何人为我编写任何代码,但有没有适合我的设计模式可以实现 以下是我目前在puesudo(顺便说一句,我使用的是Laravel)代码中所做的工作: 这很好,但我觉得 我重复了很多

您好,我正在寻找一些关于选择适合我当前项目的编程设计模式的指导

几个月来,我一直在努力寻找一个好的项目来正确地开始使用模式,而我刚刚开始的一个小项目似乎提供了一个完美的学习平台

基本上,我正在创建一个电报机器人,它将响应用户的命令。这不是我遇到的问题,而是如何最好地组织我的代码,以便添加新命令是干净且结构良好的

我不需要任何人为我编写任何代码,但有没有适合我的设计模式可以实现

以下是我目前在puesudo(顺便说一句,我使用的是Laravel)代码中所做的工作:

这很好,但我觉得

  • 我重复了很多代码(糟糕)
  • 添加新命令意味着不断编辑“入站类”文件。我认为这打破了固体中的开闭原理
  • switch语句对我来说有一种“代码味道”
我对所有不同类型图案的名称感到非常困惑。有人能告诉我,哪一个适合这种情况?我很高兴去研究它,以及它是如何实现的,但我不想去追逐一个不合适的,因为我不知道更好

多谢各位


编辑:似乎在我试图使问题变得一般化时,我把它弄得太迟钝了。我已经在使用MVC和Larvel了。我想这不是问题所在——我想知道哪种设计模式可以让我轻松、干净地添加更多命令——希望不必使用switch语句


在阅读了一些回复后,我想我开始明白该怎么做了。出于兴趣-下面建议的结构是实际的设计模式还是良好的结构化代码?

您在代码中实现的是MVC路由器。目前,您需要硬编码路由。相反,您还可以依靠自动加载为控制器实例化选择正确的类。如果该类不存在,则使用回退将使事情变得健壮。两个优点:

  • 易于扩展,只需将控制器类添加到按命名约定命名的文件中即可

  • 添加另一个控制器时,您根本不必触摸路由器

你会在互联网上找到很多这样的例子。自动加载功能也有很好的文档记录


玩得开心

您在代码中实现的是MVC路由器。目前,您需要硬编码路由。相反,您还可以依靠自动加载为控制器实例化选择正确的类。如果该类不存在,则使用回退将使事情变得健壮。两个优点:

  • 易于扩展,只需将控制器类添加到按命名约定命名的文件中即可

  • 添加另一个控制器时,您根本不必触摸路由器

你会在互联网上找到很多这样的例子。自动加载功能也有很好的文档记录


玩得开心

在arkascha sad的基础上,我还建议您为命令使用抽象类

abstract class Command {

    public function __construct( $params ){
        // do some common things with $params
        $this->do_command();
    }

    protected function do_command(){
         // empty function which will be overwritten by child classes
    }

}
你的孩子们的课程会是这样的

class FooCommand extends Command {

    public function __construct( $params ){
        parent::__construct( $params );
        // do something as well
    }

    // can be public
    public function do_command(){
         echo __CLASS__, '::FOO';
    }
}

class BarCommand extends Command {

    // or without __constructor as mentioned by scrowler if you dont
    // need to do additional coding with __contructor params

    // can be protected
    protected function do_command(){
         echo __CLASS__, '::BAR';
    }
}

class BazCommand extends Command {

    public function __construct( $params ){
        parent::__construct( $params );
        // do something as well
    }

    // it cannot be private
    private function do_command(){
         echo __CLASS__, '::BAZ';
    }
}

在arkascha sad的基础上,我还建议您为命令使用抽象类

abstract class Command {

    public function __construct( $params ){
        // do some common things with $params
        $this->do_command();
    }

    protected function do_command(){
         // empty function which will be overwritten by child classes
    }

}
你的孩子们的课程会是这样的

class FooCommand extends Command {

    public function __construct( $params ){
        parent::__construct( $params );
        // do something as well
    }

    // can be public
    public function do_command(){
         echo __CLASS__, '::FOO';
    }
}

class BarCommand extends Command {

    // or without __constructor as mentioned by scrowler if you dont
    // need to do additional coding with __contructor params

    // can be protected
    protected function do_command(){
         echo __CLASS__, '::BAR';
    }
}

class BazCommand extends Command {

    public function __construct( $params ){
        parent::__construct( $params );
        // do something as well
    }

    // it cannot be private
    private function do_command(){
         echo __CLASS__, '::BAZ';
    }
}

请查看命令设计模式。您还可以使用前面建议的抽象工厂模式来实例化要执行的命令

再详细说明一下我的答案。 让我们将入站控制器称为我们的客户机类。控制器的职责是捕获请求并将其路由到适当的操作,在这种情况下,发出命令。 但是,如果您看一下代码,控制器实际上是在决定在它接收的某些输入中实例化base的命令类型。如果由于某种原因命令类的构造函数发生了更改,那么您还必须更改入站控制器类中的代码,因为它现在还负责实例化要执行的命令对象。 如果您实现了一个抽象工厂并将其注入到控制器中,那么您将向工厂传递必要的输入,以决定应该实例化哪个命令并将其传递给控制器。控制器只触发它从工厂收到的命令,而不必担心命令是如何实例化的,或者它是什么类型的命令。控制器获得执行命令的请求,将命令的实例化委托给工厂,一旦工厂将命令交给控制器,就执行该命令。 最好是单一责任原则。抽象工厂负责实例化命令。控制器负责处理请求,在这种情况下,执行工厂返回的命令


通过查看代码,我们已经可以看到他正在以某种方式使用命令设计模式。这里有一个来自维基百科的定义:

请看一下命令设计模式。您还可以使用前面建议的抽象工厂模式来实例化要执行的命令

再详细说明一下我的答案。 让我们将入站控制器称为我们的客户机类。控制器的职责是捕获请求并将其路由到适当的操作,在这种情况下,发出命令。 但是,如果您看一下代码,控制器实际上是在决定在它接收的某些输入中实例化base的命令类型。如果由于某种原因命令类的构造函数发生了更改,那么您还必须更改入站控制器类中的代码,因为它现在还负责实例化要执行的命令对象。 如果您实现一个抽象工厂并将其注入控制器,则