【问题标题】:php - how to improve code with OOPphp - 如何使用 OOP 改进代码
【发布时间】:2017-02-17 22:22:49
【问题描述】:

这可能已经讨论过好几次了,但我想知道 OOP 如何帮助我改进我的代码。 我曾经以程序方式编码。但是有一个合理的逻辑。在整个项目中使用的代码片段都包装在函数中。但是所有函数都放在一个大的functions.php文件中(我发现效率不是很高)。 例如,这是一个检查销售是否过期的功能:

function is_sales_expired($salesId, PDO $conn) {
    $now=time();
    $sql="SELECT * FROM specialoffers WHERE id=:id";
    $st=$conn->prepare($sql);
    $st->bindvalue(":id",$salesId,PDO::PARAM_STR);
    $st->execute();
    $sales_array=$st->fetchAll();
    if($now<$sales_array[0]['finishdate'] && $now>$sales_array[0]['startdate']) {
        return FALSE;
    } else {
        return TRUE;
    }
}

现在我决定转向 OOP 并将我的代码转换为 OOP。所以我创建了类并将与特定行为相关的函数放入每个类中。例如具有is_sales_expired() 和其他与销售相关的方法的销售类。属性和构造函数如下所示:

class Sales
{
    private $conn;
    private $stockObj;
    private $userObj;
    private $cartObj;
    private $randomObj;

    function __construct(PDO $conn)
    {
        $this->conn = $conn;
        $this->stockObj = new Stock($this->conn);
        $this->userObj = new User($this->conn);
        $this->cartObj = new Cart($this->conn);
        $this->randomObj = new Random($this->conn);
    }
    //methods come here//
}

然后我使用spl_autoload_register 在我的代码中加载类,因此我不必在每个其他文件中都包含所有类文件。使用这种方法,调用方法更容易一些,我不需要将PDO $conn 传递给每个方法调用,并且它已经与构造函数一起传递了。

嗯,这些都很好,所有相关代码现在都在一个地方,也许更容易管理。但我有一种感觉,OOP 应该提供更多。使用我使用的方法,我不觉得现在我的代码更有效率和可维护性。我觉得我应该在这里错过一些概念。 感谢您的帮助。

【问题讨论】:

标签: php oop procedural-programming


【解决方案1】:

很高兴您已经开始将代码组织成对象,这是向更好的应用程序结构迈出的一步。 一旦开始深入研究它,您就会找到将当前对象拆分为更小的部分并以更好的方式组织它们的方法,从而以更少的代码以更灵活的方式解决更多问题。

例如,在您的代码中,业务逻辑仍然与数据库紧密耦合。如果您决定使用mysqli 而不是PDO 怎么办?您必须接触应用程序中的每个类。

但是,如果将数据库交互提取到业务逻辑使用的自己的一组对象中,那么替换数据库访问层会容易得多。事实上,在这种情况下,您可以很容易地将 MySQL 替换为 PostgreSQL 甚至是普通文件。

我可以想到两种方法来详细了解 OOP 的工作原理:阅读 book 或从现有代码中学习。

我链接的这本书是我最喜欢的 OOP 书籍,它展示了一些非常好的示例,说明如何通过将程序分解为协作对象来使用 OOP 解决问题。

我还建议开始使用一些 OOP 框架,我过去对 Yii 有过一些很好的经验,请查看 guide 看看它的样子。您将看到大量有用的对象解决了开发 Web 应用程序时必须解决的各种问题。 尝试使用它构建一些简单的应用程序,然后尝试查看框架代码以了解其实际工作方式。

另一个建议是研究自动测试。这不仅可以让您的应用程序保持活力,还可以教您如何组合更好的对象。您必须在两种不同的情况下使用您的类 - 您的实际代码和测试。在测试内部,您将希望将您正在测试的对象与其余代码隔离开来,例如,在不接触数据库的情况下测试销售统计算法。您必须将代码拆分成更小、更灵活的结构才能做到这一点。

【讨论】:

    【解决方案2】:

    您有了一个良好的开端,开始思考对象架构需要时间。 OOP 的优势在于它可以模仿代码必须交互的事物。所以想想它需要处理的事情和需要做的动作。因此,在您的示例中,您可以有一个新类 SpecialOffers,它将处理与您的 specialoffers 表相关的所有事情。

    例如:

    class SpecialOffers {
    
    function __construct(PDO $conn)
    {
        // this is connected to the server table
        $this->conn = $conn;
    
    }
    
    // get the details of a special offer
    private function get($salesId) {
    
        $sql="SELECT * FROM specialoffers WHERE id=:id LIMIT 1";
        $st=$this->conn->prepare($sql);
        $st->bindvalue(":id",$salesId,PDO::PARAM_STR);
        $st->execute();
        $rows = $st->fetchAll();
    
        if (count($rows) > 0) {
            return $rows[0];
        } else {
            return null;
        }
    
    }
    
    // answers whether a particular sales is active
    public function isActive($salesId) {
        $answer = $this->get($salesId);
    
        if (isset($answer['finishdate']) && isset($answer['startdate'])) {
            $now=time();
            return $now<$answer['finishdate'] && $now>$answer['startdate'];          
        } else {
            return false;
        }
    
    }
    

    }

    还有很多事情要做,比如错误处理,但随着事情的分解,您会看到它是如何开始变得更加明显的,而且您只考虑特别优惠。它们是如何工作的?会出什么问题?

    最后,在尝试考虑类的范围时,最好的建议来自 SOLID 原则。第一个,S——单一职责原则:

    一个类应该只有一个职责(即只有一个 软件规范的潜在变化应该能够 影响类的规范)

    最好的课可以用一句话来描述。方法也一样,用一句话来描述它的作用。

    【讨论】:

      猜你喜欢
      • 2015-12-25
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      • 1970-01-01
      • 2015-04-16
      • 2016-12-20
      • 2017-07-21
      相关资源
      最近更新 更多