Десериализация интерфейсных объектов

Я пробовал архитектуру SOLID в своем последнем проекте.

У меня есть интерфейс под названием ILog и класс Log, который реализовал ILog. (Насколько я понимаю, это должно быть сделано, чтобы следовать принципу открытия / закрытия)

Чтобы оставаться открытым для расширений, я реализовал интерфейс через List<ILog> вместо твердой реализации List<Log>.

Сериализация List<ILog> не проблема, а вот десериализация - нет. Я, конечно, понимаю, почему, потому что десериализатор не знает, какой класс реализации он должен использовать.

Вопрос: Как узнать, в какой конкретный тип десериализовать объект, сериализованный через ссылку на интерфейс?

Такие рекомендации, как SOLID, не принесут вам никакой пользы, если они не соответствуют вашим потребностям. Вопрос, на который нужно ответить, заключается не в том, следуете ли вы твердым принципам; действительно ли вам нужен этот интерфейс ILog или нет.

Robert Harvey 14.12.2018 17:10

Почему вы хотите сериализовать регистратор? Или, в более общем смысле, почему вы используете интерфейс, в котором хотите (де) сериализовать что-то? Вы не можете десериализовать сериализованный FooFrobber как BarFrobber, даже если они оба реализуют IFrobber.

CodeCaster 14.12.2018 17:10

Я подумал, что было бы неплохо оставаться открытым для будущих расширений, так как этот проект будет существовать еще довольно долго.

Luchspeter 14.12.2018 17:11

Почему бы не потребовать, чтобы разработчик ILog также реализовал десериализацию? В конце концов, они лучше всех знают свой имп.

Lynn Crumbling 14.12.2018 17:11

На самом деле это был не класс Log - для простоты я выбрал простое слово ...

Luchspeter 14.12.2018 17:12

Расширяемость, интерфейсы и сериализация не связаны друг с другом. Пожалуйста, задайте очень конкретный вопрос, поскольку это звучит слишком расплывчато. Если, например, ваш вопрос - «Как узнать, в какой конкретный тип десериализовать объект, сериализованный через ссылку на интерфейс», ответ может быть "Сохраните информацию о Type при сериализации".

CodeCaster 14.12.2018 17:12

@CodeCaster Да, я думаю, это может быть ответом! Соответственно обновлю свой вопрос спасибо! Вы хотите изменить свой комментарий на ответ, чтобы я мог отметить его соответствующим образом?

Luchspeter 14.12.2018 17:15

Полный ответ в некоторой степени зависит от сериализатора, который вы используете. Например, JSON.NET имеет встроенные методы для этого типа вещей., и если вы используете WCF, есть другой метод и т. д.

Heretic Monkey 14.12.2018 17:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Serializing the List is no problem, but deserializing is.

Если вы десериализуете, вам обязательно нужно каким-то образом сообщить своему сериализатору, какое конкретное представление вашего интерфейса использовать. В случае Json.NET вы можете использовать JsonConstructorAttribute (см. Также этот ответ) или резолверы в сочетании с внедрением зависимостей.

Question: What does it help me to work with List if I have to define the specific implementation-class for data storage / data import anyways?

Интерфейсы отделяют ваш код от фактической реализации, что дает различные преимущества. Например, с точки зрения модульного тестирования они упрощают имитацию (поскольку вы можете удовлетворить интерфейс с имитацией экземпляра, вместо того, чтобы заставлять использовать «настоящий» класс). Кроме того, интерфейсы позволяют получить выгоду от ковариация / контравариантность, чего у вас не было бы с классами в C#. Для получения дополнительной информации о преимуществах интерфейсов ознакомьтесь с различными ответами на вопрос это или прочтите сообщение в блоге это.

Как было сказано выше, интерфейсы всегда вводят определенный уровень накладных расходов / абстракции, и вам необходимо оценивать каждый случай / ситуацию, имеют ли они смысл или нет.

What would be the best way to handle the data-storage of interface objects or are they only used at runtime?

Вам обязательно нужно хранить конкретные представления, а это означает, что во время сохранения вам необходимо решить, какую конкретную реализацию использовать для хранения (а затем десериализации).

Другие вопросы по теме