Construindo um banco de dados de conversão de strings para vários projetos (internos)

9

Em nossa empresa, temos uma tabela ms-sql de tradução existente que armazena seqüências de caracteres como esta:

Id |     Key     | Language | Value 
 1 | hello-world |  nl-BE   | Hallo Wereld
 2 | hello-world |  en-GB   | Hello World

Existem três idiomas no sistema e espero que ele cresça para um máximo de cerca de 10 no futuro

Esta tabela é lida por vários projetos muito diferentes (cerca de 60 projetos, principalmente sites / aplicativos da web e alguns serviços da web), que abrem uma conexão com o banco de dados de tradução, armazenam em cache as traduções

O feedback dos desenvolvedores front-end é que nossa interface do usuário para inserir ou modificar a maior desvantagem das traduções é que elas não podem saber qual projeto usa quais strings.

Às vezes, eles modificam as strings sem saber que estão quebrando 7 projetos.

Agora eles só precisam digitar algo assim this.Translate("Hello World")e o sistema cuida do resto.

É claro que eu poderia forçá-los a algo como, this.Translate("Hello World","AwesomeApplication1")mas parece que isso exigirá bastante refatoração em muitos projetos.

Como você forneceria essa solução? Como você, como desenvolvedor, forneceria o "nome do projeto" para a tradução? Como você armazenaria isso no banco de dados?

Nota importante: a reutilização da tradução é o ponto principal do banco de dados centralizado, portanto, o escopo das traduções para um projeto é

1|hello-world|nl-BE|Hallo Wereld|MyAwesomeApplicatoin1
5|hello-world|nl-BE|Hallo Wereld!|MyAwesomeApplicatoin2

não é realmente uma opção desejada.

Eu preferiria algo como:

1|hello-world|nl-BE|Hallo Wereld|MyAwesomeApplicatoin1,MyAwesomeApplicatoin2

ou uma chave estrangeira equivalente a apenas colocar os nomes na tabela.

ATUALIZAR

Com base no conselho para normalizar o banco de dados, criei algo assim até agora:

//this allows me to distinquish if translations where added by developer or by translator

UPDATE2: adicionado edmx em vez de texto. Se as pessoas estiverem interessadas, eu poderia fazer o github do projeto WCF, estou envolvendo esse conceito para que outras pessoas possam testá-lo e usá-lo.

Mvision
fonte
Ty para normalização. votou q e a. Eu acredito que um github em Java ajudaria.
tgkprog

Respostas:

5

Nota preliminar 1: você não está nos dizendo como as traduções são mantidas no momento

Nota preliminar nº 2: seu banco de dados não está normalizado. Qualquer que seja a solução a ser adotada , primeiro normalize seu banco de dados . Você se depara com problemas terríveis de manutenção mais tarde, se não fizer isso agora

Isto é o que eu faria.

  1. Reescreva sua chamada de tradução para que ela carregue um ID do programa de volta para o servidor

  2. O tradutor de back-end colocará a string na tabela do banco de dados, se ainda não existir, e a marcará com o ID do programa

  3. Se a sequência já existir, ela será atualizada apenas se o ID do programa corresponder ao ID original do programa com o qual a sequência foi criada. Caso contrário, retorne uma notificação de conflito.

Variações:

  • Você pode usar um 'ID do desenvolvedor / ID do tradutor' em vez de um ID do programa. Considero isso melhor porque há pessoas que conhecem uma língua estrangeira e outras que pensam que sabem. Somente o primeiro grupo tem direitos de modificação.

  • Convém armazenar os IDs de todos os programas que usam a sequência no banco de dados, para saber quais programas entram em conflito.

  • Você pode estender esse pensamento de 'propriedade' a cada idioma individual: uma pessoa pode fazer inglês e a outra holandesa.

  • Depois que seu banco de dados é normalizado, você adiciona complexidade de construção como "O programa A está nos idiomas 1,2,3; B está nos 3 e 5"

Eu também sugiro que você escreva um programa separado de 'manutenção da tradução' que mostre as traduções ausentes etc. Uma vez fiz isso com autorização em dois níveis: cada tradução deve ser examinada por uma segunda pessoa (geralmente um falante nativo).

Jan Doggen
fonte
11
Eu atualizei a minha pergunta com base em suas idéias
Mvision
5

Como eles estão referenciando um 'this' ... você pode atribuir o nome do projeto uma vez a 'this' (via construtor, por exemplo) e a interface para as funções de tradução não mudaria para os codificadores. Sob o capô, apenas adiciona o nome do projeto à consulta ao banco de dados. Como alternativa, você pode fornecer a 'this' um meio de conhecer o nome do projeto por conta própria. Realmente vai depender de como você tem suas aulas estruturadas.

Para armazenamento, você pode fazer algo como:

1 ! hello-world ! nl-EN ! Hello World  ! *
2 ! hello-world ! nl-EN ! Howdy, World ! CowboyApp
3 ! hello-world ! nl-EN ! Arrgh        ! PirateApp

Use um curinga para aplicar uma tradução geral a todos os aplicativos, mas o nome específico do aplicativo quando você deseja substituir uma tradução para um aplicativo específico. Isso manterá as duplicações no mínimo.

Para ver qual programa está usando quais traduções, agora você sabe disso - se você não deseja analisar e coletar manualmente essas informações, pode registrar as solicitações de tradução.

GrandmasterB
fonte
A ideia de movê-lo para a classe 'this' parece boa para mim, acho que vou mudar o nome do projeto para o arquivo web / app.config e ler a partir daí. Você acha que a idéia de curinga / nomes de projeto é escalável para algo como 4000 traduções?
Mvision
3
Como aprimoramento, um gatilho pode ser adicionado ao banco de dados ou ao DBAL que atualiza a coluna "programas registrados" sempre que uma palavra traduzida é lida.
Como o gatilho do banco de dados poderia saber o nome do projeto? (Estamos usando a estrutura de entidade 4)
Mvision 28/02
@ Visão Não vejo por que não - o volume não deve ser um grande problema. Se muitas das traduções específicas do aplicativo estão simplesmente inserindo o nome do aplicativo, você também pode usar constantes para reduzir os dups.
precisa
NVV eu entendi errado. sim um gatilho poderia fazer, e as coisas wouldspeed se comparado a verificar e atualizar esse material através EF na leitura .... boa chamada
Mvision
1

Se todos os seus projetos forem escritos em C #, e todas as chamadas de tradutor ficarem assim

this.Translate("hello-world")

onde "olá mundo" é a chave na sua tabela de tradução, não deve ser muito difícil escrever um pequeno scanner de código-fonte usando expressões regulares para encontrar todas as chamadas do tradutor e atribuir às palavras-chave os nomes correspondentes do projeto. Dessa forma, você não precisa alterar nenhuma das interfaces de código ou tradutor existentes.

Dependendo da estrutura real do seu programa, como alternativa, pode ser mais fácil extrair essas informações do código IL de seus assemblies. Fiz algo muito semelhante há algum tempo, também para fins de tradução, usando este código de exemplo para analisar assemblies.

Doc Brown
fonte
Eu gostava desse tipo de solução. Mas exigiria que todos os 60 projetos (alguns nem mesmo os meus) fossem totalmente testados antes de começar a produção com este novo sistema. A solução sugerida para mover o nome do projeto para o código de chamada funciona bem e causará muito menos problemas, de qualquer maneira, obrigado!
Mvision
11
@ Vision: Eu acho que o oposto é verdadeiro. Se você determinar o nome do projeto para as traduções em tempo de execução, precisará garantir que todas as páginas da Web com todas as traduções de todos os seus 60 projetos sejam chamadas uma vez para garantir que todas sejam registradas. A varredura estática da fonte ou dos conjuntos, no entanto, fornece uma lista completa sem a necessidade de testes ou a execução de todo o sistema.
Doc Brown