Php 如何以更少的代码重写重构代码中的硬编码状态?

Php 如何以更少的代码重写重构代码中的硬编码状态?,php,laravel,design-patterns,database-design,refactoring,Php,Laravel,Design Patterns,Database Design,Refactoring,我在应用程序中使用一些硬编码状态来跟踪订单的状态。例如 1 - draft 2 - placed 3 - completed 目前,我将它们作为订单状态保存在数据库表中。在应用程序级别,我使用这些状态来验证订单更新。比如 如果订单状态=1,则无法完成。 如果订单状态=2,则不能删除。 如果订单状态>2,则无法编辑。 我不确定的是,在未来的需求中,当前状态之间可能会有新的状态。像 1 - draft 2 - placed 3 - partially completed 4 - complete

我在应用程序中使用一些硬编码状态来跟踪订单的状态。例如

1 - draft
2 - placed
3 - completed
目前,我将它们作为订单状态保存在数据库表中。在应用程序级别,我使用这些状态来验证订单更新。比如

如果订单状态=1,则无法完成。 如果订单状态=2,则不能删除。 如果订单状态>2,则无法编辑。 我不确定的是,在未来的需求中,当前状态之间可能会有新的状态。像

1 - draft
2 - placed
3 - partially completed 
4 - completed

如何在这种情况下防止代码重写,如果当前状态之间存在多个状态,我将不得不在将来重写所有条件。

您可以创建一个常量类,并在其中定义一个常量变量,如下所示:

class Constant
{
    const DRAFT = 'draft';
    const PLACED = 'placed';
}
if($orderStatus == Constant::DRAFT){
  //success
}

然后在刀片文件中使用,如下所示:

class Constant
{
    const DRAFT = 'draft';
    const PLACED = 'placed';
}
if($orderStatus == Constant::DRAFT){
  //success
}


您可以创建一个常量类,并在其中定义一个常量变量,如下所示:

class Constant
{
    const DRAFT = 'draft';
    const PLACED = 'placed';
}
if($orderStatus == Constant::DRAFT){
  //success
}

然后在刀片文件中使用,如下所示:

class Constant
{
    const DRAFT = 'draft';
    const PLACED = 'placed';
}
if($orderStatus == Constant::DRAFT){
  //success
}


我会把它抽象成一个服务。如何编写此服务取决于您,下面的示例是使用静态类和函数。您可能希望使其永不满足,并使用依赖项注入

您需要以某种方式存储状态。我将从静态数组开始,然后描述如何将其传递到数据库

id | status
--------------
1  | draft
2  | placed
3  | completed

status_id | document_class | verb
------------------------------------
1         | Models\Order   | edit
1         | Models\Order   | delete
2         | Models\Order   | edit
静态电容器类 然后,您可以使用检查对对象执行操作的能力

if (ObjectPermitter::can($object, ObjectPermitter::EDIT)) {
    // yes, you can
}
现在,这需要进行大量的静态设置,这意味着您必须在每次想要更改行为工作方式时推送代码,但您应该能够看到扩展新模型类型和新状态是多么容易

数据库 另一种方法是将所有这些数据移动到数据库中

id | status
--------------
1  | draft
2  | placed
3  | completed

status_id | document_class | verb
------------------------------------
1         | Models\Order   | edit
1         | Models\Order   | delete
2         | Models\Order   | edit
现在,您的can函数可以在数据库上执行查找

SELECT COUNT(*) AS c
FROM status
    INNER JOIN status_permission ON status.id = status_permission.status_id
WHERE status.status = :1
    AND status_permission.document_class = :2
    AND status_permission.verb = :3
您的呼叫代码填写的位置

:1 $object->getStatus()
:2 get_class($object)
:3 self::EDIT, or 'edit'

然后您的函数可以返回$results[0]['c']==1

我会将其抽象为一个服务。如何编写此服务取决于您,下面的示例是使用静态类和函数。您可能希望使其永不满足,并使用依赖项注入

您需要以某种方式存储状态。我将从静态数组开始,然后描述如何将其传递到数据库

id | status
--------------
1  | draft
2  | placed
3  | completed

status_id | document_class | verb
------------------------------------
1         | Models\Order   | edit
1         | Models\Order   | delete
2         | Models\Order   | edit
静态电容器类 然后,您可以使用检查对对象执行操作的能力

if (ObjectPermitter::can($object, ObjectPermitter::EDIT)) {
    // yes, you can
}
现在,这需要进行大量的静态设置,这意味着您必须在每次想要更改行为工作方式时推送代码,但您应该能够看到扩展新模型类型和新状态是多么容易

数据库 另一种方法是将所有这些数据移动到数据库中

id | status
--------------
1  | draft
2  | placed
3  | completed

status_id | document_class | verb
------------------------------------
1         | Models\Order   | edit
1         | Models\Order   | delete
2         | Models\Order   | edit
现在,您的can函数可以在数据库上执行查找

SELECT COUNT(*) AS c
FROM status
    INNER JOIN status_permission ON status.id = status_permission.status_id
WHERE status.status = :1
    AND status_permission.document_class = :2
    AND status_permission.verb = :3
您的呼叫代码填写的位置

:1 $object->getStatus()
:2 get_class($object)
:3 self::EDIT, or 'edit'

然后您的函数可以返回$results[0]['c']==1

我会重构为枚举。可能签出或使用数据库中模型和枚举字段上的常量进行自定义实现。

我将重构为枚举。也许可以签出或使用数据库中模型和枚举字段上的常量进行自定义实现。

当然可以帮助您。通常,我会在代码中使用常量来表示每个步骤,我的所有代码都会引用这些常量。常数的值将来可能会改变,代码也不会在意。@WesleySmith所以如果我使用常数,代码重写的次数会减少。但是还有一些重写工作要做。你可以把你的例程变成一个函数,这样你只有在将来事情发生变化时才能改变这个函数。为什么不使用设计模式来解决这个问题呢。查看php接口这可能有助于您扩展应用程序,当然也有助于您做到这一点。通常,我会在代码中使用常量来表示每个步骤,我的所有代码都会引用这些常量。常数的值将来可能会改变,代码也不会在意。@WesleySmith所以如果我使用常数,代码重写的次数会减少。但是还有一些重写工作要做。你可以把你的例程变成一个函数,这样你只有在将来事情发生变化时才能改变这个函数。为什么不使用设计模式来解决这个问题呢。看看php接口,这可能会帮助您扩展应用程序。正如我所见,这减少了代码重写。但也有一些。如果您使用const DRAFT=1;,我也将对此进行检查;。正如我所看到的,这减少了代码的重写。但也有一些。如果您使用const DRAFT=1;,我也将对此进行检查;。
id | status
--------------
1  | draft
2  | placed
3  | completed

status_id | document_class | verb
------------------------------------
1         | Models\Order   | edit
1         | Models\Order   | delete
2         | Models\Order   | edit