【问题标题】:Design Pattern for Pipleline/Stages in application应用程序中的流水线/阶段的设计模式
【发布时间】:2016-03-17 06:37:16
【问题描述】:

在我的申请中,潜在客户必须经历一些阶段。

例如:

New
In Progress
Won
Lost

这些只是 11 个阶段中的四个阶段。在每个阶段,都会有一些必须执行的动作。

例如,潜在客户从“新建”移动到“进行中”,我需要更新四个表中的一组特定值。

什么是我可以在这里使用的理想设计模式,以便将来如果出现任何新阶段,可以很容易地在代码中适应它?

我正在考虑使用工厂模式。

编辑: 我做了这样的事情:

interface StageInterface
{
    public function changeStage($previous_stage, $next_stage, $ticket_details);
}

abstract class ParentStage implements StageInterface
{
    public function changeStage($previous_stage, $next_stage, $ticket_details)
    {
        $ticket_details->stage_id = $next_stage;
        $ticket_details->save();

        return $this;
    }
}

Class InProgress extends ParentStage
{
}

class TicketStagesFactory
{
    protected $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function getObject()
    {
        switch ($this->data) {

            case Stage::IN_PROGRESS:
                return new \App\Http\Controllers\Stages\InProgress();
                break;
     }
}

然后我像这样使用工厂:

$factory = new TicketStagesFactory($next_stage);
$test = $factory->getObject()->changeStage($previous_stage, $next_stage, $ticket_details);

这是正确的做法吗?

【问题讨论】:

    标签: php algorithm oop laravel design-patterns


    【解决方案1】:

    这实际上看起来更像是一个工作流程。 状态机的工作方式更像这样: 对于一个状态,一个事件会导致它转换到另一个状态。 工作流程更像您所说的: 对于一个状态,必须执行动作,这些动作的结果决定下一个状态。

    我会为 php 寻找一个工作流引擎,以使您的工作可维护。

    【讨论】:

      【解决方案2】:

      这取决于你的程序流程,但想法可能是:

      //ABSTRACT CLASS FOR A STAGE
      abstract class LeadStage
      {
          protected $lead;
      
          //INJECT YOUR LEAD OBJECT
          public function __construct( Lead $lead )
          {
              $this->lead = $lead;
          }
      
          //handle the stage logic on the $lead object
          public abstract function handle();
      }
      
      //CONCRETE CLASS FOR A STAGE
      class InProgress extends LeadStage
      {
          //HANDLE THE CONCRETE STAGE LOGIC ON THE LEAD OBJECT
          public function handle()
          {
              //do some logic on $this->lead;
          }
      }
      
      //LEAD OBJECT
      class Lead
      {
          protected $leadStage;
      
          public function construct(  )
          {
              //here build your first LeadStage object: you could also use a factory
              //pattern to create the LeadStage instance
              $this->leadStage = //...
          }
      
          public function setStage( LeadStage $stage )
          {
              $this->leadStage = $stage;    
          }
      
          public function handleStage()
          {
              $this->leadStage->handle();
          }
      }
      

      并像这样使用类:

      $lead = new Lead();
      
      //will handle the first stage
      $lead->handle();
      
      //something causes the stage to change
      $lead->setStage( new InProgress( $lead ) );
      
      //will handle the InProgess stage logic
      $lead->handleStage();
      

      因此,为每个阶段使用单个类,会将处理阶段逻辑的责任委托给特定类的对象。

      当您需要添加状态时,您只需创建新的LeadStage 实现

      【讨论】:

      • 我已经添加了我的实现,你能看看它是否正确吗?
      • @phantophoenix :changeStage 方法的签名与您的接口和实现不同。应该是一样的。考虑将ticket 对象作为依赖项传递给阶段对象,如我在示例中所示
      • 哦。是的,我正在改变它。可能错过了。但在一般意义上,实现是否正确?
      • @phantophoenix :通常你不能说模式是否“正确”,这取决于上下文和它的使用方式;如果你觉得它适合你的架构,那就去吧
      猜你喜欢
      • 2019-02-19
      • 2017-02-18
      • 2023-03-07
      • 1970-01-01
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-29
      相关资源
      最近更新 更多