Каждый раз, когда я гугляю instanceof и читаю, я всегда вижу ответы, в которых говорится, что нужно избегать этого и использовать шаблон X.
У меня есть пример, в котором я не вижу ни одного шаблона, который, как мне кажется, мог бы использовать.
У нас есть 2 класса: Order и Payment (CashPayment и CardPayment).
CashPayment имеет 1 свойство с именем amount
и реализованный метод pay
.
CardPayment имеет 1свойство с именем cardNumber
и внедренный pay
, который вызывает сторонний API.
Теперь скажем, что вы хотите составить представление о Заказе, как бы кто-то не использовал instanceof или приведение здесь для отображения деталей платежа?
С instanceof я могу сделать это:
order = new Order(...);
order.checkout(aPayment);
Payment Details (Cash):
Type: (instanceof CashPayment ? "Cash") or order.payment().type();
Amount: ((CashPayment) order.payment()).amount();
Payment Details (Card):
Type: (instanceof CardPayment ? "Card") or order.payment().type();
Card Number: ((CardPayment) order.payment()).cardNumber();
Вопрос : можем ли мы действительно избежать instanceof и кастинга?Если да, то как мы можем достичь этого "OO-way"?Если нет, я предполагаю, что это один из действительных случаев?
IMO, мы можем избежать instanceof / casting и одобрить использование переопределенных методов, однако, если вы хотите знать о конкретном объекте, этого нельзя избежать.
Редактировать:
Я пытаюсь написать свои доменные модели, что означает, что он не зависит от инфраструктуры и конкретных приложений.
Представьте, что нам нужноДля сохранения Заказа через OrderRepository и Платеж есть свои таблицы.Разве это не было бы ужасно, если бы это было похоже на
class OrderRepository {
public function save(Order order) {
// Insert into order query here...
// Insert into orderItems query here...
// Insert payment into its table
queryBuilder
.table(order.payment().tableName())
.insert([
order.payment().columnName() => order.payment().value()
]);
}
}