前段时间我有完全相同的问题!
我遇到的问题是,每当我偶然发现此问题时,我就会发现我还没有发现一些隐藏的概念。这个概念很可能应该用一些价值对象来表达。您有一个非常抽象的示例,因此恐怕无法证明使用您的代码的含义。但是,这是我个人的做法。我有两个类,它们代表了一种将请求发送到外部资源并解析响应的方法。请求的形成方式和响应的解析方式存在相似之处。这就是我的层次结构:
abstract class AbstractProtocol
{
    /**
     * @return array Registration params to send
     */
    abstract protected function assembleRegistrationPart();
    /**
     * @return array Payment params to send
     */
    abstract protected function assemblePaymentPart();
    protected function doSend(array $data)
    {
        return
            (new HttpClient(
                [
                    'timeout' => 60,
                    'encoding' => 'utf-8',
                    'language' => 'en',
                ]
            ))
                ->send($data);
    }
    protected function log(array $data)
    {
        $header = 'Here is a request to external system!';
        $body = implode(', ', $this->maskData($data));
        Logger::log($header . '. \n ' . $body);
    }
}
class ClassicProtocol extends AbstractProtocol
{
    public function send()
    {
        $registration = $this->assembleRegistrationPart();
        $payment = $this->assemblePaymentPart();
        $specificParams = $this->assembleClassicSpecificPart();
        $dataToSend =
            array_merge(
                $registration, $payment, $specificParams
            );
        $this->log($dataToSend);
        $this->doSend($dataToSend);
    }
    protected function assembleRegistrationPart()
    {
        return ['hello' => 'there'];
    }
    protected function assemblePaymentPart()
    {
        return ['pay' => 'yes'];
    }
}
这样的代码表明我只是滥用继承。这就是重构的方式:
class ClassicProtocol
{
    private $request;
    private $logger;
    public function __construct(Request $request, Logger $logger, Client $client)
    {
        $this->request = $request;
        $this->client = $client;
        $this->logger = $logger;
    }
    public function send()
    {
        $this->logger->log($this->request->getData());
        $this->client->send($this->request->getData());
    }
}
$protocol =
    new ClassicProtocol(
        new PaymentRequest(
            new RegistrationData(),
            new PaymentData(),
            new ClassicSpecificData()
        ),
        new ClassicLogger(),
        new ClassicClient()
    );
class RegistrationData
{
    public function getData()
    {
        return ['hello' => 'there'];
    }
}
class PaymentData
{
    public function getData()
    {
        return ['pay' => 'yes'];
    }
}
class ClassicLogger
{
    public function log(array $data)
    {
        $header = 'Here is a request to external system!';
        $body = implode(', ', $this->maskData($data));
        Logger::log($header . '. \n ' . $body);
    }
}
class ClassicClient
{
    private $properties;
    public function __construct()
    {
        $this->properties =
            [
                'timeout' => 60,
                'encoding' => 'utf-8',
                'language' => 'en',
            ];
    }
}
从那以后,我非常仔细地对待继承,因为我遭受了很多次伤害。  
从那时起,我得出了关于继承的另一个结论。我强烈反对基于内部结构的继承。它破坏了封装,很脆弱,毕竟是程序性的。当我以正确的方式分解域时,继承就很少发生。