Има случаи, в които е по-добре да използваме обекти вместо примитивни типове. Нека погледнем следният пример:
Имаме клас User в който подаваме дадено пропърти, например $url като стринг и също, преди да го сетнем, правим някаква примерна валидация.
class User { private string $url; public function setUserUrl(string $url) : void { if (false === filter_var($url, FILTER_VALIDATE_URL)) { throw new SomeValidationException('Wrong url bla bla bla...'); } $this->url = $url; } public function getUserUrl() : string { return $this->url; } // ... }
На пръв поглед всичко е доста просто.
Но първото, което не е ОК, е че валидацията на URL-a e в класа User. Не нарушаваме ли Sigle Responsibility SOLID принципът?
Също, ако трябва да подадем URL и на друг клас, там също трябва да я има тази валидация – повтаряне на код.
Да не говорим, че ако подаваме така, по отделно, може да имаме „експлозия от входни параметри“ ако се наложи да подаваме и други стойности.
Няма ли да е по-елегантно и гъвкаво ако създадем нов клас Url и там да изнесем валидирането и евентуално друга логика, свързана с Url-и. И където ни трябва, просто да инджектваме обект от класа Url?
T.н. „Replace Data Value with Object “ техника за рефакториране.
class User { private string $url; public function setUserUrl(Url $url) : void { $this->url = $url; } public function getUserUrl() : string { return $this->url->getUrlAddress(); } // ... } class Url { private string $url; public function __construct(string $url) { if (false === filter_var($url, FILTER_VALIDATE_URL)) { throw new SomeValidationException('Wrong url bla bla bla...'); } $this->url = $url; } public function getUrlAddress() : string { return $this->url; } // ... }
Вижда се, че Primitive Obsession трябва да се избягва, когато не просто използваме примитивни типове за някаква стойност, но трябва и да имаме някаква логика, на която тези примитивни стойности да се подчиняват.
Добър пример би бил ако например искаме да имаме пропърти $age за даден User, но също и трябва да я използваме тази възраст само за живи хора, а не и за например исторически личности, за които възрастта може да е стотици години.
Тогава не може просто да подаваме произволен, положителен integer.
Литература:
https://dzone.com/articles/code-quality-fighting-primitive-obsession-code-sme-1