Зачем глупости писать о 99% не пользуйте просто допотопные технологии. Загрузка файлов:
Даже в PHP это уже порешали давно. Нет, не CGI едины. Да, и на PHP можно поднять демона и слушать порт, даже кодеки для сообщений уже написаны. Не хотите поднимать демона и порт слушать, хотите древний-добрый PHP-FPM — да пожалуйста. Просто не пользуйте $_FILES. Просто читайте php://input как поток, определяйте нежелательные файлы (например когда контент не соответствует заголовку) и не принимайте их. А ещё лучше — выбросьте ваш PHP и поставьте Netty. Не надо сохранять что не попадя на диск. Кеш:
В чём пробема "учитывая современные реалии, когда на странице много динамических элементов"? Технике кеширования и включения частей страницы на Nginx уже лет и лет.
В чём проблема GET /somepage.html?someshit=12345? Кешируйте определённый location в Nginx (если базовых возможностей мало — OpenResty в помощь) и не будет никто при сгенерённом кеше попадать на приложение тем самым тратя драгоценный ресурс.
Далее: "при генерации страницы можно сделать 500 запросов к мемкешеду и за это ничего не будет" — вот это уже ну совсем ни в какие ворота не лезет. Во-первых — не нужно путать кеширование внутри приложения и кеширование страницы/области страницы целиком. Они для разного предназначены и использовать одно вместо другого — нельзя. Во-вторых — любое хождение за данными через порт (особенно синхронное что характерно для memcached через PHP) — очень долго больно и дорого. Не говоря уже о 500 запросах. С memcached тоже нужно уметь работать и, например, предагрегировать данные при сохранении или другие техники применять в зависимости от задачи. Нельзя просто тянуть значение по ключу. Интерфейсы:
В чём проблема с API? Выучите заголовок Accept уже в конце концов. Читайте Content-type при ответе и игнорируйте то что вы не Accept'ите. Кривое API — не проблема API в целом. Это проблема конкретных поставщиков конкретных данных. Не нравится этот поставщик — выбирайте другого. Благо рынок широк и на рынке найдутся приложения удовлетворяющие форматам если сами данные добыть можно.
"А иногда и вообще, выдачу всех ключей приостанавливают, а обслуживание прекращают, даже на коммерческой основе, такое тоже бывает. Ну и зачем такое API? Мне проще стянуть страничку и распарсить ее регулярками, чем терпеть такое безобразие. Потому я почти никогда не пользуюсь этими вашими API" — то же самое может и со страничкой случиться. Она просто в один прекрасный момент сранет отдавать 404 или 50*. Тоже не проблема API как такового. Да и чем страничка не API если её всё равно регулярками парсить? JSON и XML да какой угодно текст вне зависимости от формата можно регулярками парсить. В чём проблема то?
Комментирование к оригинальной статье закрыто, но это не означает что перед распространением этой статьи не нужно было ознакомиться с комментариями к ней. В этих комментариях ясно и лаконично определено какие именно ошибки в проектировании (да, именно ошибки), привели автора к этой идее. Автор оригинальной статьи не способен смоделировать предметную область и ошибки в этом моделировании валит на RDM. Автор оригинальной статьи явно не знаком с трудами Роберта Мартина в полной мере. Сам Дядя Боб неоднократно высказывался против применения Simple Data Structures как основного элемента программ. Его примеры и обьяснения принципов изобилируют применением инстансов, которые несут операции, а не данные. Да, он сам говорил что для внутренней реализации могут быть использованны данные, но контракт юнита не должен давать к ним прямого доступа.
Далее: автор оригинальной статьи использует ActiveRecord, наследует сущьность и говорит что это из-за RDM он не может легко заменить хранилище на то, которое не поддерживается его базовым классом. Тем самым нарушая рекомендации (см. пункт Persistence) Uncle Bob'а и снова сваливая всю ответственность на RDM.
Тестируемость: Uncle Bob, как большой поклонник и пропагондист TDD, разумеется посвятил этой теме не мало материала, с короым автор оригинальной статьи так же не ознакомился перед её написанием. Тестироваться, прежде всего, должен контракт, а не внутренняя структура (детали реализации) т.к. детали реализации могут меняться, но контракт должен выполняться, о чём как Роберт Мартин так и Мартин Фаулер и Стив Макконелл неоднократно писали. Автор же, нарушая essence тестирования и покрывая функционал тестом "лишь бы тесты были" принципиально не правильно применяет тестирование получая сложность test maintain и, как и везде, обвиняя в этом RDM, а не себя.
Предложеный в статье рефакторинг, который бы привёл к состоянию близкому к ADM так же не является оптимальным. К таким последствиям может привести использование в приложении структуры данных идентичной к той в которой данные хранятся в постоянном хранилище, что не является обязательным. Структура, в которой данные хранятся (напр. таблица и row в ней), не должна влиять на дизайн самого приложения.
1. Несколько не понятно — если с точки зрения бизнеса или моделируемого вами бизнес-процесса это одна и та же запись (вы же в корне для этого добавляли isEquivalent) — то почему бы ORM считать это разными записями?
2. Вам надо хранить свойства что не участвуют в вашей бизнес модели? Нет? — чего они тогда не участвуют в эквивалентности. Сравнение сложным образом свойства — точно так же только Equals уже на свойстве вызывается.
В зависимости от того что вам нужно/чего достаточно. Если PHP-style request->db->response и пользователей будет 2k-потолок то и Spring Boot хватит с головой.
Если данные либо имеют потоковую природу или request->response, но уже с болше чем 2k планируемых пользователей то Play! По его API — там сейчас новые фичи (некоторые) пилятся сначала на Java, а уже потом портируются в Scala. Для остальных есть правило: вы не можете отправить пулл с фичёй в Play только для одного из API — вам нужно будет давать поддержку вашей фичи как для Java так и дл Scala. Лично я не понимаю зачем это правило ввели — всегда отличто пользовался Java кодом из Scala и Scala кодом из Java.
Детальнее можно почитать тут. Оно то рекламный whitepaper, но там описаны как сильные так и слабые стороны и почему надо и когда не надо.
Если к спрингу прикипели, а более 2k всё равно надо — то Netty и Spring Boot Webflux поверх. Только не сервлет 3.0. Почему — всё в том же whitepaper.
По поводу ABBYY CLI OCR for Linux — как внедряли, что пробовали перед этим (каких конкурентов и какие подходы рассматривали кроме Google)
и конкретно о кейсе когда "8" распознаётся как "0" — как с таким боретесь, применимо ли к данной системе модное нынче слово "обучить", если нет — какими методами достигается улучшение производительности распознавания? Рассматривали ли уже/рассматриваете ли сейчас модный нынче подход с сетями, или оно вам не надо?
Зачем глупости писать о 99% не пользуйте просто допотопные технологии.
Загрузка файлов:
Даже в PHP это уже порешали давно. Нет, не CGI едины. Да, и на PHP можно поднять демона и слушать порт, даже кодеки для сообщений уже написаны. Не хотите поднимать демона и порт слушать, хотите древний-добрый PHP-FPM — да пожалуйста. Просто не пользуйте $_FILES. Просто читайте php://input как поток, определяйте нежелательные файлы (например когда контент не соответствует заголовку) и не принимайте их. А ещё лучше — выбросьте ваш PHP и поставьте Netty. Не надо сохранять что не попадя на диск.
Кеш:
В чём пробема "учитывая современные реалии, когда на странице много динамических элементов"? Технике кеширования и включения частей страницы на Nginx уже лет и лет.
В чём проблема GET /somepage.html?someshit=12345? Кешируйте определённый location в Nginx (если базовых возможностей мало — OpenResty в помощь) и не будет никто при сгенерённом кеше попадать на приложение тем самым тратя драгоценный ресурс.
Далее: "при генерации страницы можно сделать 500 запросов к мемкешеду и за это ничего не будет" — вот это уже ну совсем ни в какие ворота не лезет. Во-первых — не нужно путать кеширование внутри приложения и кеширование страницы/области страницы целиком. Они для разного предназначены и использовать одно вместо другого — нельзя. Во-вторых — любое хождение за данными через порт (особенно синхронное что характерно для memcached через PHP) — очень долго больно и дорого. Не говоря уже о 500 запросах. С memcached тоже нужно уметь работать и, например, предагрегировать данные при сохранении или другие техники применять в зависимости от задачи. Нельзя просто тянуть значение по ключу.
Интерфейсы:
В чём проблема с API? Выучите заголовок Accept уже в конце концов. Читайте Content-type при ответе и игнорируйте то что вы не Accept'ите. Кривое API — не проблема API в целом. Это проблема конкретных поставщиков конкретных данных. Не нравится этот поставщик — выбирайте другого. Благо рынок широк и на рынке найдутся приложения удовлетворяющие форматам если сами данные добыть можно.
"А иногда и вообще, выдачу всех ключей приостанавливают, а обслуживание прекращают, даже на коммерческой основе, такое тоже бывает. Ну и зачем такое API? Мне проще стянуть страничку и распарсить ее регулярками, чем терпеть такое безобразие. Потому я почти никогда не пользуюсь этими вашими API" — то же самое может и со страничкой случиться. Она просто в один прекрасный момент сранет отдавать 404 или 50*. Тоже не проблема API как такового. Да и чем страничка не API если её всё равно регулярками парсить? JSON и XML да какой угодно текст вне зависимости от формата можно регулярками парсить. В чём проблема то?
Комментирование к оригинальной статье закрыто, но это не означает что перед распространением этой статьи не нужно было ознакомиться с комментариями к ней. В этих комментариях ясно и лаконично определено какие именно ошибки в проектировании (да, именно ошибки), привели автора к этой идее. Автор оригинальной статьи не способен смоделировать предметную область и ошибки в этом моделировании валит на RDM. Автор оригинальной статьи явно не знаком с трудами Роберта Мартина в полной мере. Сам Дядя Боб неоднократно высказывался против применения Simple Data Structures как основного элемента программ. Его примеры и обьяснения принципов изобилируют применением инстансов, которые несут операции, а не данные. Да, он сам говорил что для внутренней реализации могут быть использованны данные, но контракт юнита не должен давать к ним прямого доступа.
Далее: автор оригинальной статьи использует ActiveRecord, наследует сущьность и говорит что это из-за RDM он не может легко заменить хранилище на то, которое не поддерживается его базовым классом. Тем самым нарушая рекомендации (см. пункт Persistence) Uncle Bob'а и снова сваливая всю ответственность на RDM.
Тестируемость: Uncle Bob, как большой поклонник и пропагондист TDD, разумеется посвятил этой теме не мало материала, с короым автор оригинальной статьи так же не ознакомился перед её написанием. Тестироваться, прежде всего, должен контракт, а не внутренняя структура (детали реализации) т.к. детали реализации могут меняться, но контракт должен выполняться, о чём как Роберт Мартин так и Мартин Фаулер и Стив Макконелл неоднократно писали. Автор же, нарушая essence тестирования и покрывая функционал тестом "лишь бы тесты были" принципиально не правильно применяет тестирование получая сложность test maintain и, как и везде, обвиняя в этом RDM, а не себя.
Предложеный в статье рефакторинг, который бы привёл к состоянию близкому к ADM так же не является оптимальным. К таким последствиям может привести использование в приложении структуры данных идентичной к той в которой данные хранятся в постоянном хранилище, что не является обязательным. Структура, в которой данные хранятся (напр. таблица и row в ней), не должна влиять на дизайн самого приложения.
2. Вам надо хранить свойства что не участвуют в вашей бизнес модели? Нет? — чего они тогда не участвуют в эквивалентности. Сравнение сложным образом свойства — точно так же только Equals уже на свойстве вызывается.
В зависимости от того что вам нужно/чего достаточно. Если PHP-style request->db->response и пользователей будет 2k-потолок то и Spring Boot хватит с головой.
Если данные либо имеют потоковую природу или request->response, но уже с болше чем 2k планируемых пользователей то Play! По его API — там сейчас новые фичи (некоторые) пилятся сначала на Java, а уже потом портируются в Scala. Для остальных есть правило: вы не можете отправить пулл с фичёй в Play только для одного из API — вам нужно будет давать поддержку вашей фичи как для Java так и дл Scala. Лично я не понимаю зачем это правило ввели — всегда отличто пользовался Java кодом из Scala и Scala кодом из Java.
Детальнее можно почитать тут. Оно то рекламный whitepaper, но там описаны как сильные так и слабые стороны и почему надо и когда не надо.
Если к спрингу прикипели, а более 2k всё равно надо — то Netty и Spring Boot Webflux поверх. Только не сервлет 3.0. Почему — всё в том же whitepaper.
Видимо пермишны на атрибуты вешать и в fine-grained авторизацию уходить.
По поводу ABBYY CLI OCR for Linux — как внедряли, что пробовали перед этим (каких конкурентов и какие подходы рассматривали кроме Google)
и конкретно о кейсе когда "8" распознаётся как "0" — как с таким боретесь, применимо ли к данной системе модное нынче слово "обучить", если нет — какими методами достигается улучшение производительности распознавания? Рассматривали ли уже/рассматриваете ли сейчас модный нынче подход с сетями, или оно вам не надо?