1

'我有一个关于处理类属性的最佳方法的问题。

为了便于解释,假设我有一个名为 company 的类。“公司”具有单一属性,例如“名称”、“地址”等。除了这些单一属性之外,“公司”还具有多个员工、多个办公室和多个咖啡机。(不好的例子,但我能想到的最好的例子)。

初始化一个类时,我可以在构造方法中运行 SQL 查询来检索姓名、地址等。但是,由于“Employees”、“Offices”和“Coffee Machines”都存储在不同的数据库表中,并返回多个结果,要立即设置这些属性,我需要再运行三个 SQL 查询。

这是最好的方法,还是创建三个方法“getEmployees”、“getOffices”和“getCoffeeMachines”并在需要时运行查询的最佳实践?

不确定这是否清楚。这里有两个例子。是否最好这样做,从而在初始化时调用四个 SQL 查询,以便所有信息立即可用:

Class Company
{
    private $name;
    private $address;
    private $employees;
    private $offices;
    private $coffeeMachines;

    public function __construct()
    {
        $this->employees = array();
        $this->offices = array();
        $this->coffeeMachines = array();

        ... SQL to get name and address ...
        $this->name = $rs['name'];
        $this->address = $rs['address'];

        ... SQL to get employees ...
        while ($rs = mysql_fetch_array)
        {
            $this->employees[$rs['id']] = $rs['name'];
        }

        ... SQL to get offices ...
        while ($rs = mysql_fetch_array)
        {
            $this->offices[$rs['id']] = $rs['office'];
        }

        ... SQL to get coffee machines ...
        while ($rs = mysql_fetch_array)
        {
            $this->coffeeMachines[$rs['id']] = $rs['coffeeMachine'];
        }
    }
}

或者最好这样做,只在初始化时运行一个 SQL 查询,并在需要时运行未来的查询

Class Company
{
    private $name;
    private $address;
    private $employees;
    private $offices;
    private $coffeeMachines;

    public function __construct()
    {
        ... SQL to get name and address ...
        $this->name = $rs['name'];
        $this->address = $rs['address'];
    }

    public function getEmployees()
    {
        ... SQL to get employees ...
        while ($rs = mysql_fetch_array)
        {
            $this->employees[$rs['id']] = $rs['name'];
        }
    }

    public function getOffices()
    {
        ... SQL to get offices ...
        while ($rs = mysql_fetch_array)
        {
            $this->offices[$rs['id']] = $rs['office'];
        }
    }

    public function getCoffeeMachines()
    {
        ... SQL to get coffee machines ...
        while ($rs = mysql_fetch_array)
        {
            $this->coffeeMachines[$rs['id']] = $rs['coffeeMachine'];
        }
    }
}

对于它的价值,我怀疑后者,但可以使用其他意见。

谢谢

4

4 回答 4

0

我认为这是一个偏好和性能问题。如果您可以读取具有可接受的启动性能的子集合,您可以选择这样做。延迟初始化将在开始时加载得更快,但您需要防止尝试多次填充集合。

于 2013-05-14T00:12:53.900 回答
0

我认为在需要时运行查询是最好的方法,这将使代码比第一种方法更具可读性和可理解性。在第二种方法中修改也很容易。

于 2013-05-14T00:25:10.823 回答
0

这取决于您的需求。

$company = new Company();
$company->addOffice();
$company->getOffices();

此代码将在每种方式上产生不同的结果。延迟加载是一种很好的做法。

于 2013-05-14T00:27:40.773 回答
0

当我面对这样的情况时,我更喜欢将物体分开。因此,我不会查询从公司类内的员工中选择数据。我会有一个员工实例,该实例的定义如下:

公司.php

<?php
require_once "employee.php";
class company{
    protected $employee;
    protected $company_name;
    protected $company_id;
    function company($id_company,$employee=null){
        if($employee){
            {
                $this->employee = $employee;
            }
            //setting company methods values. Here I have the company query
            //...
        }
    }
    function get_company_employees(){
        if($this->employee){
            return $this->employee->get_employees_by_company_id($this->company_id);
        }else{
            //throw same exception
        }
    }

}

员工.php

 <?php
class employee{
    //employee class attribs
    function employee($employee_id=null){
        if($employee_id){
            //load data from db to class attribs. Here I have a query to get one employee
        }
    }
    function get_employees_by_company_id($company_id){
        //select employees from db and populate collection to return. Here I have a query to return employees from one company
        return array();
    }
}

所以,当我需要有员工的公司时,我会这样做:

<?php
    require_once "company.php";
    require_once "employee.php";
    $comp_id = 1; 
    $company = new company($comp_id, new employee);
    print_r($company->get_company_employees());

?>

好处在哪里?员工的行为大于向公司检索信息。它本身就是一个实体。那么,为什么要将其逻辑传播到您的代码中呢?将逻辑保留在自己的类中,如果其他类需要它,只需使用。请注意,公司有一种方法来检索其员工。但是公司没有得到它的逻辑。

如果您不需要,它仍然可以不加载员工。离开在需要员工时做出决定,并在需要时加载它。

当然,我用你的例子来引导我完成我的回答。但是这种方法可以扩展到您的所有需求。

于 2013-05-14T00:42:37.040 回答