Вы можете использовать своего рода «шаблон стратегии» для улучшения своего кода, создавая некоторые службы для обработки вычисления цвета для каждого типа сообщения (каждой стратегии), а затем одну службу «делегатора», которая решает, какую службу вызов на основе типа сообщения ...
Для начала вам нужен интерфейс для всех ваших калькуляторов:
interface ColorCalculatorInterface
{
public function calculateColor(Message $message);
public function getSupportedMessageType();
}
Тогда один сервис для каждой стратегии:
class InfoColorCalculator implements ColorCalculatorInterface
{
public function getSupportedMessageType()
{
return 'info';
}
public function calculateColor(Message $message)
{
// lots of code here!
return 'blue';
}
}
class WarningColorCalculator implements ColorCalculatorInterface
{
public function getSupportedMessageType()
{
return 'warning';
}
public function calculateColor(Message $message)
{
// lots of code here!
return 'yellow';
}
}
// More calculators...
class DefaultColorCalculator implements ColorCalculatorInterface
{
public function getSupportedMessageType()
{
return 'default';
}
public function calculateColor(Message $message)
{
// lots of code here!
return 'grey';
}
}
И, наконец, один сервис, который решает, какую стратегию использовать, основываясь на типе сообщения (этот код может быть непосредственно в контроллере, но он чище как отдельный сервис):
class ColorCalculator
{
private $calculators = [];
private $defaultCalculator;
public function setDefaultColorCalculator(ColorCalculatorInterface $calculator)
{
$this->defaultCalculator = $calculator;
}
public function registerColorCalculator(ColorCalculatorInterface $calculator)
{
$this->calculators[$calculator->getSupportedMessageType()] = $calculator;
}
public function calculateColor(Message $message)
{
if (array_key_exists($message->getType(), $this->calculators)) {
$calculator = $this->calculators[$message->getType()];
} else {
$calculator = $this->defaultCalculator;
}
return $calculator->calculateColor($message);
}
}
Теперь ваш контроллер намного тоньше!
class MessageController extends Controller
{
/** @var ColorCalculator */
private $calculator;
public function show(Message $message)
{
$color = $this->calculator->calculateColor($message);
// do what you want with your color...
}
}
Заметьте, я не разработчик Laravel, а разработчик Symfony! Я предполагаю, что Laravel предоставляет какой-то способ определить службу делегата и зарегистрировать в ней все калькуляторы, и, наконец, внедрить эту службу в контроллер ... (Symfony делает)