|
|
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
Доброе время суток ! Есть некоторый класс, назову его "Article", содержит большое количество свойств (около 30). "Article" представляет данные для разного типа (типов 8) обьектов, что опеределяется через одно из свойст "Article" (ArticleType). Кроме этого некоторые свойства содержат данные на нескольких языках (Название, описание, страна и т.д.). Код: java 1. 2. 3. 4. 5. 6. 7. Нужно сгенерировать ссылку (не http), а по заданному шаблону с данными для конкретного "ArticleType". От типа "Article" отличаются как шаблоны, так и данные для шаблона, кроме того некоторые данные для разных типов по разному отображаются. Также нужно учитывать язык, сейчас два языка это значит что надо сгенерировать две ссылки. Вот к чему я пришел... Создать общий класс (абстрактный) для генерации ссылки и получения нужных компонентов из "Article" для конкретного шаблона. В абстрактном класс определить общие правила. От него наследовать более специфичные классы (по типам статей) и переопределить, только те методы для которых необходимо реализовать другое отображение. В абстрактном классе, добавить абстрактный метод, который реализует каждый тип. Что-то вроде: Код: java 1. 2. 3. 4. 5. 6. На данный момент внимание к нескольким языкам не уделено. Так же в абстрактном классе опредеть еще один финальный метод (generate), который вызывает в свою очередь buildValueMap() ,а затем передаёт данные (hashmap) вместе с шаблоном другому обьекту для обьединения. Для обьединения в данном случае использовать Velocity. Код: java 1. 2. 3. 4. 5. 6. getReferenceTemplate() это абстрактный метод, который переопределяется каждым наследуемым классом, и возвращает путь до шаблона для конкретного типа "Article". Необходимую реализацию генератора получать через фабрику через тип "Article". Решение написаное выше не претендует на лучшее, поэтому вопрос в том, есть ли другое/другие решения для данного случая или что изменить не трогая модель "Article"/"ArticleType". В проекте используется фреймворк Spring. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 15:32:15 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
uvladНужно сгенерировать ссылку (не http), а по заданному шаблону с данными для конкретного "ArticleType". От типа "Article" отличаются как шаблоны, так и данные для шаблона, кроме того некоторые данные для разных типов по разному отображаются. Также нужно учитывать язык, сейчас два языка это значит что надо сгенерировать две ссылки. То ли у вас с объяснением сложно, то ли у меня с пониманием. По-моему задача просто решается выделением абстрактных слоёв. А так, не понятно что за "разные типы", куда ссылки из чего они состоят и т.п. uvladСоздать общий класс (абстрактный) для генерации ссылки и получения нужных компонентов из "Article" для конкретного шаблона. В абстрактном класс определить общие правила. От него наследовать более специфичные классы (по типам статей) и переопределить, только те методы для которых необходимо реализовать другое отображение. В абстрактном классе, добавить абстрактный метод, который реализует каждый тип. Здесь нужно быть осторожным и понимать что композиция за частую может оказатся удобнее наследования. Мне без понимания предметной области сложно сходу оценить. Но просто на это стоит обращать внимание каждый раз когда хочется воспользоваться наследованием. uvladЧто-то вроде: Код: java 1. 2. 3. 4. 5. Во-первых повылазили странности анемичной модели. Что за getPublisher(article)??? article.getPublisher() чем не угодил? Во-вторых то чем меня так последнее время раздражает Java это вот эти вот неконтролируемые стринги. Т.е. это совершенно тупой код по копированию свойств в HashMap. Можно Introspector или BeanUtils навернуть и вместо кучи такого бессмысленного кода получить копирование свойств в map одним методом. uvladНа данный момент внимание к нескольким языкам не уделено. Вы объясняете своё решение, лишь изредка упоминая условие задачи. Задача с языками - классическая, или шаблоны нужно под разные языки держать, или доменную модель сразу проектировть с учетом языков. Здесь скорее всего второго и этого здесь не видно. uvladТак же в абстрактном классе опредеть еще один финальный метод (generate), Вы бы его назвали как-то. Было бы понятнее. uvladкоторый вызывает в свою очередь buildValueMap() ,а затем передаёт данные (hashmap) вместе с шаблоном другому обьекту для обьединения. Для обьединения в данном случае использовать Velocity. Как-то слишком много этапов. Лучше бы на примере показали. Что есть и что надо получить. uvlad Код: java 1. 2. 3. 4. 5. 6. Нафига козе баян? Т.е. для чего здесь состояние? Что если buildValueMap() ещё не был вызван? Какая вообще польза от Map если все нормальны движки сразу из объектов нормально читают? uvladgetReferenceTemplate() это абстрактный метод, который переопределяется каждым наследуемым классом, и возвращает путь до шаблона для конкретного типа "Article". Если у вас тип это поведение, и тогда статьи это иерархия наследования, то можно применить GoF Bridge - сделать схожую иерархию ReferenceBuilder-ов. Но, если у вас "тип" это просто признак, то buildReference() должен быть методом этого типа. Либо сильно связаным article.getType().buildReference(); (если тип статьи единственный кто определяет тип ссылки) Либо слабо связаный, если связь не такая строгая: ReferenceBuilderFactory.createBuilder(article) - а там уже по признакам article искать подходяшщий билдер. uvladНеобходимую реализацию генератора получать через фабрику через тип "Article". О! Я ж о том же. Но с другой стороны не ясно почему Article.buildReference() не подходит и какие проблемы влечет за собой такой метод? Я бы приминил Rich Domain Model в данном случае по максимуму. Т.е. разбиение на классы, у вас, в целом, логичное. А вот разбиение методов по классам и их реализация, уже не очень понятны. uvladРешение написаное выше не претендует на лучшее, поэтому вопрос в том, есть ли другое/другие решения для данного случая или что изменить не трогая модель "Article"/"ArticleType". Почему не трогая? Объяснитесь? Реализация, конечно же, должна быть вынесена в отдельный слой. А вот методы, удобее всего будет прикрутить там где они нужнее. Если reference создаётся всегда в контексте статьи, то почему бы и метод соответствующий в статье не завести? uvladВ проекте используется фреймворк Spring. Это не сильно важно. Spring компануют инфраструктуру. Вы же решаете задачу построения модели предметной области. Разве что в Spring может быть удобно map описать чтобы слабо связать, например ArticleType и ReferenceBuilder - но есть ли польза от такого решения, я пока не уверен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 16:30:24 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
BlazkowiczuvladНужно сгенерировать ссылку (не http), а по заданному шаблону с данными для конкретного "ArticleType". От типа "Article" отличаются как шаблоны, так и данные для шаблона, кроме того некоторые данные для разных типов по разному отображаются. Также нужно учитывать язык, сейчас два языка это значит что надо сгенерировать две ссылки. То ли у вас с объяснением сложно, то ли у меня с пониманием. По-моему задача просто решается выделением абстрактных слоёв. А так, не понятно что за "разные типы", куда ссылки из чего они состоят и т.п. Может и с обьяснением сложно, просто написал я слишком кратко. Как вы упомянули "тип" это признак, т.е. то чем статья "Article" является. BlazkowiczuvladСоздать общий класс (абстрактный) для генерации ссылки и получения нужных компонентов из "Article" для конкретного шаблона. В абстрактном класс определить общие правила. От него наследовать более специфичные классы (по типам статей) и переопределить, только те методы для которых необходимо реализовать другое отображение. В абстрактном классе, добавить абстрактный метод, который реализует каждый тип. Здесь нужно быть осторожным и понимать что композиция за частую может оказатся удобнее наследования. Мне без понимания предметной области сложно сходу оценить. Но просто на это стоит обращать внимание каждый раз когда хочется воспользоваться наследованием. uvladЧто-то вроде: Код: java 1. 2. 3. 4. 5. Во-первых повылазили странности анемичной модели. Что за getPublisher(article)??? article.getPublisher() чем не угодил? Во-вторых то чем меня так последнее время раздражает Java это вот эти вот неконтролируемые стринги. Т.е. это совершенно тупой код по копированию свойств в HashMap. Можно Introspector или BeanUtils навернуть и вместо кучи такого бессмысленного кода получить копирование свойств в map одним методом. Почему именно через стринги заданы свойства в HashMap ? Я не знаю как работать с Introspector или BeanUtils не слышал не использовал (имею не большой опыт программирования на Java), мой случай для каждого шаблона мне нужно выбрать только часть свойств и от типа статьи они отличаются. Те название ключей которые определяются в HashMap, впоследствие используются в шаблоне от Velocity. Код: java 1. По поводу анемичной модели, если я буду обращаться через геттеры к модели "Article", то всегда буду получать общие значения не относительно того, для какого типа "Article" получаю данные. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. BlazkowiczuvladНа данный момент внимание к нескольким языкам не уделено. Вы объясняете своё решение, лишь изредка упоминая условие задачи. Задача с языками - классическая, или шаблоны нужно под разные языки держать, или доменную модель сразу проектировть с учетом языков. Здесь скорее всего второго и этого здесь не видно. Шаблон один и через SpringMessage делается перевод статического текста. Для данных из модели думал сначало сделать ссылку для одного язык, затем для остальных и все это вернуть в коллекции. Существующею доменную модель я менять не могу, только дополнять. BlazkowiczuvladТак же в абстрактном классе опредеть еще один финальный метод (generate), Вы бы его назвали как-то. Было бы понятнее. Полное определение Код: java 1. 2. 3. 4. Blazkowiczuvladкоторый вызывает в свою очередь buildValueMap() ,а затем передаёт данные (hashmap) вместе с шаблоном другому обьекту для обьединения. Для обьединения в данном случае использовать Velocity. Как-то слишком много этапов. Лучше бы на примере показали. Что есть и что надо получить. uvlad Код: java 1. 2. 3. 4. 5. 6. Нафига козе баян? Т.е. для чего здесь состояние? Что если buildValueMap() ещё не был вызван? Какая вообще польза от Map если все нормальны движки сразу из объектов нормально читают? В данном случае, как мне кажется не может быть как, что buildValueMap() не будет вызван. Состояние да, здесь ни к чему, можно просто возращать результат работы от buildValueMap(). По поводу пользы от Map, если я правильно понял, то да можно было бы передать весь обьект, но как я писал выше "Article" имеет разные типы от которых зависит не только какие свойства нужны (что в таком случае можно было бы ограничить шаблоном), но и как их выводить. Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. BlazkowiczuvladgetReferenceTemplate() это абстрактный метод, который переопределяется каждым наследуемым классом, и возвращает путь до шаблона для конкретного типа "Article". Если у вас тип это поведение, и тогда статьи это иерархия наследования, то можно применить GoF Bridge - сделать схожую иерархию ReferenceBuilder-ов. Статьи как раз не являются иерархией наследования, а вот для создания ArticleReference использовано наследования. А getReferenceTemplate(), что видимо не является совсем корректным Код: java 1. 2. 3. 4. 5. 6. BlazkowiczНо, если у вас "тип" это просто признак, то buildReference() должен быть методом этого типа. Либо сильно связаным article.getType().buildReference(); (если тип статьи единственный кто определяет тип ссылки) Либо слабо связаный, если связь не такая строгая: ReferenceBuilderFactory.createBuilder(article) - а там уже по признакам article искать подходяшщий билдер. О! Какое точно подмечено, признак. Видимо правильнее сказать "тип" (ArticleType) это признак, того чем "Article" является. BlazkowiczuvladНеобходимую реализацию генератора получать через фабрику через тип "Article". О! Я ж о том же. Но с другой стороны не ясно почему Article.buildReference() не подходит и какие проблемы влечет за собой такой метод? Я бы приминил Rich Domain Model в данном случае по максимуму. Т.е. разбиение на классы, у вас, в целом, логичное. А вот разбиение методов по классам и их реализация, уже не очень понятны. Article.buidleReference() не понял как данный метод должен работать. BlazkowiczuvladРешение написаное выше не претендует на лучшее, поэтому вопрос в том, есть ли другое/другие решения для данного случая или что изменить не трогая модель "Article"/"ArticleType". Почему не трогая? Объяснитесь? Реализация, конечно же, должна быть вынесена в отдельный слой. А вот методы, удобее всего будет прикрутить там где они нужнее. Если reference создаётся всегда в контексте статьи, то почему бы и метод соответствующий в статье не завести? Тут возможно я слишком радикально выразился, дополнять модель конечно можно, но менять структуру никак. Т.к. это повличет большие изменения в проекте, а проект рабочий уже не первый год. Спасибо за развернутый ответ, постарался ответить на все замечания. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 18:37:59 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
Мне всё равно не очень понятна связь между Article, ArticleType и, например, getPublisher(article) - как он для разных типов разные значения получает? Но, в целом, вам просто нужен адаптер мержду шаблоном и Article, который по типу будет находить правильные значения. Сначала нужно найти шаблон по каким-то параметрам (по каким?) Затем найти адаптер по параметрам (тот же набор, или другой?) Задача адаптера в зависимости от типа находить правильные свойства. Шаблон Код: java 1. Логика (условный код, имена можно дать любые) Код: java 1. или rich вариант. Код: java 1. Аналогично ищем адаптер Код: java 1. Затем рендерим (условный код, по единственному ключу кидаем враппер) Код: java 1. Сам адаптер по методу wrap создаёт обертку, которая умеет в статье находить правильные значения для свойст нужных шаблону. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 19:02:16 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
Да мои обьяснения не лучшии, обычно я читаю форумы, а не пишу ) BlazkowiczМне всё равно не очень понятна связь между Article, ArticleType и, например, getPublisher(article) - как он для разных типов разные значения получает? Не разные значения, а разное представление/отображение свойства (возможно где-то я не так написал, но старался просматривать текст). Допустим getAuthors(article), авторы в модели храняться как коллекция <Person>, персоны имеют роли (например авторы), есть метод article.getAuthors() возвращает List<Person>. Через метод Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Да таких несколько методов можно определить в классе Person и если полностью передать обьект "Article" в шаблон, то там их вызывать. Но проблема будет с такими типами как Integer, Date. Т.к. не все данные имеют свой тип, а где-то надо дату преобразовать в промежуток по дням или еще что-то. BlazkowiczНо, в целом, вам просто нужен адаптер мержду шаблоном и Article, который по типу будет находить правильные значения. Сначала нужно найти шаблон по каким-то параметрам (по каким?) Затем найти адаптер по параметрам (тот же набор, или другой?) Да параметр по которому все определяется один это тип (признак) "Article", код из нескольких символов, например "NM". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 19:30:55 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
uvlad, Ох, что-то у вас всё запутанее и запутанее. У вас уже эта ссылка на "View" слой становится похожа. Какая конечная цель reference? Это отоброжение в конце статьи? Я бы делал отдельный рендеринг и всё. Причем рендеринг весь в шаблоне по сущностям. Потому что ваш пример List<Person> -> String это рендеринг, и шаблон это рендеринг. Зачем два разных этапа для одной задачи? Если вы можете сформулировать причину, то сформулируйте её как можно точно и найдёте решение. Пока я не вижу чем просто шаблоны не подходят? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 22:27:24 |
|
||
|
Реализация для генерации ссылок (не http)
|
|||
|---|---|---|---|
|
#18+
Blazkowiczuvlad, Ох, что-то у вас всё запутанее и запутанее. У вас уже эта ссылка на "View" слой становится похожа. Какая конечная цель reference? Это отоброжение в конце статьи? Я бы делал отдельный рендеринг и всё. Причем рендеринг весь в шаблоне по сущностям. Потому что ваш пример List<Person> -> String это рендеринг, и шаблон это рендеринг. Зачем два разных этапа для одной задачи? Если вы можете сформулировать причину, то сформулируйте её как можно точно и найдёте решение. Пока я не вижу чем просто шаблоны не подходят? Конечная цель ссылки, сохранение в модели как отдельной сущности "ArticleReference", точнее даже набора с ArticleReference, так как они будут на нескольких языках. После сохранения статьи происходит создание ссылки/ссылок, которая вместе с другими данными попадает в базу. Код: java 1. 2. 3. 4. Отображение происходит при просмотре статьи (вместе с другими данными) или при редактирование, где можно будет редактировать сгенерированную ссылку (но это другая история), или когда нужно получить только ссылки для выбранных статей (например в xls). List<Person> -> String, это наверно просто преобразование для Velocity (его я использую как шаблонизатор для слияния шаблона и модели, так же как можно было его использовать для создания содержимого email), хотя в том же шаблоне можно циклом пройтись по списку, но не хочется усложнять читаемость шаблона для ссылки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2013, 22:54:04 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38116464&tid=2130161]: |
0ms |
get settings: |
21ms |
get forum list: |
29ms |
check forum access: |
8ms |
check topic access: |
8ms |
track hit: |
59ms |
get topic data: |
21ms |
get forum data: |
5ms |
get page messages: |
81ms |
get tp. blocked users: |
3ms |
| others: | 332ms |
| total: | 567ms |

| 0 / 0 |
