Developers/Object oriented programming in PHP/Classes/ru

Зачем вместо функций использовать классы?
Большое преимущество классов в том, что для методов классов не нужно предоставлять данные в виде параметров. Метод сам "знает", какие данные, например, объекты, ему принадлежат. В то время как для функций все данные, которые она обрабатывает, должны быть предоставлены в виде параметров. Тем не менее, можно определить методы принимающие параметры для настройки обработки свойств объектов или чего-то ещё.

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

Как дополнить классы
В общем, дополнение классов применяется для добавления функционала к наследуемому классу или для изменения существующего функционала суперкласса, производя новый класс из родительского.

Каждый класс может дополнить лишь один родительский класс. Для класса недопустимо быть произведённым из нескольких родительских классов.

Использование в Arcavias:

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

Пример:

Взгляните на заголовок следующих классов, все они выстраивают "цепочку наследования" от суперкласса к субклассу.

MShop_Product_Item_Default <- MShop_Common_Item_ListRef_Abstract <- MShop_Common_Item_Abstract <- MW_Common_Item_Abstract

Смотрите также:


 * http://php.net/manual/en/language.oop5.basic.php -> extends

Какие общие правила относительно субклассов?
Для дополнения классов применимы следующие правила:


 * Один класс может дополнять лишь один родительский класс. Класс не может быть наследником нескольких классов.
 * Методы, передаваемые в субклассы и переопределяемые ими должны иметь ту же область видимости (public или protected), как и в родительских классах.
 * В классе все public / protected свойства / методы суперкласса видимы, то есть могут быть использованы в субклассе без необходимости их определения заново. Также, все свои свойства / методы, включая декларируемые как private видимы, но, конечно, должны быть сначала определены.
 * При помощи оператора :: (оператор разрешения области или двойное двоеточие) возможно добраться до переназначенных методов не прямых суперклассов в определениях класса:.
 * parent:: ссылка на методы непосредственного родительского класса:.
 * Константы и статические методы / свойства также могут быть вызваны при помощи оператора :::  или  . Ключевые слова self::</tt> и parent::</tt> также доступны. Но parent::</tt> следует в этом контексте избегать.

Смотрите также:


 * http://php.net/manual/en/language.oop5.basic.php -> extends
 * http://php.net/manual/en/language.oop5.paamayim-nekudotayim.php

Как спроектировать "хорошие" классы и писать хорошо структурированный код
Общие правила:


 * Разбивайте код на значимые части функционирования.
 * Создавайте классы для повторно используемого кода.

Каждый класс должен выполнять лишь одну задачу

 * Один ресурс.
 * Несколько методов, управляющих этим ресурсом.
 * Отсутствие слишком больших классов.

Пример в Arcavias:

MW_Logger_Zend</tt> является хорошим примером класса, обрабатывающего один ресурс. MW_Logger_Zend</tt> отвечает за внесение записей в журнал и является единственным классом, управляющим ресурсом Zend_Log</tt>:

Композиция лучше дополнения

 * Не создавайте для всех целей один "корневой класс" со множеством субклассов, дополняющих друг-друга.
 * Вместо этого пишите несколько классов, параллельно друг-другу, начиная от корня или того же иерархического уровня.
 * Используйте классы в других классах.
 * Создавайте объекты управления классами для других классов.
 * Подумайте об использовании шаблонов проектирования.

Сравнение композиции и наследования:
 * Класс A имеет m</tt> возможностей что-то сделать.
 * Класс B имеет n</tt> возможностей что-то сделать.
 * Максимальное количество возможностей что-то сделать, используя один родительский класс A и непосредственный его субкласс B равно m + n</tt>.
 * Максимальное количество возможностей что-либо сделать, используя два параллельных класса A и B, стоящих на том же иерархическом уровне уже m x n</tt>.

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

Пример в Arcavias:

MShop_Catalog_Item_Default</tt> и MShop_Catalog_Manager_Default</tt> демонстрируют работу композиции:

Объект элемент каталога (catalog item) содержит узел каталога (node) и его потомков, посредством свойств _node</tt> и _children</tt>. Элемент (item) содержит методы, относящиеся только к своим методам (в основном методы setter и getter). Но менеджер каталога заботиться обо всех необходимых действиях, это стандартные для менеджера действия по созданию, сохранению, поиску, удалению элемента, и специфичные для домена, вроде перемещения или вставки узла дерева каталога, или получения всех узлов каталога, лежащих на пути к определённому узлу. Элемент и менеджер выражают шаблон проектирования DAO / DTO.

Далее: свойства >>