Здравствуйте. Подскажите как правильно соотнести например, получаемую Строку извне строку и Класс
и при этом выполнить Принцип открытости/закрытости из SOLID?
Например, извне я получаю строку
$animal_type="cat" и должен вызвать метод
say() класса
Cat;
Первый вариант: через оператор switch
class Human {
public function touchAnimal($animal_type)
{
switch ($animal_type) {
case 'dog':
$animal = new Dog();
break;
case 'cat':
$animal = new Cat();
break;
}
$animal->say();
}
}
Второй вариант: массив соответствий
class Human {
$home_animals = [
'dog' => Dog::class,
'cat' => Cat::class,
];
public function touchAnimal($animal_type)
{
$animal = new $this->home_animals[$animal_type]();
$animal->say(); // IDE не знает объектом какого класса является переменная и не подсказывает
}
}
Третий правильный вариант:
class Human {
public function touchAnimal($animal: VoiceAnimal) // или интерфейс IVoiceAnimal
{
$animal->say();
}
}
В третьем случае мы выносим логику соотношения наверх, за пределы класса и выполняем принцип.
Но наверху всё равно надо будет делать этот выбор
switch, в каком-нибудь другом классе и уже там нарушать принцип открытости/закрытости.
Как правильно сделать в данном случае?
Просто содержимое классовclass VoiceAnimal
{
public $sound = '';
public function say()
{
print_r('Animal says: ' . $this->sound);
}
}
class Dog extends VoiceAnimal
{
public $sound = 'GAV-GAV';
public function say()
{
print_r('DOG SAY: ' . $this->sound);
}
}
class Cat extends VoiceAnimal
{
public $sound = 'MYAU';
public function say()
{
print_r('CAT SAY: ' . $this->sound);
}
}