kernel panic

быдлокодю, дорого, интим не предлагать!

Множественное наследование на PHP

Вернуться

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

Если учесть, что я перешел на PHP с C++, то мне пришлось очень сильно пересмотреть то, как я проектирую архитектуру приложения.

Если в C++ утверждение, что любой набор методов, свойств, который повторяется для нескольких объектов, должен быть вынесен в отдельный класс было вполне верно, то в PHP это было труднореализуемо.

Как известно на PHP можно смешивать интерфейсы, но интерфейс несет лишь перечень методов, которые должны быть определены в финальном объекте. Тоесть всеравно приходилось писать дублирующий код.

И тут на помощь нам приходят трейты (traits). Трейты позволяют объединять код по группам, и после использовать, визуально это похоже на класс но на самом деле, это просто макрос который копирует код функций в нужное место, хотя это и покрывает требование убрать задублированность кода.

Тогда мне пришла идея, она конечно не нова, кто-то уже делал подобное. Создавая объект, который должен наследовать несколько свойств и методов, как обязать пользователя, указать все нужные методы. В итоге все достаточно просто.

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

Возможно не очень красиво, но зато работает.


interface iTest
{
function use1();
function use2();
};

trait tTest
{
function use1()
{
echo do some stuff;
}
};


class MyClass implements iTest
{
use tTest;


function use2()
{
$this->use1();
}
}


Сейчас идет обсуждение о возможности добавить использование интерфейсов при объявлении трейтов, это позволит не забыть включить нужные методы в трейты.

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

Тоесть в будущем будет работать примерно такой код


interface iTest
{
function use1();
};

interface iTest2
{
function use2();
};

trait tTest implements iTest1, iTest2
{
function use1()
{
echo do some stuff;
}

function use2()
{
$this->use1();
}

};


class MyClass
{
use tTest;


function use3()
{
$this->use1();
}
}