ООП дизайн вопрос - избегать повторения кода в похожих классах? - PullRequest
1 голос
/ 11 декабря 2010

Я пишу несколько классов на PHP для серверной части веб-сайта, который мы разрабатываем. Классы выглядят примерно так:

class SomeEntity {
    // These fields are often different in different classes
    private $field1 = 0, $field2 = 0, ... ;

    // All of the classes have one of these
    static function create($field1, $field2) {
        // Do database stuff in here...
    }

    // All of the classes have similar constructors too
    function __construct($id_number) {
        // Do more database stuff in here...
    }

    // Various functions specific to this class
    // Some functions in common with other classes
}

Проблема в том, что существует множество этих классов, и все они должны иметь похожие конструкторы и несколько общих функций, поэтому в идеале я бы хотел написать суперкласс для обработки всего этого, чтобы было минимальное копирование / вставка. на. Тем не менее, каждый из подклассов имеет разные переменные экземпляра и параметры, так какой же лучший способ создать суперкласс?

(Чтобы сформулировать это, возможно, немного лучше, как написать функцию-конструктор или другие функции, которые работают с переменными экземпляра класса, но не обязательно зная, что такое переменные экземпляра класса, и жестко кодируют их по имени?)

Ответы [ 2 ]

4 голосов
/ 11 декабря 2010

Вы можете пойти довольно далеко в направлении очень общего класса типа "Entity", особенно если вы используете различные магические методы.

Рассмотрим класс следующим образом (просто некоторые случайные удобные методы для классов, похожих на сущности, для совместного использования):

<?php
abstract class AbstractEntity {

  protected $properties;

  public function setData($data){
    foreach($this->properties as $p){
        if (isset($data[$p])) $this->$p = $data[$p];
    }
  }

  public function toArray(){
    $array = array();
    foreach($this->properties as $p){
       $array[$p] = $this->$p;
       //some types of properties might get special handling
       if ($p instanceof DateTime){
           $array[$p] = $this->$p->format('Y-m-d H:i:s');
       }
    }
  }

  public function __set($pname,$pvalue){
     if (! in_array($pname,$this->properties)){
        throw new Exception("'$pname' is not a valid property!");
     }
     $this->$pname = $pvalue;
  }
}


<?php

class Person extends AbstractEntity {
   protected $properties = array('firstname','lastname','email','created','modified');
}
0 голосов
/ 11 декабря 2010

По сути, вы разделяете все, что вы повторяете, в родительский класс или вспомогательный класс.

Если это обычное действие, которое относится к объекту и применяется к аналогичным объектам, вы помещаете это в родительский класс и наследуете от него. Если дочерние элементы этого родителя имеют сходные члены / свойства, но по какой-либо причине имеют разные имена, вы просто пишете метод для приема параметров, а затем передаете различные имена свойств при вызове этого метода.

Если это обычное действие, относящееся к объекту, и только к этому объекту, оно становится методом в дочернем классе, которому это необходимо.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...