Imagine a class is a person working in an office. Coupling is how many other people they need to talk to in order to do their job.
If a worker needs to constantly bother the Accountant, the Manager, the Janitor, and the CEO just to send an email, they are tightly coupled to everyone else. If any of those people change how they work, our worker breaks!
Coupling Between Objects (CBO) counts exactly how many distinct external classes your class knows about. We count a class if you:
new.Logger::info().Exception.If your score gets too high (default > 10), your class is too dependent on the rest of the system.
This class has to know about 6 different external classes just to process a refund!
// Knows about: BaseService, AuditableService, UserRepository, PaymentGateway,
// Mailer, Logger, EventBus, Order, PaidOrder, StripeRefund, RefundReceipt,
// GatewayException, CannotRefundOrder (Score: 13)
class OrderService extends BaseService implements AuditableService
{
private UserRepository $users;
private PaymentGateway $payments;
private Mailer $mailer;
public function __construct(Logger $logger, EventBus $events) {}
public function refund(Order $order): RefundReceipt
{
if ($order instanceof PaidOrder) {
StripeRefund::create($order);
}
try {
return new RefundReceipt();
} catch (GatewayException $exception) {
throw new CannotRefundOrder();
}
}
}
Split responsibilities so each class only talks to the few collaborators it actually needs.
class RefundService
{
public function __construct(
private PaymentGateway $payments,
private RefundReceiptFactory $receipts,
) {}
public function refund(Order $order): RefundReceipt
{
// Much simpler! Only knows about PaymentGateway, RefundReceiptFactory,
// Order, and RefundReceipt.
$this->payments->refund($order);
return $this->receipts->createFor($order);
}
}
rules:
E0017:
max_coupling: 10
If Phanalist flags your class for high CBO, it means your class has its fingers in too many pies. Try to split it into smaller classes, or pass in simple data (like arrays or strings) instead of entire objects.