Skip to content

Instantly share code, notes, and snippets.

@cborgas
Last active October 17, 2021 07:56
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 cborgas/f305592323bf16beb1e7a8e2add72a3b to your computer and use it in GitHub Desktop.
Save cborgas/f305592323bf16beb1e7a8e2add72a3b to your computer and use it in GitHub Desktop.
Extract Methods, Extract Interface & Wrap Class
<?php
interface FrontDeskInterface
{
public function addMemberships(array $emailAddresses): void;
}
class FrontDesk implements FrontDeskInterface
{
public function __construct(
protected CustomerRepository $customerRepository,
protected WelcomeMessageSender $welcomeMessageSender,
protected CustomerMembershipManagerInterface $membershipManager
) {}
public function addMemberships(array $emailAddresses): void
{
$customers = $this->customerRepository->getCustomersByEmailAddresses(
$emailAddresses
);
$previousCustomers = [];
$newCustomers = [];
foreach ($customers as $customer) {
if ($this->membershipManager->hadMembership($customer)) {
$previousCustomers[] = $customer;
} else {
$newCustomers[] = $customer;
}
}
foreach ($newCustomers as $customer) {
$this->membershipManager->addMembership($customer);
$this->welcomeMessageSender->sendWelcomeMessage($customer);
}
foreach ($previousCustomers as $customer) {
$this->membershipManager->renewMembership($customer);
$this->welcomeMessageSender->sendWelcomeBackMessage($customer);
}
}
}
class LoggingFrontDesk implements FrontDeskInterface
{
public function __construct(
private FrontDesk $frontDesk,
private LoggerInterface $logger
) {}
public function addMemberships(array $emailAddresses): void
{
$this->logger->debug(sprintf('Adding memberships for %s', implode(', ', $emailAddresses)));
$this->frontDesk->addMemberships($emailAddresses);
}
}
interface MembershipManagerInterface
{
/**
* @throws RuntimeException
*/
public function addMembership(Customer $customer): void;
public function renewMembership(Customer $customer): void;
public function hadMembership(Customer $customer): bool;
}
class MembershipManager implements MembershipManagerInterface
{
/**
* @throws RuntimeException
*/
public function addMembership(Customer $customer): void
{
// ...
}
public function renewMembership(Customer $customer): void
{
// ...
}
public function hadMembership(Customer $customer): bool
{
// ...
}
}
class LoggingMemembershipManager implements MembershipManagerInterface
{
public function __construct(
private MembershipManagerInterface $membershipManager,
private LoggerInterface $logger
) {}
public function addMembership(Customer $customer): void
{
$this->logger->debug(sprintf('Adding membership for %s', $customer->getName()));
try {
$this->membershipManager->addMembership($customer);
$this->logger->debug(sprintf('Membership added for %s', $customer->getName()));
} catch (RuntimeException $exception) {
$this->logger->error(
sprintf('Failed to add membership for %s', $customer->getName()),
['exception' => $exception]
);
}
}
public function renewMembership(Customer $customer): void
{
$this->logger->debug(sprintf('Renewing membership for %s', $customer->getName()));
$this->membershipManager->renewMembership($customer);
}
public function hadMembership(Customer $customer): bool
{
return $this->membershipManager->hadMembership($customer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment