Нарушение возникает, если клиент вправе ожидать рабочий Save или Read, а новая реализация принципиально этого не умеет. Лучше разделить интерфейсы чтения и записи и зависеть только от нужной возможности.
Проблема LSP при добавлении нового типа хранилища
Нарушение возникает, если клиент вправе ожидать рабочий Save или Read, а новая реализация принципиально этого не умеет. Лучше разделить интерфейсы чтения и записи и зависеть только от нужной возможности.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В системе есть иерархия интерфейса IStorage и его реализации. Требуется ввести новый тип хранилища, при этом один из методов (Save или Read) может быть неактуален для этой реализации. Если в такой ситуации метод будет генерировать исключение, это приводит к нарушению принципа подстановки Лисков (LSP). Опишите, в чём заключается ошибка такого подхода и предложите изменения в архитектуре, позволяющие сохранить корректность LSP.
class IStorage {
public:
virtual void Save(const std::string& path) = 0;
virtual void Read(const std::string& path) = 0;
};
class FileStorage : public IStorage {
public:
void Save(const std::string& path) override;
void Read(const std::string& path) override;
};
class DatabaseStorage : public IStorage {
public:
void Save(const std::string& path) override;
void Read(const std::string& path) override;
};
class RemoteStorage : public IStorage {
public:
void Save(const std::string& path) override;
void Read(const std::string& path) override;
};
Ответ
Нарушение возникает, если клиент вправе ожидать рабочий Save или Read, а новая реализация принципиально этого не умеет. Лучше разделить интерфейсы чтения и записи и зависеть только от нужной возможности.
Например, выделите IReadStorage и IWriteStorage с виртуальными деструкторами. Хранилище только для чтения реализует первое, а обычное — оба. Потребитель записи тогда не сможет случайно получить реализацию без этой способности.
Само наличие исключения ещё не нарушает LSP: допустимые ошибки могут быть частью исходного контракта. Проблема именно в несовместимом усилении требований или отказе от обещанного поведения. Пустой Save, молча ничего не сохраняющий, тоже не решение.