Попытка повторно использовать код, но не может расширить два класса, альтернатива?

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

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

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

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

  1. Внутри CMS
  2. Вне CMS

Внутри CMS

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

Вне 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
}

Единственное решение, которое я могу придумать, это использовать черту, которую используют moduleParser и cmsModuleParser?
Это не оптимальное IMO, потому что я все еще должен добавить дубликаты переменных и т. Д.

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

-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;
}

}

ПРОГРАММИРОВАНИЕ В ИНТЕРФЕЙС

    <?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(){}

}
1

Другие решения

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

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

  • Женщина человек
  • Тойота это Автомобиль
  • PageController — это контроллер (более распространенный сценарий в MVC
    Приложения)

Но наследство вроде

  • Автомобиль — это двигатель
  • Женщина — это нога
  • 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, вы получаете слабую связь между вашими зависимостями и получаете лучший дизайн.

Поиск в Google о Инъекция зависимости а также Композиция по наследству consepts.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector