2013-05-13 5 views
1

«У меня вопрос о наилучшем способе обработки свойств класса.Лучшая практика с классами

Для удобства объяснения, скажем, у меня есть класс, называемый компанией. «Компания» имеет отдельные свойства, такие как «имя», «адрес» и т. Д. Помимо этих отдельных свойств «Компания» также имеет несколько сотрудников, несколько офисов, & несколько кофейных машин. (Плохой пример, но лучшее, что я мог придумать).

При инициализации класса я могу запустить SQL-запрос в методе конструктора, чтобы получить имя, адрес и т. Д. Однако, поскольку «Сотрудники», «Офисы» и «Кофе-машины» хранятся в отдельных таблицах базы данных, и возвращать несколько результатов, чтобы сразу установить эти свойства, мне понадобится запустить еще три 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']; 
     } 
    } 
} 

Для чего это стоит, я подозреваю последнее, но могу использовать другие мнения.

Благодаря

ответ

0

Я думаю, что это вопрос предпочтений и производительности. Если вы можете прочитать дочерние коллекции с приемлемой производительностью запуска, вы можете сделать это. Изначальная инициализация будет загружаться быстрее с самого начала, но вам нужно защитить от попытки многократно заполнять коллекции.

0

Я думаю, что работающий запрос при необходимости является лучшим методом, это сделает код более понятным и понятным, чем первый метод. Модификация также легка во втором методе.

0

Это зависит от ваших потребностей.

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

Этот код будет производить разные результаты по каждому пути. Ленивая загрузка - хорошая практика.

0

Когда я сталкиваюсь с подобными ситуациями, я предпочитаю, чтобы объекты были разделены. Таким образом, у меня не было бы запроса выбора данных у сотрудников внутри корпоративного класса. Я бы экземпляр сотрудника и этот экземпляр будет определен так:

company.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 
     } 
    } 

} 

employee.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()); 

?> 

Где преимущества? Сотрудник имеет поведение, большее, чем получение информации для компании. Это сама сущность. Итак, зачем распространять свою логику на ваш код?Держите логику внутри своего класса, и если нужен другой класс, просто используйте. Обратите внимание: у компании есть способ извлечения своих сотрудников. Но у компании нет логики ее получить.

Он по-прежнему не может загружать сотрудников, если вам это не нужно. Оставьте решение, когда оно понадобится сотруднику и загрузите его, если потребуется.

Конечно, я использовал ваш пример, чтобы привести меня через свой ответ. Но этот подход можно распространить на все ваши потребности.

Смежные вопросы