Как сохранять и загружать разные типы объектов?

Во время кодирования я часто сталкиваюсь с такой ситуацией:

  1. У меня есть несколько объектов (ConcreteType1, ConcreteType2, ...) с одним и тем же базовым типом AbstractType, у которого есть абстрактные методы save и load. Каждый объект может (и должен) сохранять определенные данные, переопределяя метод save.
  2. У меня есть список объектов AbstractType, который содержит различные объекты ConcreteTypeX.
  3. Я прохожу список и метод save для каждого объекта.

На данный момент я думаю, что это хороший объектно-ориентированный дизайн. (Или я ошибаюсь?) Проблемы начинаются, когда я хочу перезагрузить данные:

Каждый объект может загружать свои собственные данные, но я должен знать конкретный тип заранее, чтобы создать экземпляр правильного ConcreteTypeX и вызвать метод load. Таким образом, метод загрузки должен многое знать о конкретных типах. Я обычно «решал» эту проблему, записывая перед вызовом save какой-то маркер, который используется загрузчиком для определения правильного ConcreteTypeX.

У меня всегда было / было плохое предчувствие по этому поводу. Похоже на какой-то антипаттерн ...

Есть способы лучше?

Обновлено: Прошу прощения за недоразумение, часть текста переписал. Я знаю о сериализации и, возможно, есть какое-то почти идеальное решение в Java / .NET / yourFavoriteLanguage, но я ищу общее решение, которое могло бы быть лучше и более "ООП-иш" по сравнению с моей концепцией. .

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
180
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это .NET или Java? Если да, то почему вы не используете сериализацию?

Ирония в том, что я обычно пишу это с буквой «s», так как я британец!

Mitch Wheat 15.11.2008 17:36

Ага! Итак, мы оттираемся на вас. Когда вы начнете пить кофе вместо чая, тогда мы сможем одержать победу!

George Stocker 15.11.2008 17:39

РЖУ НЕ МОГУ. Я американец, но случайно установил в своей системе английский, не заметив, что это британский английский. :)

Bill the Lizard 15.11.2008 17:40

Это ни .NET, ни Java :) Конечно, сериализация справится со своей задачей, но как и мое решение. Но я уточнил свой вопрос.

Daniel Rikowski 15.11.2008 17:40
Ответ принят как подходящий

Если вы не можете просто использовать сериализацию, я бы все равно вытащил логику загрузки объекта из базового класса. Ваш инстинкт верен, и вы правильно определите запах кода. Базовый класс не должен изменяться при изменении или добавлении производных классов.

Проблема в том, что что-нибудь должен загрузить данные и создать экземпляры этих объектов. Звучит как работа для Абстрактный узор фабрики.

Есть способы получше, но давайте сделаем шаг назад и рассмотрим концептуально. Что делают все объекты? Загрузка и сохранение. Когда вы получаете объект из памяти, вам действительно не нужно заботиться о том, получает ли он свою информацию из файла, базы данных или реестра Windows. Вы просто хотите, чтобы объект был загружен. Это важно помнить, потому что позже ваш программист по техническому обслуживанию будет смотреть на метод LoadFromFile () и спрашивать: «Почему он так называется, если на самом деле он ничего не загружает из файла?»

Во-вторых, вы сталкиваетесь с проблемой, с которой мы все сталкиваемся, и она основана на разделении работы. Вам нужен уровень, который обрабатывает получение данных из физического источника; вам нужен уровень, который управляет этими данными, и вам нужен уровень, который отображает эти данные. В этом суть N-уровень развития. Я дал ссылку на статью, которая подробно описывает обсуждает вашу проблему и подробно описывает, как создать уровень доступа к данным для решения вашей проблемы. Также существует множество проектов кода здесь и здесь.

Если вы ищете Java, просто замените .NET на «java» и выполните поиск «Java N-Tier development». Однако, помимо синтаксических различий, структура дизайна такая же.

Названия методов использовались в качестве эскизов для описания моей проблемы. Конечно, в реальных приложениях я использую более удачные имена :) Но спасибо за статью, я ее прочту!

Daniel Rikowski 15.11.2008 17:29

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