01/09/2017 - PHP
Classlar concretion yerine, abstraction tiplerine bağımlı olmalıdırlar. Daha fazla ayrıntıya girmek istersek, bir (üst seviye modül) class concretion (alt seviye modül) tipleri yerine, abstraction tiplerine bağımlı olmalıdırlar. Başka bir deyişle, üst seviye modülller hiç bir zaman değişmemeliler ve her an değişebilen alt seviye modüllerine gevşekçe bağlı olmalıdırlar.
# VIOLATION
class Publisher
{
private $twitter;
public function __construct(Twitter $twitter)
{
$this->twitter = $twitter;
}
public function publish()
{
return $this->twitter->getComment();
}
}
class Twitter
{
private $comment;
public function setComment(string $comment)
{
$this->comment = $comment;
}
public function getComment(): string
{
return $this->comment;
}
}
$twitter = new Twitter();
$twitter->setComment('Twitter comment');
$publisher = new Publisher($twitter);
echo $publisher->publish();
Yukarıda gördüğümüz gibi, üst seviye modül olan Publisher
class, alt seviye modül olan Twitter
classa sıkıca bağımlı görünüyor. Bu nedenle sadece Twitter
objesini kabul ediyor. Eğer Facebook yorumlarını da yayınlamak istersek, Publisher
classını değiştirmemiz gerekecektir, ki bu da prensip ihlalidir. Ayrıca eğer Twitter
classında değişiklik yaparsak, muhtemelen Publisher
classında da değişiklik yapmamız gerekecektir, ki bu da prensip ihlalidir.
# REFACTORED
class Publisher
{
private $socialMedia;
public function __construct(SocialMediaInterface $socialMedia)
{
$this->socialMedia = $socialMedia;
}
public function publish()
{
return $this->socialMedia->getComment();
}
}
interface SocialMediaInterface
{
public function setComment(string $comment);
public function getComment(): string;
}
class Twitter implements SocialMediaInterface
{
private $comment;
public function setComment(string $comment)
{
$this->comment = $comment;
}
public function getComment(): string
{
return $this->comment;
}
}
class Facebook implements SocialMediaInterface
{
private $comment;
public function setComment(string $comment)
{
$this->comment = $comment;
}
public function getComment(): string
{
return $this->comment;
}
}
$twitter = new Twitter();
$twitter->setComment('Twitter comment');
$publisher = new Publisher($twitter);
echo $publisher->publish();
$facebook = new Facebook();
$facebook->setComment('Facebook comment');
$publisher = new Publisher($facebook);
echo $publisher->publish();
Yukarıda gördüğümüz gibi, Twitter
ve Facebook
classlarının kullanması için SocialMediaInterface
yarattık. Çalışma prensibini kırmadan her iki objeyi de Publisher
class içine enjekte edebiliriz. Eğer daha fazla sosyal medya classı yaratıp yorumları yayınlamak istersek, tüm yapmamız gereken yeni classın da SocialMediaInterface
kullanmasını sağlamamız yeterli olacaktır.