Я пытаюсь понять SRP, но, хотя я понимаю аргументы в пользу того, как его применять, я не вижу в этом преимущества. Рассмотрим этот пример, взятый у Роберта Мартина SRP PDF:
interface IModem
{
void Dial(string number);
void Hangup();
void Send(char c);
char Recv();
}
Он предлагает разделить это на два интерфейса:
interface IModemConnection
{
void Dial(string number);
void Hangup();
}
interface IModemDataExchange
{
void Send(char c);
char Recv();
}
Я также читал эту статью, которая делает следующий шаг:
interface IModemConnection : IDisposable
{
IModemDataExchange Dial(string number);
}
interface IModemDataExchange
{
void Send(char c);
char Recv();
}
В этот момент я понимаю, что подразумевается под функциональными (Send / Recv
) и нефункциональными (Dial / Hangup
) аспектами, но я не вижу преимущества их разделения в этом примере. Учитывая эту базовую реализацию:
class ConcreteModem : IModemConnection
{
public IModemDataExchange Dial(string number)
{
if (connection is successful)
{
return new ConcreteModemDataExchange();
}
return null;
}
public void Dispose()
{
//
}
public bool IsConnected { get; private set; }
}
В этот момент позвольте мне еще раз процитировать Роберта Мартина, хотя он говорит о другом примере из этого PDF:
Во-вторых, если изменение в GraphicalApplication приводит к изменению Rectangle по какой-либо причине, это изменение может заставить нас пересоздать, повторно протестировать и повторно развернуть ComputationalGeometryApplication. Если мы забудем это сделать, это приложение может сломаться непредсказуемым образом.
Это то, чего я не понимаю. Если бы мне пришлось создать вторую реализацию IModemDataExchange
, и я хотел бы использовать ее, мне все равно пришлось бы изменить метод Dial
, то есть класс также должен быть перекомпилирован:
public IModemDataExchange Dial(string number)
{
if (some condition is met)
{
return new ConcreteModemDataExchange();
}
else if (another condition is met)
{
return new AnotherConcreteModemDataExchange();
}
return null;
}
Я не вижу, что это сделало, чтобы уменьшить влияние изменений на класс. Его все еще нужно перекомпилировать, так что польза? Что вы получаете от этого, что так важно для создания качественного кода?