Как я могу написать DAO для ресурсов с расширяемыми свойствами? - PullRequest
0 голосов
/ 23 апреля 2009

Я пытаюсь написать на Java встроенную ( НЕ веб, а не корпоративную ) систему управления контентом с упором на организацию, простоту использования и масштабируемость до 100 000 или около того элементов. Пользователь и система должны иметь возможность создавать и определять элементы метаданных, которые могут быть связаны с уникальными ресурсами, чтобы обеспечить возможность поиска.

Например, они могут создать тег «ProjectName», который принимает строковые значения. Затем они могут пометить кучу ресурсов как принадлежащие проектам «Take Over the World» или «Fix My Car». Теги строго типизированы, поэтому в теге могут храниться одна или несколько строк, целых чисел, двойных чисел и т. Д. Каждый тип тега должен иметь средства форматирования и проверки ввода для возможности редактирования.

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

Проблема заключается в том, что ресурсы должны вести себя как кортежи (для табличного просмотра / сортировки / фильтрации) и как (TagName, TagValue) карт. Модели GUI могут вызывать эти методы потенциально тысячи раз для каждого обновления GUI, поэтому некоторое представление об индексации заставит все это работать лучше. К сожалению, множественные типы тегов означают, что будет неудобно, если я не верну все как универсальный объект и не сделаю целый беспорядок условных выражений типа TagValue.

Я рассмотрел использование отражений и DynaBeans Apache, но кодирование этого для работы с моделями графического интерфейса выглядит просто болезненно и неловко. Есть лучший способ сделать это??? Какая-то библиотека или шаблон дизайна?

Итак, мой вопрос: есть ли лучший способ? Какая-нибудь библиотека или шаблон дизайна, который бы просто занимался этим?

Ответы [ 3 ]

1 голос
/ 24 апреля 2009

Из вашего вопроса я предполагаю, что «ресурс» - это сущность в вашей системе, с которой связаны некоторые «теговые» сущности. Если мое предположение верно, вот вам интерфейс DAO ванили, дайте мне знать, если вы об этом думаете:

public interface ResourceDAO {
    void store(Resource resource);
    void remove(Resource resource);
    List<Resource> findResources(QueryCriteria criteria);
    void addTagsToResource(Resource resource, Set<Tag> tags);
}

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

Это соответствует тому, что вы думаете?

Другим аспектом проблемы, о которой вы упоминаете, является необходимость иметь дело с несколькими различными типами тегов, которые требуют различного поведения в зависимости от типа (требующих условных выражений "TagValue instanceof Type"). Шаблон посетителя может справиться с этим элегантно.

1 голос
/ 24 апреля 2009

Не думаю, что вы должны рассматривать какое-либо из этих свойств как фактические переменные-члены. У вас должен быть объект «Property», который содержит свойство (которое будет аналогично переменной-члену), и объект «Collection», который имеет коллекции свойств (которые будут похожи на класс).

Поскольку эти атрибуты и коллекции на самом деле не связаны с кодом, было бы бессмысленно реализовывать их как объекты (и это было бы настоящей болью в заднице)

Ваши атрибуты и коллекции должны содержать ВСЕ данные, относящиеся к ним. Например, если поле в конечном итоге записывается в базу данных, ему нужно где-то хранить имя таблицы. Если его нужно записать на экран, его тоже нужно где-то сохранить.

Проверка диапазона / значения может быть «добавлена» к атрибутам, поэтому, когда вы определяете тип данных атрибута, у вас может быть текст с надписью «MaxLength (12)», который будет создавать экземпляр класса под названием MaxLength с значение 12, и сохранить этот класс в атрибуте. Всякий раз, когда значение атрибута изменяется, новое значение будет передаваться каждой проверке диапазона, которая была применена к этому классу. С классом может быть связано много типов действий.

Это просто база. Я разработал что-то подобное, и это большая работа, но это намного проще, чем пытаться делать это простым языком.

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

edit (ответ на комментарий):

Я думал о попытке поработать с реестром / ключом (мы все еще говорим о парах значений атрибутов), но он не совсем подходит.

Вы пытаетесь встроить DAO в объекты Java. Это действительно естественно, но я считаю, что это просто плохой подход к решению проблемы DAO / DTO. Объект Java имеет атрибуты и поведения, которые действуют на эти атрибуты. Для того, что вы делаете, нет поведения (например, если пользователь создает поле «День рождения», вы не будете использовать объектный код для вычисления его возраста, потому что вы действительно не знаете, что такое день рождения).

Итак, если вы выбросите объекты и атрибуты, как вы будете хранить эти данные?

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

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

Проблема: вы потеряли Strong Typing, и ваши данные имеют очень свободный формат (что, вероятно, плохо)

Решение: Создайте базовый класс для «Атрибута», который будет использоваться вместо значения в хеш-таблице. Расширьте этот базовый класс для IntegerAttribute, StringAttribute, DateAttribute, ... Не допускайте значений, которые не соответствуют этому типу. Теперь у вас строгая типизация, но это время выполнения, а не время компиляции - вероятно, все в порядке, так как ваши данные на самом деле определяются во время выполнения в любом случае.

Проблема: Форматеры и валидаторы

Решение: Иметь возможность создавать плагин для вашего атрибута базового класса. Вы должны иметь возможность установить setValidator или setFormatter для любого атрибута. Валидатор / форматтер должен жить с этим атрибутом, поэтому вам, вероятно, потребуется иметь возможность сериализовать их в БД при сохранении атрибута.

Приятной частью здесь является то, что когда вы выполняете «attribute.getFormattedValue ()» для атрибута, он предварительно форматируется для отображения. attribute.setValue () автоматически вызовет валидатор и выдаст исключение или вернет код ошибки, если какая-либо из валидаций окажется неудачной.

Проблема:Как я могу отобразить их на экране? у нас уже есть getFormatted (), но где он отображается на экране? что мы используем для этикетки? Какой элемент управления должен редактировать это поле?

Решение: Я бы сохранил все эти вещи в КАЖДОМ атрибуте. (Порядок должен храниться в классе, но, поскольку это хеш-таблица, поэтому она не будет работать - мы вернемся к этому дальше). Если вы сохраняете отображаемое имя, тип элемента управления, используемый для его отображения (текстовое поле, таблица, дата, ...) и имя поля базы данных, этот атрибут должен иметь всю информацию, необходимую для взаимодействия с дисплеем и базой данных I / О подпрограммы, написанные для работы с атрибутами.

Проблема: Hashtable - плохой интерфейс для DAO.

Решение: Это абсолютно правильно. Ваша хеш-таблица должна быть заключена в класс, который знает о коллекции атрибутов, которые она содержит. Он должен иметь возможность хранить себя (включая все его атрибуты) в базе данных - возможно, с помощью вспомогательного класса. Вероятно, он сможет проверить все атрибуты с помощью одного вызова метода.

Проблема: Как на самом деле работать с этими вещами?

Решение: Поскольку они содержат свои собственные данные, в любой точке вашей системы, где они взаимодействуют (скажем, с экраном или с БД), вам нужен «Адаптер».

Допустим, вы представляете экран для редактирования ваших данных. Вашему адаптеру будет передан кадр и один из ваших DTO на основе хеш-таблицы.

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

Это создаст текстовое поле, затем он добавит слушателя в текстовое поле, которое обновит данные, это связывает ваши данные с элементом управления на экране.

Теперь, когда пользователь обновляет элемент управления, обновление отправляется в Атрибут. Атрибут хранит новое значение, все готово.

(Это будет осложнено концепцией кнопки «ОК», которая передает все значения за раз, но я все равно настроил бы каждую привязку перед рукой и использовал бы «ОК» в качестве триггера.)

Эта привязка может быть трудной. Я сделал это вручную, как только я использовал инструментарий под названием «JGoodies», в котором была встроена некоторая способность связывания, чтобы мне не приходилось писать каждую возможную комбинацию связывания, но я не уверен в долгосрочной перспективе это сэкономило много времени.

Это слишком долго. Я должен был когда-нибудь просто создать инструментарий DAO / DTO - я думаю, что объекты Java совсем не подходят как объекты DAO / DTO.

Если вы все еще в тупике, не стесняйтесь, пишите мне по электронной почте / мне ... bill.kress на gmail.

0 голосов
/ 23 апреля 2009

Вы привязаны к использованию реляционной базы данных? Возможно, стоит заглянуть в базу данных, ориентированную на документы, например, couchDB. Это даст вам гибкость, необходимую для хранения любого произвольно строго типизированного объекта, который вы хотите, и даст вам возможность запрашивать эти объекты. Я полагаю, что есть некоторые библиотеки Java для доступа к couchDB.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...