Skip to content

Instantly share code, notes, and snippets.

@Great-Antique
Last active October 27, 2017 18:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Great-Antique/8e22d4778ad72c550a59307958f04518 to your computer and use it in GitHub Desktop.
Save Great-Antique/8e22d4778ad72c550a59307958f04518 to your computer and use it in GitHub Desktop.
What is the difference between Service Locator and class with 2+ methods?
<?php
/*
*
* What is the difference between Service Locator and class with 2+ methods?
*
*/
// We have class with two methods
class InvoiceService implements InvoiceServiceInterface
{
private $invoiceSender;
private $invoiceGenerator;
public function __construct(InvoiceSenderInterface $invoiceSender, InvoiceGeneratorInterface $invoiceGenerator)
{
$this->invoiceSender = $invoiceSender;
$this->invoiceGenerator = $invoiceGenerator;
}
// This method is unit of logic that we need to run
public function sendInvoice(Payment $payment)
{
$this->invoiceSender->send($payment->getInvoice());
}
public function createInvoiceForPayment(Payment $payment)
{
$invoice = $this->invoiceGenerator->generate($payment);
$payment->setInvoice($invoice);
$payment->save();
}
}
// We use service locator to get (as we think) some service (unit of logic) to run logic (send invoice)
class PaymentService
{
private $serviceLocator;
public function __construct(ServiceLocator $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function capturePayment(Payment $payment)
{
$payment->setCaptured();
$payment->save();
$this->serviceLocator->get(InvoiceServiceInterface::class)->sendInvoice($payment);
}
}
// We use class with 2 methods to do the same
class OtherPaymentService
{
private $invoiceService;
public function __construct(InvoiceService $invoiceService)
{
$this->invoiceService = $invoiceService;
}
public function capturePayment(Payment $payment)
{
$payment->setCaptured();
$payment->save();
$this->invoiceService->sendInvoice($payment);
}
}
// But in fact we use that class as service locator for real service (unit of logic) - THE METHOD
class OtherPaymentServiceForShowingProblem
{
private $invoiceService;
public function __construct(InvoiceService $invoiceService)
{
$this->invoiceService = $invoiceService;
}
public function capturePayment(Payment $payment)
{
$payment->setCaptured();
$payment->save();
// get unit of logic that we want to run by method name and run it
$unitOfLogic = $this->invoiceService->getMethod('sendInvoice');
$unitOfLogic($payment);
// ^^^ Here above we are using class with 2 methods as service locator (unit of logic locator)
// And by doing it we inject hidden unused dependency - second method of that class
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment