Скажи не спрашивай
В объектно-ориентированном программировании TDA (Tell Don’t Ask) означает указание объекту выполнить действие, а не запрашивать информацию и выполнять действия от имени объекта.
Одна из фундаментальных идей ООП — связать воедино поведение и данные. Когда класс обслуживания запрашивает информацию у объекта и выполняет над ним операции, это приводит к разделению поведения и данных, при этом поведение реализуется в классе обслуживания, а данные остаются в объекте.
Поведение и данные лучше всего тесно связаны, потому что они обычно меняются вместе и по одной и той же причине. Это также отделяет объект от клиента, позволяя ему сосредоточиться на выполнении операций и поддержании достоверности своего состояния. Между тем, клиент может обрабатывать логику приложения, взаимодействие между объектами и связь с другими уровнями. Такое разделение задач обеспечивает удобство сопровождения системы в долгосрочной перспективе.
Пример
Давайте подумаем о реальном сценарии. В ресторанах официанты обычно говорят клиентам оплачивать счета, а не просят предъявить их кошельки и берут у них наличные. В последнем случае клиент не может быть уверен, сколько наличных было снято с его кошелька. Это может привести к проблемам, потому что клиент несет ответственность за управление деньгами в своем кошельке.
Реализация запроса кошелька будет следующей.
type Wallet = { cash: number }; class Customer { private wallet: Wallet = { cash: 100 }; public getWallet(): Wallet { return this.wallet; } public setWallect(wallet: Wallet): void { this.wallet = wallet; } } class PayBillService { public handle(paymentAmount: number): void { const customer = new Customer(); const wallet: Wallet = { cash: customer.getWallet().cash - paymentAmount }; customer.setWallect(wallet); } } new PayBillService().handle(10);
Реализация сообщения клиенту об оплате счета будет следующей.
type Wallet = { cash: number }; class Customer { private wallet: Wallet = { cash: 100 }; public pay(paymentAmount: number) { this.wallet.cash -= paymentAmount; } } class PayBillService { public handle(paymentAmount: number): void { const customer = new Customer(); customer.pay(paymentAmount); } } new PayBillService().handle(10);
Статьи по Теме
Искусство энбаггинга Энди Ханта и Дэйва Томаса
https://media.pragprog.com/articles/jan_03_enbug.pdf
TellDontAsk, Мартин Фаулер