Pull to refresh
6
0
Андрей Бычко @courage_andrey

инженер-программист

Send message
IMHO, смысла что-то срочно куда-либо мигрировать вообще очень мало. Мой опыт показывает, что реальной необходимости миграции в большинстве случаев нет. Есть требования заказчика, сформированные в результате прочтения статей о том, что «все системы такого-то типа должны обладать таким-то набором функций» (список из 10-20 позиций, из которых заказчик будет использовать хорошо если 2-3). Есть стремление всего более нового, вне зависимости от того, сколько будет стоить обновить инфраструктуру до требуемого уровня. Есть надежды на серебрянную пулю (типа «вот переведу свою систему в облака/микросервисы — и сразу заживу!»). А есть, наоборот, дремучее легаси, которое написано ещё до твоего рождения и уже не одно десятилетие портит людям кровь, но никто его не будет менять из риска хоть что-то потерять — а с ним тоже взаимодействовать надо. Повторяю, это только IMHO, но я очень мало видел примеров того, как миграция на новые инструменты или версии приносила реальные преимущества, а не тонну геморроя.

Пример: примерно раз в два года наша компания «перезжает» на новую версию Visual Studio. Разрабатываемое решение большое, проектов в нём много, разных типов, покрытие тестами — моё почтение. Каждый раз при переезде примерно месяц у всей команды (не одна сотня человек) проект будет или не открываться, или не компилироваться, или не работать, или значительная часть тестов упадёт. Я не говорю уже про тормоза и зависания новой версии первые полгода или отваливающиеся расширения и дополнения среды разработки.

grpc — не исключение. WCF нет в актуальных версиях? А что из предоставляемых в актуальных версиях планируется использовать? А почему архитектура организована таким образом, что проект зависит от фреймворков? А если с архитектурой всё хорошо, то откуда проблемы с миграцией?

P.S.: Извините за «простыню». Так получается…
Господа, не стоит холиварить за инструменты. Их было много, и их ещё больше будет. За свои 20 лет активного программирования я насмотрелся всякого: и забивания гвоздей микроскопами (с неизменным выводом «эти ваши микроскопы все гамно»), и выдающегося применения совершенно неподходящих для этого вещей («в умелых руках и срамной уд — балалайка»). Весь смысл статьи (помимо очевидной горькой самоиронии) заключён во втором её выводе: последовательное повторное решение задачи с помощью изменяющихся инструментов ведёт к углубленному изучению этих самых инструментов и связанных с ними технологий.
Я предпочитаю про жив/мёртв не спорить, потому что встречал самые удивительные примеры использования инструментов и технологий, включая MS-DOS в 2006 году. Кроме того, есть отрасли, в которых исторически сложилось отставание на 2-3 года от мировых трендов.
Не будет, к сожалению. Не взлетело.
Обратите внимание на начало статьи — проект писался в 2014 (как видите, слоупоком я был уже тогда :) ). Сейчас просто захотел поделиться опытом.
1. Согласен.
2. Дефолтная локаль и у меня есть. То есть, при выходе новой версии можно переключиться на язык по умолчанию, посмотреть на нужную строку в программе, скормить её автопереводчику и записать в локализацию самому. Способ костыльный, зато позволяет не простаивать в ожидании официальной локализации.
Да, такая проблема есть. Впрочем, это не намного хуже, чем «текст, вшитый в приложение», который чаще всего является нечитаемой аббревиатурой с кучей подчёркиваний.
Gettext я не использовал. Всё-таки это стороннее решение, которое надо ещё решить использовать. А иерархия нужна, потому что перевести фразу правильно можно только тогда, когда знаешь контекст, в котором она употребляется. Если ты видишь, в каком месте и какой формы она она прицеплена (есть подробный иерархический ключ), то и перевести просто. Если просто видишь фразу, висящую в вакууме, то и при переводе сделать максимум получится сферического коня. Пример из текущего проекта с нынешней работы: 6 строк, лежащих в разных местах, в английской локализации имеют вид «Successfull». В японской локали все шесть строк разные, хоть и говорят об успешном завершении.
У класса TypeDescriptor есть метод Refresh. Есть возможность вызвать его при переключении языка?
В чём принципиальная разница?
Если все хранить в одном файле (аля rus.xml) то добавление новых значений существенно усложняют жизнь локализаторам.
Чтобы не усложнять переводчикам жизнь, можно отправлять им Diff текущих изменений, чтобы знали, что и где править. Я уже говорил выше в других комментариях, что предпочитаю всё хранить в единственном файле, а не размазывать локализованные ресурсы по дочерним папкам. Предложенный способ локализации не универсален, а потому следовать ему или нет — вопрос требований, стоящих при разработке.
Мой следующий комментарий почти успел =)
А пробовали реализовать своему типу custom TypeDescriptor с переопределённым методом GetAttributes? То есть, чтобы Attributes[typeof(DisplayNameAttribute)] as DisplayNameAttribute возвращал атрибут с локализованным значением.
Буква дня: C = Сурово. Тогда исходники можно не искать. В C я умею, но сейчас на нём не пишу, так что решение будет уже не актуально.
Если я правильно понял, поиск ресурса осуществлялся по строке-ключу?
У меня такая задача не стояла, но могу рассказать, с чего бы я начал свои поиски решения (в рамках указанного в статье подхода). Все три указанных типа имеют виртуальные методы, которые могут быть перегружены в наследнике, который Вы создадите.
class DisplayNameExtendedAttribute : DisplayNameAttribute
{
	public override string DisplayName
	{
		get { return %language%.%Member%; }
	}
}

Откуда в данном примере брать язык — вопрос №1. (Сидящий на левом плече чёрт уже кричит в ухо: «Singleto-o-on!») Второй вопрос — как получить нужный член. Очевидная идея — передать туда base.DisplayName — не слишком сочетается с требованием не использовать строки. Дальше надо думать.
Реализация Gettext для NET существует, но наличие иерархической структуры в локализованных данных (это не только от пункт 4, это 1-4) было реально важно для тех проектов, для которых я делал локализацию. Кроме того, подключение Gettext потребует подключения дополнительных сторонних библиотек, а предложенный подход основывается на использовании только стандартных «кирпичей». Статья описывает способ локализации проекта, для которого важны перечисленные в начале статьи требования, но ни разу не золотую пулю для решения всех проблем локализации.
1, 4 и (2). А зачем писать обёртку, если её можно не писать? Класс Language и играет роль такой обёртки, только ему для работы не требуется вообще никакой дополнительной логики — только свойства со значениями.

3. Не «нельзя», а «нужно». Нельзя требования под реализацию подгонять. А если есть требование хранить структурированную информацию, то надо искать способ такое реализовать. В указанном примере можно схитрить, если ввести нейтральные строки «дней осталось: {0}» — я думаю, в каждом языке найдутся такие конструкции.

5. А в чём принципиальное отличие от редактирования resx файла?

Я не утверждаю, что придумал идеальный способ локализации. Потому и написал в заголовке статьи «Ещё один...» И, судя по первому комментарию, не я один люблю всё упрощать.
Перезалил, ссылка теперь ведёт на GITHUB.
Перезалил, ссылка теперь ведёт на GITHUB.

Information

Rating
Does not participate
Location
Warszawa, Warszawa, Польша
Registered
Activity