2016-07-18 1 views
-1

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

Я использую базовый класс, parser, который анализирует страницу моей CMS. Этот класс содержит все основные функции, необходимые для фильтрации данных, полученных из базы данных, и их преобразования в HTML-страницу.

Все остальные классы НУЖНЫ парсер, потому что без него они не работают.

У меня 2 режима:

  1. Внутри CMS
  2. за пределами CMS

Внутри CMS

Если внутри CMS, пользовательские данные и другие дополнительные данные загружены в класс.

Вне CMS

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


модули

страница может быть использована для отображения данных/элементов по умолчанию, но он также может быть использован для отображения данных из модуля (например, страницы каландра). Если это случай, дополнительные данные должны быть загружены в объект синтаксического анализатора, и, таким образом, у меня есть 4 различных вариантов использования:

  1. режим анализатора
  2. режим cmsParser (внутри CMS)
  3. режим moduleParser (Синтаксический анализатор с данными модуля загружен)
  4. режим cmsModuleParser (оба)

у меня есть следующие [чрезвычайно упрощенный] классы:

class parser { 
    protected $oDataSource1; 
    protected $oDataSource2; 
    protected $oDataSource3; 

    //... 
    public function filterData() { 
     //.. Search through the data sources and return filtered data 
    } 
} 

class cmsParser extends parser { 
    protected $sUser_name; 
    protected $iUser_id; 
    protected $sUserLanguage; 

    ///.. some functions here that are called only within the CMS 
} 

class moduleParser extends parser { 
    protected $mModuleData; 
    //.. Do something with this moduleData; 
} 

class cmsModuleParser extends ?? { 
    //... Get functions from the cmsParser + module functions 
} 

Единственное решение, которое я могу придумать, - использовать черту, которую используют модульParser и cmsModuleParser? Это не оптимальная ИМО, потому что мне все еще нужно добавлять повторяющиеся переменные и т. Д.

Я не хочу дублировать код, конечно, так как решить эту загадку?

+0

Любая причина, по которой парсер загружает данные в себя и не просто возвращает объект данных, который может использоваться другими классами? Это позволит вам просто передать парсер-экземпляр любому классу, который ему нужен, и позволить ему анализировать столько вещей, сколько нужно для этого класса. – Erik

+0

Основная причина использования класса парсера - инкапсулировать данные и иметь центральную точку для получения моих данных в последующих точках процесса синтаксического анализа. Вы можете включать фрагменты PHP на странице, и, сохраняя все данные в классе парсера, я сразу же знаю, что я могу или не могу использовать. – Abayob

+0

Вы можете расширить класс, но реализовать несколько классов. Возможно, вам стоит попробовать использовать интерфейсы. –

ответ

1

Слышали ли вы, что фраза пользуется композицией над наследованием? Иногда композиция оплачивала бы больше, чем Наследование. В этом случае, cmsModuleParser extends cmsParser, а затем вводит moduleParser через конструктор в качестве зависимости. Однако у вас также есть getter и setter для $moduleParser. Поэтому, если вам не нужно вводить его через конструктор, вы все равно можете удалить его из конструктора и вместо этого использовать метод доступа setModuleParser().В качестве альтернативы вы также можете запрограммировать на интерфейс. Ниже приведен код, который бы иллюстрировать оба понятия:

СОСТАВ

<?php 
     class parser { 
      protected $mData; 

      //... 
      public function filterData() { 
       //.. filter the data here and return it 
      } 
     } 

     class cmsParser extends parser { 
      protected $sUser_name; 
      protected $iUser_id; 
      protected $sUserLanguage; 

      ///.. some functions here that are called only within the CMS 
     } 

     class moduleParser extends parser { 
      protected $mModuleData; 
      //.. Do something with this moduleData; 
     } 

     // HERE YOU EXTEND THE cmsParser 
     // AND THEN USING DI, INCLUDE THE moduleParser 
     class cmsModuleParser extends cmsParser { 
      /** 
      * @var ModuleParser 
      */ 
      protected $moduleParser; 
      //... Get functions from the cmsParser + module functions 

      public function __construct(moduleParser $moduleParser) { 
      } 

      /** 
      * @return moduleParser 
      */ 
      public function getModuleParser() { 
       return $this->moduleParser; 
      } 

      /** 
      * @param moduleParser $moduleParser 
      * @return cmsModuleParser 
      */ 
      public function setModuleParser($moduleParser) { 
       $this->moduleParser = $moduleParser; 

       return $this; 
      } 

     } 

ПРОГРАММИРОВАНИЕ НА INTERFACE

<?php 
     interface iParser{ 
      public function filterData(); 
      public function renderView(); 
      public function saveData(); 

     } 

     class parser implements iParser{ 
      protected $mData; 

      //... 
      public function filterData() { 
       //.. filter the data here and return it 
      } 

      public function renderView(){} 
      public function saveData(){} 
     } 

     class cmsParser extends parser { 
      protected $sUser_name; 
      protected $iUser_id; 
      protected $sUserLanguage; 

      ///.. some functions here that are called only within the CMS 
     } 

     class moduleParser extends parser { 
      protected $mModuleData; 
      //.. Do something with this moduleData; 
     } 


     class cmsModuleParser implements iParser { 
      //... Get functions from the cmsParser + module functions 

      public function __construct() { 
      } 

      public function filterData(){} 
      public function renderView(){} 
      public function saveData(){} 

     } 
+0

Но moduleParser и cmsParser оба являются расширениями класса парсера. Не загружает ли этот дубликат в память? – Abayob

+0

@Abayob В этом случае вы можете просто удалить инъекцию на основе конструктора, а затем вручную вызвать 'setModuleParser' только тогда, когда это необходимо. Вот типичное доказательство фразы: * предпочитайте композицию над наследованием * .... Кроме того, вы можете решить не расширять класс, а затем использовать композицию для 'moduleParser' и' cmsParser'. Таким образом, ваш класс 'cmsModuleParser' ** составлен ** из обоих классов, но не наследуется ни от одного из них. Другой способ - «Программирование на интерфейсы» – Poiz

0

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

Наследование является чем-то вроде A is a B. То есть, все ваши классы IS CmsParser. Это, конечно, неправильно и вызовет такие проблемы, о которых вы говорите. Есть много примеров, когда Наследование является полезным как

  • Женщина является человек
  • Toyota является автомобиль
  • PageController является контроллером (более общий сценарий в приложениях MVC )

Но наследование например

  • Автомобиль - это двигатель
  • Женщины является Leg
  • cmsModuleParser является PARSER

не хороший дизайн и вопрос очевиден.

Итак, как вы можете решить вашу проблему? Подходит для Car кейс. Сначала определим класс автомобиля

class Car extends Engine{ 

    public function reverse(){ 
    $this->startEngine();//Parent's method. 
    ..... 
    } 

вместо вышесказанного можно сделать что-то вроде этого

class Car{ 
protected $Engine; 
protected $Driver; 

public function __construct($Engine, $Driver){ 
$this->Engine = $Engine; 
$this->Driver = $Driver; 
} 

public function reverse(){ 
$this->Engine->start(); 
$this->Driver->LookBehindYou(); 
... 
} 

} 

С этого пути с помощью инъекции contstructor вы имеете слабую связь между вашим depedencies и у вас есть лучший дизайн.

Поиск в Google о Depedency Injection и состава по наследству consepts.

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