LINUX.ORG.RU

Как бы отрефакторить свое собственное говнецо?

 , , , ,


0

1

Когда я был молодой, мне поручили написать важную хрень, и я начал писать, и написал. Мы использовали embedded-базу (если интересно - neo4j), и я тогда плевался от паттернов, поэтому сейчас по всему проекту иногда сквозь все слои абстракции прорывается низкоуровненая хрень.

Есть один класс-менеджер, который отвечает за инициализацию/конфигурирование базы и индексов. Из него наружу торчат методы для создания классов, которые оборачивают сущности базы и позволяют сверху налепливать свою логику. (делал тогда еще по этому ману: http://neo4j.com/docs/stable/tutorials-java-embedded-entities.html), оказалось, что зря.

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

Если база падает, можно ее перезапустить и все будет в порядке, казалось бы, но! Поскольку каждый наш объект внутри держит какой-то примитив базы, после перезапуска эти примитивы будут ссылаться на старую базу, и, соответственно, весь перезапуск бесполезен.

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

Можно было бы сделать все на исключениях (типа словить что-то в стиле «БазаВыключенаИсключение» и отрефрешить объект), но из-за того, что нет единой точки оперирования хренями, пришлось бы это совать всюду, где может быть взаимодействие с примитивами базы.

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

★★★★★

Регистрируй каждый БД-объект в богоклассе, пусть хранит список «слушателей» и отправляет им сообщение о том, что база переинициализировалась.

Это если религия не позволяет использовать синглтон, конечно.

E ★★★
()
Ответ на: комментарий от E

А как синглтон? У меня просто есть синглтон в качестве провайдера айдишников и я уже сто раз об этом пожалел.

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

Ну и проект как бы нормально нагружен. Мне тоже приходила идея со слушателями, но их может быть порядка сотен тысяч, я хз, насколько он тогда будет бутылочным горлышком. И база еще шардится на троечку, там всегда мастер есть и если он грохнется, придется еще весь кластер дергать.

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

Синглтон как виртуальная ссылка на глобальный инстанс. Как его кошерно готовить в Java - не знаю, увы.

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

Вообще дизайн плохой. Объекты не должны быть никак связаны с низкоуровневыми примитивами. Максимум - ссылаться на какой-то глобальный объект, которых хранит примитивы внутри. Например, сам богообъект держит список примитивов, наружу выдавая только внутренние виртуальные id. Тогда при переинициализации затронется только богообъект: пересоздаст примитивы, а айдишники останутся прежними. В идеале ноды/рёбра не должны даже не подозревать, что что-то произошло.

E ★★★
()

tl; dr

Как бы отрефакторить свое собственное говнецо?

просто пиши заново, потом мигрируй данные

umren ★★★★★
()

В proxy-объект оберни ссылку на базу. Пусть он хранит всегда актуальную ссылку и переинициализирует её по необходимости.

Reset ★★★★★
()
Ответ на: комментарий от Reset

В том-то и проблема, что так не получается. Я пробовал так сделать. Вон там есть GraphDatabaseService, который отдает свои сущности (e.g. Node), у которих под капотом ссылка на эту базу, и когда я те ноды оборачиваю в свои сущности, они просто ломаются при падении базы.

Кажется, надо как-то отделить мои объекты от их, но тут в любом случае эта проблема с тем, что у активных в данный момент объектов инвалидируются ссылки. омг, ну я и говно написал :/

anonymous
()
Ответ на: комментарий от umren

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

anonymous
()

Формально, слои соответствуют «уровню низости»

Когда много слоёв - это выглядит как разобранный девайс на мелкие винтики - разобрать можно, но после сборки могут появиться лишние детали в простейшем случае )

Можно использовать ещё такой подход: добавлять новый код, не разрушая старый без особой необходимости. Постепенно, система плавно перерастет в обновленную архитектуру за счёт новых компонентов, работавших в старом коде.

Разумеется, многое определяется эффективностью, целесообразностью и возможностями.

Мне кажется не стоит БД сильно притягивать в ООП - тут уместен простой набор слоёв: «линейные» или простые операции ввода-вывода, низкоуровнеый API над этими функциями, примитивный слой API бизнес-логики...

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

отметь галочкой:

а) тред не читал

б) прочитал книжку по рефакторингу, цитирую по памяти

в) набиваю посты

г) не люблю высказываться по сути

anonymous
()

Поскольку каждый наш объект внутри держит какой-то примитив базы

нет единой точки оперирования хренями

Тогда проще всего в хрени держать идентификатор подключения. И при каждом обращении сравнивать его с глобальным. Если отличаются - обновить кэш

There are only two hard things in Computer Science: cache invalidation and naming things.

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

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

Ставлю свои носки, что есть какой-то такой энтэрпрайзный Паттерн!

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

Черт, я залогиниться забыл. Это я отвечал)

cdshines ★★★★★
() автор топика
Ответ на: комментарий от anonymous

угадал: а)

б) как раз наоборот - можно через (умную ссылку) т.е. прокси реализовать

swwwfactory ★★
()
Ответ на: комментарий от nosuchuser

Проверки в каждый метод? А насколько тормозить будет?

cdshines ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.