Рефакторинг: встраивание класса
Представим себе такую ситуацию, когда мы провели серию приемов рефакторинга и в результате оказалось, что от класса становится мало пользы, т.к. в нем осталось мало функций. Проблема, которая может быть решена с помощью сегодняшнего приема, - это устранение малого класса. Хотя это, конечно, не проблема. Но все же
Суть приема встраивания класса состоит в том, чтобы встроить имеющиеся функции нашего класса А в другой класс Б, который чаще всего использует функции класса А. Сам класс А при этом удалить.
Подробно я описывать процесс не буду. Приведу лишь небольшой пример, который далее можно разобрать самостоятельно.
Допустим у нас есть два класса - Person и PhoneNumber. При этом класс Person использует методы класса PhoneNumber:
class Person { private $_name; private $_officePhone; public function __construct() { $this->_officePhone = new PhoneNumber(); } public function GetName() { return $this->_name; } public function GetPhoneNumber() { return $this->_officePhone->GetPhoneNumber(); } public function GetOfficePhone() { return $this->_officePhone; } } class PhoneNumber { private $_number; private $_areaCode; public function GetPhoneNumber() { return '('.$this->_areaCode.') '.$this->_number; } public function GetAreaCode() { return $this->_areaCode; } public function SetAreaCode($arg) { $this->_areaCode = $arg; } public function GetNumber() { return $this->_number; } public function SetNumber($arg) { $this->_number = $arg; } }
Чтобы применить наш прием, сначала нужно добавить в класс Person методы из класса PhoneNumber:
class Person { … public function GetAreaCode() { return $this->_officePhone->GetAreaCode(); } public function SetAreaCode($arg) { $this->_officePhone->SetAreaCode($arg); } public function GetNumber() { return $this->_officePhone->GetNumber(); } public function SetNumber($arg) { $this->_officePhone->SetNumber($arg); } … }
После этого шага мы можем использовать код
$myPerson = new Person(); $myPerson->setAreaCode ("123");
вместо кода, который мы использовали бы раньше:
$myPerson = new Person(); $myPerson->getOfficePhone()->setAreaCode("123");
Таким образом, мы избавляемся от создания лишнего объекта (который на самом деле пока создается внутри класса Person).
А после этого шага мы можем спокойно применять такие приемы рефакторинга, как «Перемещение метода» и «Перемещение поля», о которых я расскажу в следующих постах.
Но и без их описания не трудно догадаться, что мы теперь можем выкинуть метод GetOfficePhone из класса Person, и можем переместить тела методов GetPhoneNumber, GetAreaCode, SetAreaCode, GetNumber, SetNumber. Но перед этим конечно нужно переместить внутренние поля _number и _areaCode класса PhoneNumber в класс Person. А затем мы можем смело удалить класс PhoneNumber, инициализацию поля _officePhone в классе Person и само поле _officePhone в классе Person.
В результате применения этих приемов класс PhoneNumber исчезнет совсем, чего мы и добивались, а класс Person станет таким:
class Person { private $_name; private $_number; private $_areaCode; public function GetName() { return $this->_name; } public function GetPhoneNumber() { return '('.$this->_areaCode.') '.$this->_number; } public function GetAreaCode() { return $this->_areaCode; } public function SetAreaCode($arg) { $this->_areaCode = $arg; } public function GetNumber() { return $this->_number; } public function SetNumber($arg) { $this->_number = $arg; } }
Думаю, это полезный прием очищения кода, который кому-нибудь обязательно пригодится
Такое может понадобиться только изночально при неправельной архитектуре проекта
По мне так статья бесполезная(
Если говорить про архитектуру, то не всегда удается с первого раза создать такую архитектуру, которая была бы идеальна для конкретного проекта. А то, что статья бесполезная - это Ваше субъективное мнение.
У класса Person метод setAreaCode не совсем понятен. Если же # $myPerson->getOfficePhone()->setAreaCode(“123″) вот так делаем, то понимаем, что устанавливаем код для телефона. Каждый класс и объект этого классы занимается теми вещами, которые ему присущи. Смотрите антипаттерн - Божественный объект.
Нормальная статья. Насчет правильной архитектуры, построить такую сразу не реально, поэтому и есть реффакторинг.