Php, это отвратительное решение? Выполнение всех методов начинается со строки

#php

#php

Вопрос:

 class Processer
{
    private function processChat() { }
    private function processUsers() { }
    private function processBuys() { }
    private function processOrders() { }
}
  

Обычно я бы использовал это:

 public function do()
{
    $this->processChat();
    $this->processUsers();
    $this->processOrders();
}
  

но легко забыть вызвать новую функцию (поскольку я намеренно пропустил processBuys() метод).

Если я проведу рефакторинг таким образом:

 public function do()
{
    foreach (get_class_methods($this) as $m)
    {
        if (substr($m, 0,7) == 'process')
        {
            $this->$m();
        }
    }
}
  

это работает, но кажется уродливым (например, невыполнимым в Java)

Комментарии:

1. Это можно было бы сделать и на Java, хотя, вероятно, это не было бы хорошим решением. В конечном итоге вы пытаетесь найти функциональное решение для программирования, для которого Java не была разработана (во всяком случае, до Java 8). Как есть, этот вопрос основан на мнениях (и, следовательно, не по теме), поэтому я бы реорганизовал его, чтобы получить ответы, основанные на большем количестве фактов.

2. Это выполнимо в java с использованием отражения. Если вы не пишете фреймворк или обычный код, я бы не советовал этого делать. Порядок выполнения методов, который не был бы запрограммирован, может вызвать проблемы.

3. вопрос о реализации того же самого в java?

4. нет, я эксперт по php и очень новичок в Java. Я просто привел пример, потому что думал, что это невыполнимо на Java (оказалось, это возможно, но тем же отвратительным способом 🙂

5. Я голосую за закрытие этого вопроса как не по теме, потому что он лучше подходит для codereview.stackexchange.com (где он получит удар).

Ответ №1:

Это определенно уродливое решение. Вызывайте методы явно или реорганизуйте свой код.

легко забыть вызвать новую функцию

Я не согласен. Никто не должен ожидать, что недавно добавленный метод будет автоматически вызван по умолчанию. Кроме того, если кто-то модифицирует существующий код, не поняв сначала, как он работает, это будет не единственное, в чем они могут ошибиться.


Что касается ваших вариантов дизайна — почему один класс обрабатывает как «чат», так и «заказы»? Я предлагаю перенести логику в отдельные классы:

(Это всего лишь пример того, как это можно реализовать, не прибегая к магии.)

 interface Process
{
    function execute();
}

class Processor
{
    private $processes;

    function addProcess(Process $process)
    {
        $this->processes[] = $process;
    }

    function process()
    {
        foreach ($this->processes as $process) {
            $process->execute();
        }
    }
}

class ChatProcess implements Process { function execute() { echo "Executing chatn"; } }
class UsersProcess implements Process { function execute() { echo "Executing usersn"; } }
class PurchasesProcess implements Process { function execute() { echo "Executing purchasesn"; } }
class OrdersProcess implements Process { function execute() { echo "Executing ordersn"; } }

// test
$processor = new Processor();

$processor->addProcess(new ChatProcess());
$processor->addProcess(new UsersProcess());
$processor->addProcess(new PurchasesProcess());
$processor->addProcess(new OrdersProcess());

$processor->process();
  

Вывод:

 Executing chat
Executing users
Executing purchases
Executing orders
  

Комментарии:

1. да, кажется, это круто — исходите из того факта, что это увеличивает сложность и требует больше классов