Pull to refresh

Comments 40

Любопытно. Хотелось бы, однако, понять, можно ли не вводить явно в код на Java сущности, относящиеся к конкретным реквизитам?

С точки зрения ООП, ПлатёжноеПоручение есть связный набор объектов, включая, собственно, сам платёж, потом есть Плательщик, Получатель и прочие реквизиты.

Да! Кстати. Вы не напомните, как появляются платёжные поручения и что они делают (какие регистры затрагивают)?

Любопытно. Хотелось бы, однако, понять, можно ли не вводить явно в код на Java сущности, относящиеся к конкретным реквизитам?

Можно - как в ADO ADO — Википедия (wikipedia.org) Там для каждой таблицы или view можно получать row а уже для row есть коллекция fields . В этом случае названия конкретных полей содержатся в field.name т.е. все универсально . Просто если делать связи между полями (напр ИНН) разных объектов, то мэппинг get* и set* всеравно понадобится

С точки зрения ООП, ПлатёжноеПоручение есть связный набор объектов, включая, собственно, сам платёж, потом есть Плательщик, Получатель и прочие реквизиты

В представлении в виде класса обертки никто не ограничивает, в том же 1С Документ может содержать несколько табличных частей, как часть "объекта" а в базе это несколько таблиц. Поэтому я предложил Get\Set pattern хотя в ORM JPA автоматически генерируемые сущности в базе представляют отдельные таблицы, а уже сложнее нужно руками писать

Да! Кстати. Вы не напомните, как появляются платёжные поручения и что они делают (какие регистры затрагивают)?

Их вводят руками либо на основании другого документа типа счет. Если говорить о типовой 1С Бух 3.0 то документы оформляются, а движения в регистрах делает другой "списание с расчетного счета " подробнее тут Банковские расчетные документы :: Бухгалтерский и налоговый учет в 1С:Бухгалтерии 8 (редакция 3.0). Издание 7 (1c.ru) .

У него там много регистров, для разных ситуаций (но это реализация типовой конфы 1С)

Перефразируя классиков, программист на 1С может писать на 1С на любом языке.

Ёлки-иголки, можно же было хотя бы стандарты наименования соблюдать? С заглавной буквы в java называют исключительно классы, а не поля и уж тем более локальные переменные.

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

Поэтому мы завяжемся на непонятные строки, которые нигде, кроме времени выполнения не проверяются. И грохнется это всё дело с вероятностью близкой к 146% при первом же использовании данного подхода не автором сего великолепия.

Настоятельно рекомендую не заниматься хернёй, а перед началом разработки провести хоть какой-нибудь аналитический обзор того, как это принято делать не в 1С.

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

String LinkedClass();

А почему не java.lang.Class?

LinkSubsystemS

По какой причине тут заглавная буква в конце имени?

Возвращать null из toString()- вообще за гранью.

Спасибо что напомнили а то сам oracle спустил эти Соглашения (чувствуете разницу со Стандартом) в архив https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html

Настоятельно рекомендую не заниматься хернёй, а перед началом разработки провести хоть какой-нибудь аналитический обзор того, как это принято делать не в 1С.

А Вы можете подсказать как принято решать эти проблемы не в 1С без тумана тайного знания.это кстати статья с открытыми вопросами. За mapstruct спасибо я про эти продукты не знал. Но здесь задача разработки совместимых компонент для ORM а это несколько сложнее чем просто мэппинг классов. Просто ищу кто реализовал?

Без тумана тайного знания в мире Java вопросы решаются следующим образом:

  1. Осознаете что же вы на самом деле хотите

  2. Смотрите существующие инструменты максимально покрывающие вашу потребность

  3. Если какой-то один инструмент не нашелся - пытаетесь делить задачу на более простые и снова смотрите что есть подходящего

  4. И вот только когда вы убедились что ничего подходящего совсем нет среди готовых инструментов вы начинаете писать велосипед

То что вы не искали подходящие инструменты видно хотябы по тому что для мапинга ваших сущностей есть много готовых инструментов, (mupstruct/Dozer/в некотором объеме даже Jackson и т.д.) но вы пошли снизу - увидели в языке вроде бы подходящий инструмент для создания своего инструмента и давай свой велосипед изобретать. Это плохой подход, не надо так - вместо того чтобы изобретать уже изобретенное, покрытое тестами и рабочее, лучше бы сделали что-то действительно новое.

И да, если пишете на языке - соблюдайте принятый Code Style, иначе ваш код читать будете только вы.

Так в том то и дело, что просто мэппинга сущностей для независимой разработки компонент на ORM (скажем на JPA ) недостаточно (нужны соглашения о ключах в таблицах и т.д.). Поэтому я и не искал просто мэппинг классов.

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

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

И да, если пишете на языке - соблюдайте принятый Code Style, иначе ваш код читать будете только вы.

Да над этим надо поработать, Java для меня не основной язык, но применяю его для микросервисов вокруг 1С . Правда когда увидел что Oracle слил https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html это в архив, удивился. Неужели за 20 лет не появилось более актуальной доки про clean code?

Так в том то и дело, что просто мэппинга сущностей для независимой разработки компонент на ORM (скажем на JPA ) недостаточно (нужны соглашения о ключах в таблицах и т.д.).

А по делу, что именно требуется? Что есть "независимая разработка компонент на ORM" в вашем понимании?

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

Неужели за 20 лет не появилось более актуальной доки про clean code?

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

от такого clean code у любого Java разработчика глаза прослезятся

Про clean code спасибо но хотелось бы по существу статьи

По существу - налицо феноменальная воинствующая некомпетентность. Минусов насыпать могут запросто.

Почему? Примерно такая аналогия. Представьте: написали криво-коряво-убого тетрис на 1С. Ничтоже сумяшеся заявили на хабре, что сие есть готовый уникальный суперпупер движок для 3D игр для всех платформ, ну и само собой вишенка на торте: приписали DirectX в заголовок. В выводах сообщили, что без проблем можно и в OpenGL и вообще это все неважно - на любом же можно языке тетрис переписать, посоветуйте как лучше.

На справедливое замечание от игроделов "что это за дичь" говорят "спасибо, но давайте по существу".

У читателей лукалицо. Это по существу.

ПисАть как и пИсать нужно только если уж совсем невмоготу. (с) М.Жванецкий.

По существу - налицо феноменальная воинствующая некомпетентность. Минусов насыпать могут запросто.

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

Про мэппинги сущностей я ответил выше, для ORM этого недостачно. Если Вы имеете опыт работы с каким либо ORM (необязательно Java) - это интересно.

Ну а минусы на Хабре всегда могут насыпать, но ради хороших комментариев это можно и потерпеть.

Есть ощущение что у вас проблема на этапе осознания чего вы хотите:

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

Вы хотите сделать в одном проекте РАЗНЫЕ модели навешанные на одни и те же таблицы/колонки БД? Вы хотите странного, тут так не принято ну совсем - почитайте как должен быть устроен маппинг таблиц в рамках существующих ORM.

Вы хотите сделать в одном проекте РАЗНЫЕ модели навешанные на одни и те же таблицы/колонки БД? Вы хотите странного, 

Не понимаю откуда такой вывод, причем один и теже таблицы на разные модели. Я вроде пример прозрачный привел. Сформулирую по другому.

  1. Вендор 1СKiller сделал платформу ORM на Java JPA и некоторые базисные вещи (например компоненту\класс "справочник Контрагентов"). Допустим ORM поддерживает несколько СУБД , но классы используем только в одной выбранной СУБД

  2. Василиса сделала на этой ORM компоненту\класс "Платежное поручение" и использовала часть функционала справочника контагентов 1СKiller (банковские счета , инн, наименование)

  3. Вася сделал свой справочник "Контрагенты Васи", который лучше (поддерживает функционал для нерезидентов и вообще) ., но имеет совершенно другую внутреннию структуру таблиц\сущностей

  4. Петя захотел сделать систему платежей из Платежного поручения Василисы, и Контрагентов Васи.

Как Пете наиболее простым образом соединить эти два решения в ORM 1СKiller, если Василиса использовала для разработки справочник Вендора?

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

При реализации такого ORM возможен рынок\market place совместимых компонент. Иначе только два пути clean кодом склеивать разные решения, ну либо микросервисы которые гораздо более изолированные

Если Василиса хоть немного имеет представление о проектировании и архитектуре информационных систем, то она

использовала часть функционала справочника контагентов 1СKiller

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

Без вот этого концептуального решения ни один из пункт 4 невозможен. Вернее возможен, но через задн универсальный интерфейс.

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

Паттерн Адаптер приходится делать если никаких стандартов\соглашений на интерфейсы нет. Ну получится еще набор clean code примерно как тут Паттерн проектирования «Адаптер» / «Adapter» / Хабр (habr.com) или тут Паттерн адаптер в Java (javarush.com)

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

Мне видится что договоренности о стандарте и использование анотации решает вопрос всего парой строк и сильно упрощает жизнь.

@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getFullName", TargetSetter = "setCounterPartName")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getPhone", TargetSetter = "setTelephone")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getINN", TargetSetter = "setTAXNumber")
class MyPaymentOrder extends PaymentOrder {};

Например в JSF сумели сделать стандарт для работы со страницами без javascript , но по каким то причинам не стали развивать эту тему . В итоге его удел это простенькие админ интерфейсы

Паттерн Адаптер приходится делать если никаких стандартов\соглашений на интерфейсы нет.

Мужик, ты непробиваемый. Я же писал

внутри адаптеров своих интерфейсов, предоставляющих данные для её платёжного поручения.

Сделал интерфейс - задал стандарт/соглашение общения со своим сервисом.

Тут выше уже писали, что "налицо феноменальная воинствующая некомпетентность", полностью поддерживаю. Объяснять что-то бесполезно, всё равно понимание о чём говорят отсутствует полностью.

Попробую показать код.

/**
 * Вендор 1СKiller сделал платформу ORM на Java JPA и 
 * некоторые базисные вещи (например компоненту\класс 
 * "справочник Контрагентов").
 */
@Entity
class OneCKillerEntity {
  long id;
  String name;
  String account;
  String individualTaxNumber;
}

class PaymentOrderVasilisa {
  /**
   * Василиса сделала на этой ORM компоненту\класс "Платежное поручение" 
   * и использовала часть функционала справочника контагентов 1СKiller 
   * (банковские счета , инн, наименование)
   */
  String badImplementaion(OneCKillerEntity data) {
    return String.format(
      "%d - %s %s", 
      data.getId(), 
      data.getAccount(), 
      data.getIndividualTaxNumber()
    );
  }

  /**
   * Внутри адаптеров своих интерфейсов, предоставляющих данные 
   * для её платёжного поручения.
   */
  String goodImplementation(PaymentOrderData data) {
    return String.format("%s - %s", data.getCode(), data.getDescription());
  }
}

/**
 * Свой интерфейс, предоставляющий данные для платёжки.
 */
interface PaymentOrderData {
  String getCode();
  String getDesctiption()
}

/**
 * Реализация интерфейса, использующая сущность из 1CKiller.
 */ 
class OneCKillerPaymentOrderData implements PaymentOrderData {
  final OneCKillerEntity entity;

  OneCKillerPaymentOrderData(OneCKillerEntity entity) {
    this.entity = entity;
  }

  public String getCode() {
    return Long.toString(entity.getId());
  }

  public String getDescription() {
    return data.getAccount() + ' ' + data.getIndividualTaxNumber();
  }
}

/**
 * Вася сделал свой справочник "Контрагенты Васи", 
 * который лучше (поддерживает функционал для нерезидентов и 
 * вообще) ., но имеет совершенно другую внутреннию структуру 
 * таблиц\сущностей
 */
class VasiliyEntity {
  BigInteger primaryKey;
  Account account;
  Customer customer;
}

/**
 * Этот класс - по факту единственное, что требуется от Пети, 
 * чтобы в его коде можно было использовать сущности Васи и
 * сервис для платёжек Василисы.
 */
class PeterPaymentOrderData implements PaymentOrderData {
  final PeterPaymentOrderData entity;

  PeterPaymentOrderData(VasiliyEntity entity) {
    this.entity = entity;
  }

  public String getCode() {
    return entity.getPrimaryKey().toString();
  }

  public String getDescription() {
    return data.getAccount().getNumber() + ' ' + data.getCustomer().getIndividualTaxNumber();
  }
}

Причём, когда появится Герман Акакиевич с Акулиной Кузьминичной и вообще наворотят работу через космический астрал, а не БД, то для использования Василисиного сервиса платёжек им всё равно будет достаточно только реализовать интерфейс PaymentOrderData.

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

У меня вопрос по последнему участку кода. Вы же по сути сделали мэппинг методов справочника контрагентов на сущности платежного поручения?

public String getCode() {
    return entity.getPrimaryKey().toString();
  }

  public String getDescription() {
    return data.getAccount().getNumber() + ' ' + data.getCustomer().getIndividualTaxNumber();
  }

Я сделал примерно тоже самое но через аннотацию и единую! процедуру обработки (parser) , где можно заложить общую логику обработки ошибок, логгирование и т.д. как плюс.

Итоговый код для Пети у меня получается короче (не прописываю обращения к методам контрагентов) . Почему с Вашей точки зрения реализация через аннтотацию хуже? Я понимаю что менее универсально, но мы говорим стандартизации и разработки совместимых компонентов.

@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getFullName", TargetSetter = "setCounterPartName")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getPhone", TargetSetter = "setTelephone")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getINN", TargetSetter = "setTAXNumber")
class MyPaymentOrder extends PaymentOrder {
};

единую! процедуру обработки (parser),

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

можно заложить общую логику обработки ошибок, логгирование и т.д. как плюс.

Если сильно нужна дополнительная логика обработки для гетеров - используй декоратор.

Итоговый код для Пети у меня получается короче (не прописываю обращения к методам контрагентов) .

И часто у вас команда длинами меряется? Возьми mapstruct, будут те же аннотации, код сгенерируется, руками писать ничего не придётся.

Почему с Вашей точки зрения реализация через аннтотацию хуже?

Потому что небезопасно, потому что не KISS. С таким подходом требуется лишний код для тестирования корректности имён, типов результата и аргументов методов. А если тестов на это не делать, то с очередным обновлением, когда в третьесторонней библиотеке метод грохнут (переименуют/перенесут в другой класс/поменяют тип возвращаемого результата), всё навернётся во время исполнения, и хорошо, если это исполнение будет на тестовом стенде, а не на проде.

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

Вендор 1СKiller сделал платформу ORM на Java JPA и некоторые базисные
вещи (например компоненту\класс "справочник Контрагентов"). Допустим ORM
поддерживает несколько СУБД , но классы используем только в одной
выбранной СУБД

ORM - это про доступ к данным лежащим в БД через парадигму ООП, правильно? Сделать "справочник Контрагентов" можно было в такой ситуации разве что как демонстрационный пример, как оно работает, сам смысл применения ORM в том что такие вещи делаются тривиально в том проекте где требуются, если с помощью этого ORM создание справочника это скольконибудь нетривиальная задача эту стыдобу лучше бы где-нибудь прикопать и никому не показывать, т.к. есть production-ready решения в которых это делается за час.

Но ок, допустим речь идет о Keycloak - комплексная система работы с аутентификацией/авторизацией пользователей, и вам очень захотелось взять ее к себе в проект и приделать еще что-то. Не вопрос - вы затягиваете ее к себе в проект через dependency и используете что там вам из нее надо. Там и модели построены, и описаны, и разворачивание на разные БД предусмотрено.

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

Вы захотели еще какой-то проект затащить и взять модели из него - да не вопрос, сверились что БД общее поддерживается, добавили скрипты подготовки БД (если надо) из этого проекта, затянули его к себе через dependency. Готово. Хотите создать модель которая будет иметь часть полей из одного проекта, а часть из другого - наздоровье, продумали план обработки сущностей (как читать/как сохранять/как обновлять) и вперед, ORM позаботиться о том чтобы все распихать по таблицам как вы решили.

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

ORM - это про доступ к данным лежащим в БД через парадигму ООП, правильно?

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

Вы захотели еще какой-то проект затащить и взять модели из него - да не вопрос, сверились что БД общее поддерживается, добавили скрипты подготовки БД (если надо) из этого проекта, затянули его к себе через dependency. 

Вот тут самое интересное начинается, если в "моделях" нет стандарта на уникальный ключ записей (guid или чтото подобное) , с типами Вы начнете искать "что БД общее поддерживается". А что может быть ключом для справочника пользовалей - да кто что придумает . Ктото ID с типом Integer , Кто то AccountID типа String, а кторо ФИО в трех полях и будет ждать когда тезка придет. И да кодом Вы решите и в Вашей IDE наверняка будет генератор классов для ORM.

Вот скажем я захочу этой модели прикрутить свой справочник UserRole а у меня ключ для идентификации пользователя AccountID String, а не Integer как текущей модели. В 1С эти проблемы решаются наличием guid во всех таблицах и соотвественно индексах. Вы наверное адаптер напишете ?

P S Я поэтому и попытался на аннотациях показать какой простой вариант я имею ввиду, чтобы делать миниму кода

Вот тут самое интересное начинается, если в "моделях" нет стандарта на
уникальный ключ записей (guid или чтото подобное) , с типами Вы начнете
искать "что БД общее поддерживается". А что может быть ключом для
справочника пользовалей - да кто что придумает . Ктото ID с типом
Integer , Кто то AccountID типа String, а кторо ФИО в трех полях и будет
ждать когда тезка придет. И да кодом Вы решите и в Вашей IDE наверняка
будет генератор классов для ORM.

Вы должно быть шутите. С чего вдруг меня вообще должно волновать какой там первичный ключ в чьей-то там модели? Я саму модель пишу в поле, а не ее ключ, ORM сам делает все что нужно там с этим ключом делать в той модели, хоть UUID там хоть sequence какой.

Истинно глаголю вам, откройте документацию тогоже Hibernate, посмотрите примеры.

Истинно глаголю вам, откройте документацию тогоже Hibernate, посмотрите примеры.

Это именно у Hibernate или у JPA тоже есть такой механизм ?

Даже если с ключами вопрос решен , следующий уровень это представление свойств

У Cправочника ролей есть getUserRoleByName() но перед этим нужно сделать setCurrenUser(UserID)

  • Скажем у одной реализации справочника пользователей один разработчик написал одну getRowsByName(Name) и для class Row метод getField() , (примерно в стиле ADO от Microsoft)

  • А в другой реализации getCurrentUserByName(Name) и дальше можно делать getUserID() , getUserFullName etc.

В отсуствии стандартов\соглашений на представление информации о сущностях нам адаптер писать?

В отсуствии стандартов\соглашений на представление информации о сущностях

Кто, блядь, мешает эти стандарты задать?! Для этого и придуманы интерфейсы, чтобы специфицировать формат общения с кодом.

нам адаптер писать?

Необязательно. В случае с "...class Row метод getField()..." лучше подойдёт фасад.

Это именно у Hibernate или у JPA тоже есть такой механизм

Судя по вопросу вы ни туда ни туда не смотрели, обратитесь к @Id

Я указал на Hibernate просто как на референсную реализацию, в его документации достаточно хорошо освещены все JPA возможности и его частные доработки (легко понять что к чему относиться по пакетам)

У Cправочника ролей есть getUserRoleByName() но перед этим нужно сделать setCurrenUser(UserID)

Вы не шутите? А эту вот информацию вы в сопроводительной записке к вашей реализации напишете?

В параллельной ветке увидел у вас такое:

class MyPaymentOrder extends PaymentOrder 

Вы похоже даже не понимаете насколько гиблое дело наследование в моделях. Нет, если вы живете по ватерфоллу, вы можете себе позволить спроектировать очень красивую, аккуратную, "эффективно немногословную" схему моделей. Но почти любое изменение в моделях будет аукаться у вас по всей выстроенной системе типов. Так не надо делать никогда, если только вы на 100% не уверены что абсолютно точно понимаете почему вы именно так поступаете. Как общий паттерн проектирования это абсолютно негодно.

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

Судя по вопросу вы ни туда ни туда не смотрели, обратитесь к @Id

Понял что имели ввиду, но он не стандартизирует представление ID для нашей задачи это всего лишь инструмент с подстройкой по модель данных СУБД

Василиса может у себя заложится на простой ключ для работы с контрагентом . Будет ждать чтото подобного от Васи

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Integer id; 

А Вася у себя сделает в справочнике контрагентов составной

    @EmbeddedId
    protected idPK ComplexPK;

И что Василисе тогда сохранять в качестве ID выбранного контрагента?

Поэтому 1С для всех своих метаданных использует обязательное поле guid , это дает много плюсов (напр прозрачный обмен данными, составные типы в ORM и прочее что в Java посчитают ересью )

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

"

У Cправочника ролей есть getUserRoleByName() но перед этим нужно сделать setCurrenUser(UserID)

Вы не шутите? А эту вот информацию вы в сопроводительной записке к вашей реализации напишете?

" setCurrenUser(UserID) это конечно к справочнику пользователей ошибся

Вы похоже даже не понимаете насколько гиблое дело наследование в моделях. Нет, если вы живете по ватерфоллу, вы можете себе позволить спроектировать очень красивую, аккуратную, "эффективно немногословную" схему моделей. Но почти любое изменение в моделях будет аукаться у вас по всей выстроенной системе типов. Так не надо делать никогда, если только вы на 100% не уверены что абсолютно точно понимаете почему вы именно так поступаете. Как общий паттерн проектирования это абсолютно негодно.

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

@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getFullName", TargetSetter = "setCounterPartName")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getPhone", TargetSetter = "setTelephone")
@LinkSubsystem(LinkedClass = "Suppliers", LinkedGetter = "getINN", TargetSetter = "setTAXNumber")
public PaymentOrder мyPaymentOrder;

Вообще когда Вы рассуждаете о годности паттернов проектирования возникает вопрос: Какую библию по архитектуре Вы читаете?

Когда я смотрю литературу по паттернам (и антипаттернам) я понимаю что это рецепты организации кода, часто с абстрактными примерами и из за этого читается тяжело. А хотелось бы видеть Best Practice потому что кроме качества кода есть еще Производительность, Обработка ошибок, Логгирование трассировка, Маштабирование и т.д. вот литература по Best practice как то не попадалась, только отдельные статьи иначе бы не появлялись посты типа

Есть ли польза от GoF-паттернов? / Хабр (habr.com)

Василиса может у себя заложится на простой ключ для работы с контрагентом

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

Если же мы говорим что справочник таки уже существует - мы просто берем его к себе в проект и смотрим какой там ключ.

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

Когда я смотрю литературу по паттернам (и антипаттернам) я понимаю что
это рецепты организации кода, часто с абстрактными примерами

Большинство конкретных примеров вы найдете либо в рабочих проектах коллег, либо в статьях/выступлениях ребят кто любит рассказывать что у них на проектах случалось и как они это решали. Из авторов по JPA/Hibernate могу рекомендовать Vlad Mihalcea и Thorben Janssen

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

В 1С к этому подошли очень близко , вот картинка

Справочник контрагентов с собственным интерфейсом (у него и форма элемента и списка все в одном "классе" описано

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

Я больше скажу - составным типом 1С я могу два справочника одновременно привязать в один реквизит и все благодаря единому формату ключа.

Необходимость ссылаться на реквизиты единственное, что приводит к более жесткой связи этих "классов" . Если это развязать красивым образом , то Code reuse улучшится на порядок. Чтото вроде компонентного подхода для ORM. Адаптеры с точки зрения RAD (Rapid application development) дадут слишком много кода.

Если про авто говорить - сейчас авто делают на так называемых платформах наберите MQB платформа. На ней получаются совершенно разные авто

Просто кроме Java которая застряла в бэкэнде, из за нежелания Oracle вкладываться в красивый Frontend (ну мы не будем показывать на JSF и JavaFX) есть системы где это удобно реализовали, и иногда полезно менять точку обзора

А хотелось бы видеть Best Practice

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

Какую библию по архитектуре Вы читаете?

Хороший, кстати, вопрос. К вам. Потому как, если судить по статье и диалогу в комментариях, - никакую.

Василиса может у себя заложится на простой ключ для работы с контрагентом

А Вася у себя сделает в справочнике контрагентов составной

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

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

Я вот думаю откуда появляются статьи типа "100 ошибок которых легко избежать" , "Как не нужно делать " . Это видимо из детства когда ребенку говорили нельзя, но при этом не говорили хотябы две альтернативы.

Я Вашу позицию понял и за код с адаптерами спасибо. Но когда речь идет о архитектурных вопросах мне интересно знать откуда автор черпает свои взгляды. Поверьте когда успешно гоняешь 1С на 5 терабайтах и видишь полных стек, начинаешь отличать абстрактные концепции от best practice

Но когда речь идет о архитектурных вопросах мне интересно знать откуда автор черпает свои взгляды.

Личный опыт и соотнесение его абстрактными примерами из книжек, статей, докладов на конференциях и прочим.

Поверьте когда успешно гоняешь 1С на 5 терабайтах

Так гоняйте дальше, дело-то хозяйское. Что ж в java-разработку полезли с вопросами, ответы на которые упорно не хотите принимать?

З.Ы. У меня складывается впечатление, что вы тупо не решаетесь попросить, чтобы кто-то за вас задизайнил систему "как в 1С, но на java". Так я вам вот что скажу, так не получится, слишком разные языки и подходы к разработке. Чтобы пересесть на с 1С на java придётся поломать некоторые привычки.

У меня складывается впечатление, что вы тупо не решаетесь попросить, чтобы кто-то за вас задизайнил систему "как в 1С, но на java". Так я вам вот что скажу, так не получится, слишком разные языки и подходы к разработке. Чтобы пересесть на с 1С на java придётся поломать некоторые привычки.

Зачем как в 1С, когда есть 1С :) . Можно ли сделать лучше чем в 1С при этом чтобы это выглядело как RAD , была возможность независимой разработки за счет стандартизации связей между (классами, компонентами , метаданными как больше нравится) .?

Поскольку Java вбирает в себя модные технологии, и сам хорошо стандартизирован была надежда что на нем можно выразить эту идею красиво. Адаптеры в RAD превращают его в noRAD с моей точки зрение.

Чтобы пересесть на с 1С на java придётся поломать некоторые привычки.

Да привычки в Jave согласен совершенно другие, таже архитектура JavaEE как они ее сами называют

1.3 Distributed Multitiered Applications - Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7) (oracle.com)

никогда нет ощущения что ты пишешь приложение, а только всегда некую часть.

это выглядело как RAD

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

Всё, я сливаюсь. Обсуждать одно и то же по 100500 раз надоело.

архитектура JavaEE

Это который за ненадобностью отдали в сообщество ещё в 2018? И с тех пор оно (сообщество) пытается хоть как-то сделать так, чтобы его (JakartaEE) использование не причиняло попоболь?

Вот только большинство новых проектов выбирает spring/quarkus/micronaut/ktor/etc., а не EE.

Хороший пример, ага.

"100 ошибок которых легко избежать" , "Как не нужно делать " . Это, видимо, из детства когда ребенку говорили нельзя, но при этом не говорили хотя бы две альтернативы.

Не, зачастую, такие статьи пишут либо:

а) внезапно прозревшие джуны;

б) опытные товарищи для непрозревших джунов.

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

Я, кажется, понял. Т.е. класс Контрагент для postgres, mysql, oracle, dbf - это 4 разные реализации, так? Тогда я могу с уверенностью сказать, что дизайн системы - говно. Так быть не должно и работать на длинной дистанции не будет. И уж тем более, ни о каком убийстве 1С можно не мечтать.

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

если в "моделях" нет стандарта на уникальный ключ записей (guid или чтото подобное)

То я создам этот стандарт через объявление интерфейсов и базовых классов. И всем пользователям придётся ему следовать.

с типами Вы начнете искать "что БД общее поддерживается"

Неа, я буду использовать то, что мне нужно. Если какая-то БД что-то не поддерживает, то либо эта БД не будет поддерживаться моим приложением вообще, либо я расширю диалект ORM-а, чтобы научить работать БД с конкретным типом.

Вы наверное адаптер напишете ?

Можно и так, почему нет? Ещё можно просто в мапинге задать полю пользовательский тип, в котором руками описать все необходимые преобразования. А можно забить и просто через промежуточную таблицу соединить, например.

Я, кажется, понял. Т.е. класс Контрагент для postgres, mysql, oracle, dbf - это 4 разные реализации, так? Тогда я могу с уверенностью сказать, что дизайн системы - говно. Так быть не должно и работать на длинной дистанции не будет. И уж тем более, ни о каком убийстве 1С можно не мечтать.

Зачем так, в том же 1С структура таблиц для разных субд одинакова вплоть до индексов. Просто в ORM никто не запрещает представить Контранетов и связанный с ним справочник Телефонов как одина класс Контрагенты . Я только это имел ввиду.

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

А внутри базы вот так, но это никого не волнует поскольку все работают через ORM

Понятнее не стало. Что-то похожее на EAV? Тогда лучше сразу забыть про JPA.

Обычная реляционная модель, таблица контактной информации имеет поле ссылки на справочник контрагентов. А "класс"\объект метаданных в терминах 1С с точки зрения Java это класс обертка для этих двух сущностей и он ими управляет. На Java такое несложно реализовать и без JPA, конечно в базе JPA управляет Одна сущность Одна таблица, но путем Mapping a Single Entity to Multiple Tables in JPA | Baeldung можно достичь желаемого и в JPA.

Sign up to leave a comment.

Articles