Я ищу, чтобы привести в порядок некоторый код, который я унаследовал. По сути, у нас есть два класса (A + B), которые расширяют два отдельных класса, которые выполняют разные функции по-разному, однако A и B также разделяют некоторые функции. В настоящее время функции копируются и вставляются между ними, и, очевидно, я знаю, что это неправильно. Я смотрю, есть ли решение для этого, так что мне нужно определить функции только один раз, чтобы и A, и B могли использовать их. Любая помощь будет отличной!
С php 5.4 вы можете использовать Черты.
Вот пример из руководства
<?php
trait ezcReflectionReturnInfo {
function getReturnType() { /*1*/ }
function getReturnDescription() { /*2*/ }
}
class ezcReflectionMethod extends ReflectionMethod {
use ezcReflectionReturnInfo;
/* ... */
}
class ezcReflectionFunction extends ReflectionFunction {
use ezcReflectionReturnInfo;
/* ... */
}
?>
В идеальном мире вполне возможно, что вам действительно нужно множественное наследование, но это не поддерживается PHP (или многими другими языками), поскольку оно намного сложнее, чем одиночное наследование.
Одна альтернатива, которую стоит рассмотреть, — это упорядочить ваш код так, чтобы оба класса в конечном итоге наследовали от какого-то общего предка, чтобы вы могли разместить свой код здесь. Однако это не всегда может быть желательным или практичным, особенно если некоторые из расширенных классов взяты из разных библиотек без общей зависимости.
Вы можете изменить происхождение некоторых из ваших классов, используя «состав» и «делегирование», а не прямое наследование. Основная идея заключается в том, что вместо класса B, расширяющего класс A, вы сохраняете экземпляр класса A как свойство класса B; когда вызываются определенные методы класса B, они вызывают соответствующие методы экземпляра A, в то время как другие методы B полностью отделены и могут наследоваться откуда-то еще. магический метод __call может быть полезным для реализации этого без необходимости заранее знать все возможные делегированные методы.
Начиная с PHP 5.4, существует форма «горизонтальное повторное использование кода», называемое чертами. Черты иногда описываются как «копирование и вставка с помощью компилятора», потому что они не представляют каких-либо ООП-отношений между классами, в которых они используются, а лишь способ редактирования функций в одном месте.
Если функции общедоступны, вы можете объявить классы как реализующие интерфейс, который позволяет другому коду проверять, что набор методов доступен, обычно с помощью instanceof
оператор. Это может быть использовано в сочетании с Чертой, которая содержит детали как эти методы реализованы.