Интерфейсы позволяют более четко разграничивать обязанности. Например:
PHP:
interface IActionValidator {
function validateAction(IMarsProtoAction $action);
}
interface PaymentSystemOperator {
function payout(PayoutRequest $request);
function testInvoice(PayoutRequest $request);
}
те кто имплементируют эти методы могут быть в виде одного или двух классов, в зависимости от необходимости. А тем, кто используют классы с этими интерфейсы абсолютно по барабану, что там имплементируется кроме того, что требуется для работы. Главное - они могут затребовать тот интерфейс, который им нужен.
PHP:
class RegisterExchangeActionHandle implements IMarsProtoActionHandle {
public function execute(IMarsProtoAction $action){
$action = new RegisterExchangeAction($action);
if ( ($result = System::getInstance()->getPaymentSystemFactory()
->validateAction($action)) !== null )
{
return $result;
}
$payout = ...
$result = new RegisterExchangeResult();
$result->sayApproved();
return $result;
}
}
class PayoutProcessor {
public function run($callbackUrl){
$request = $this->_getPayoutRequests();
$factory = System::getInstance()->getPaymentSystemFactory();
while ( $request->next() ){
$skip = false;
try {
$inPaymentSys = $factory->get($request->in_currency);
$outPaymentSys = $factory->get($request->out_currency);
}catch( Exception $e ){
$request->status = PayoutRequest::STATUS_ERROR;
$skip = true;
}
if ( !$skip ){
if ( $inPaymentSys->testInvoice($request) ){
$request->status = $outPaymentSys->payout($request) ?
PayoutRequest::STATUS_COMPLETED :
PayoutRequest::STATUS_DECLINED;
}else{
$request->status = PayoutRequest::STATUS_QUEUE;
}
}
$request->save();
}
$balanceController = new AccountBalanceController();
$balanceController->run($callbackUrl);
}
}
В конечном итоге не важно что мы реализуем в классе. Абстрактный класс это почти реализация. Интерфейс - это далеко не реализация.