Pregunta

La mayoría de la gente estaría de acuerdo en que internacionalizar una aplicación existente es más costoso que desarrollar una aplicación internacionalizada desde cero.

¿Es eso realmente cierto?¿O cuando escribes una aplicación internacionalizada desde cero, el costo de hacer I18N simplemente se amortiza en múltiples tareas pequeñas y nadie siente sobre sus hombros todo el peso de la tarea de internacionalización?

Incluso puede afirmar que una aplicación madura tiene muchas LOC que se eliminaron durante el historial del proyecto, y que no necesitan ser I18Ned si la internacionalización se realiza después, pero habrían sido I18N si el proyecto se internacionalizó. desde el principio.

Entonces, ¿crees que un proyecto que comienza hoy? debe internacionalizarse, o se puede aplazar esa decisión para el futuro en función del éxito (o no) del software y de la distribución geográfica de la demanda.

No me refiero a la capacidad de manipular datos Unicode.Que tienes de forma gratuita en la mayoría de los lenguajes, bases de datos y bibliotecas principales.Me refiero específicamente a admitir la interfaz de usuario de su propio software en múltiples idiomas y configuraciones regionales.

¿Fue útil?

Solución

"cuando se escribe una aplicación internacionalizada desde cero el costo de hacer I18N es ... amortizado"

Sin embargo, eso no es toda la historia.

Retroactivamente rastrear todos los mensajes a los usuarios es - en algunos casos -. Imposible

No es difícil. Imposible.

Considere esto.

theMessage = "Some initial part" + some_function() + "some following part";

vamos a tener un terrible tiempo encontrar todos estos tipos de situaciones. Después de todo, some_function sólo devuelve una cadena. Usted no sabe si se trata de una clave de base de datos (no se muestra a una persona) o un mensaje que debe ser traducido. Y cuando se traduce, reglas gramaticales pueden revelar que una concatenación de cadenas 3-parte era una idea tonta.

No se puede simplemente GrEP cada función con valor de cadena que contiene como un posible mensaje de I18N que debe ser traducido. Hay que leer el código realidad, y posiblemente volver a escribir la función.

Es evidente que cuando some_function tiene ninguna complejidad a él en absoluto, no tienes ni idea de por qué una parte de su aplicación está todavía en Suecia, mientras que el resto se I18N'd con éxito en otros idiomas. (No meterse con los suecos, en particular, sustituir esto con cualquier idioma utilizado para el desarrollo de diferentes despliegue final.)

Peor aún, por supuesto, si está trabajando en C o C ++, es posible que tenga algo de esta división entre las macros pre-procesador y la sintaxis correcta en lenguaje C.

Y en un lenguaje dinámico - donde el código se puede construir sobre la marcha - se le paralizado por un diseño en el que no se puede identificar positivamente a todo el código. Mientras que la generación dinámica de código es una mala idea, sino que también hace su trabajo I18N retroactiva imposible.

Otros consejos

Me voy a tener que estar en desacuerdo de que cuesta más que añadir a una aplicación existente que a partir de cero con una nueva.

  • Una gran parte del tiempo i18n no es necesaria hasta que la aplicación se pone 'grande'. Cuando usted consigue grande, es probable que tenga un equipo de desarrollo más grande para dedicar a i18n por lo que será menos de una carga.
  • Usted puede realmente no lo necesita. Una gran cantidad de equipos pequeños puesto un gran esfuerzo por la internacionalización de apoyo cuando no tiene clientes que lo requieran.
  • Una vez que haya internacionalizado, que hace que los cambios incrementales más tiempo. No se necesita una gran cantidad de tiempo extra, pero cada vez que es necesario agregar una cadena con el producto, es necesario agregar que al haz primero y luego agregar una referencia. No, no es mucho trabajo pero es esfuerzo y toma un poco de tiempo.

Yo prefiero 'cruzar ese puente cuando lleguemos a él' e internacionalizar sólo cuando se tiene un cliente que paga en busca de ella.

Sí, la internacionalización de una aplicación existente es, sin duda más caro que el desarrollo de la aplicación como internacionalizado desde el primer día. Y es casi nunca es trivial.

Por ejemplo

Message = "Do you want to load the " & fileType() & " file?"

no puede ser internacionalizado sin algunas alteraciones de código debido a que muchos idiomas tienen reglas gramaticales como la concordancia de género. A menudo se necesita una cadena de mensaje diferente para cargar cada posible tipo de archivo, a diferencia de Inglés cuando es posible subseries perno juntos.

Hay muchos otros temas como este : necesita más espacio de interfaz de usuario, ya que algunos idiomas tienen más caracteres que Inglés para expresar el mismo concepto, necesita fuentes más grandes de Asia Oriental, es necesario utilizar fecha / horas localizadas en la interfaz de usuario, pero quizá Inglés de Estados Unidos cuando se comunica con las bases de datos , es necesario utilizar un punto y coma como delimitador de archivos CSV, las comparaciones de cadenas y clasificación son culturales, números de teléfono y direcciones ...

  

Así que te crees una partida del proyecto   hoy en día, debe ser internacionalizada, o   puede que la decisión se aplace hasta el   futuro basado en el éxito (o no)   el software y disfruta de la geográfica   distribución de la demanda?

Depende . ¿Qué tan probable es el proyecto específico a ser internacionalizada? Lo importante que es para obtener una primera versión rápida?

no puedo decir lo que es caro, pero, que yo pueda decir que una API de limpieza le permite internacionalizar su Aplicación a muy bajo costo.

No parece que estés configurando los valores clave primarios para sus objetos de Mietzins. Debe establecer los valores clave principal antes de intentar guardar en la base de datos o decirle a EF que la base de datos generará las teclas primarias.

Cómo especifica que la clave generada por la base de datos depende de si está utilizando el código primero o la base de datos primero. En el código, primero, está usualmente, de forma predeterminada para los tipos de teclas enteros, o puede usar la base de datosGeneratedAttribute y establecer la identidad. Para la base de datos, primero utiliza el diseñador EF y configura la faceta StoreGenerated de la propiedad clave en la identidad.

Re-creó su modelo como se muestra en el diagrama usando las siguientes clases y codifiquen las primeras asignaciones. (Reconozco que probablemente no esté usando el código primero, pero esta fue la forma más fácil para mí crear el mismo modelo con todas las relaciones como se muestra en el diagrama).

public class Mietzins
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int MieterId { get; set; }
    public int ObjektId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public Mieter Mieter { get; set; }
    public Objekt Objekt { get; set; }
}

public class Mieter
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int ObjektId { get; set; }
    public string Name { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public Objekt Objekt { get; set; }
}

public class Objekt
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int HausId { get; set; }
    public int Zimmer { get; set; }

    public Haus Haus { get; set; }
    public Liegenschaft Liegenschaft { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public ICollection<Mieter> MieterMenge { get; set; }
}

public class Liegenschaft
{
    public int Id { get; set; }
    public string Strasse { get; set; }
    public int UserId { get; set; }

    public ICollection<Haus> HausMenge { get; set; }
    public ICollection<Mieter> MieterMenge { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public ICollection<Objekt> ObjektMenge { get; set; }
}

public class Haus
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int Nummer { get; set; }

    public ICollection<Objekt> ObjektMenge { get; set; }
    public Liegenschaft Liegenschaft { get; set; }
}

contexto:

public class ImmoReportsEntities : DbContext
{
    public DbSet<Liegenschaft> Liegenschaft { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.HausMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.MieterMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.ObjektMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Haus>()
            .HasMany(e => e.ObjektMenge)
            .WithRequired(e => e.Haus)
            .HasForeignKey(e => e.HausId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Objekt>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Objekt)
            .HasForeignKey(e => e.ObjektId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Objekt>()
            .HasMany(e => e.MieterMenge)
            .WithRequired(e => e.Objekt)
            .HasForeignKey(e => e.ObjektId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Mieter>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Mieter)
            .HasForeignKey(e => e.MieterId)
            .WillCascadeOnDelete(false);
    }
}

Luego corrió su código exactamente como en la pregunta y funcionó bien.

Luego cambié la clave principal de Mietzins para que ya no se genere la base de datos:

public class Mietzins
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int MieterId { get; set; }
    public int ObjektId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public Mieter Mieter { get; set; }
    public Objekt Objekt { get; set; }
}

Volví al código y obtuve la siguiente excepción:

Excepción no controlada: System.Data.entity.infrastructure.dbupdateException: Se produjo un error al actualizar las entradas. Vea la excepción interna para más detalles. ---> System.Data.UpdateException: Se produjo un error al actualizar las entradas. Vea la excepción interna para más detalles. ---> System.data.sqlclient.sqlexception: violación de la restricción de clave primaria 'pk_mietzins'. No se puede insertar la tecla duplicada en el objeto 'dbo.mietzins'. La declaración ha sido terminada.

Si esto es diferente a la excepción que está viendo, por favor, publique su código y el mensaje de excepción completa y la pila de seguimiento y tomaré otra mirada.

El concepto de i18n y l10n es más amplio que simplemente traducir las cadenas de un lado a otro algunos idiomas.

Ejemplo: Considere la entrada de fecha y hora por los usuarios. Si no lo ha internacionalización en cuenta cuando se diseña

a) la interfaz para el usuario y

b) el almacenamiento, el mecanismo de recuperación y visualización

obtendrá un muy mal tiempo, cuando se desea permitir que otros esquemas de entrada.

De acuerdo, en la mayoría de los casos i18n no es necesario en primer lugar. Pero, y ese es mi punto, si usted no pasa un pensamiento en algunos , áreas que deben ser tocadas por i18n, se encontrará terminando reescribir grandes porciones del código original. Y luego, la adición de i18n es mucho más caro que el de haber pasado algún pensamiento de antemano.

Una cosa que parece que puede ser un gran problema es que los diferentes cargos de caracteres para un mensaje en varios idiomas. Hago algo de trabajo de aplicaciones para el iPhone y, especialmente, en una pequeña pantalla si el diseño de la interfaz de usuario para un mensaje que tiene 10 caracteres y luego intenta internacionalizar más tarde y encontrar lo que necesita 20 caracteres para mostrar lo mismo que ahora tiene que volver a hacer la interfaz de usuario para acomodar. Incluso con aplicaciones de escritorio esto todavía puede ser una gran PITA.

Depende de tu proyecto y de cómo esté organizado tu equipo.

He estado involucrado en la internacionalización de un sitio web, y fui desarrollador a tiempo completo durante un año, probablemente entre 6 y 8 meses a tiempo parcial para que yo manejara los impactos de la instalación cuando fuera necesario (reorganización de archivos, etc.), y otros los desarrolladores se involucran de vez en cuando cuando sus proyectos necesitan una refactorización intensa.Esto fue en una aplicación que estaba en la versión v3.

Entonces eso es definitivamente caro.Lo que hay que preguntarse es qué tan caro es proporcionar un sistema de localización desde el principio y cómo afectará eso al proyecto en las primeras etapas.Es posible que su proyecto en la versión 1 no pueda sobrevivir a los retrasos y contratiempos causados ​​por problemas con un marco de internacionalización diseñado apresuradamente, mientras que un proyecto estable en la versión 3 con una amplia base de clientes puede tener el capital para invertir en hacerlo correctamente.

También depende de si desea internacionalizar todo, incluidos los mensajes de registro, o solo las cadenas de la interfaz de usuario, y cuántas de esas cadenas de la interfaz de usuario hay, y a quién tiene disponible para realizar la localización y el control de calidad que la acompaña, e incluso en qué idiomas. desea admitir; por ejemplo, si su sistema necesita admitir cadenas Unicode (que es un requisito para los idiomas asiáticos).

y Don; t olvidar que el cambio de la base de datos back-end de apoyo internacionalizó datos pueden ser costosos también. Simplemente tratar de cambiar ese campo varchar a nvarchar cuando ya tiene 20.000.000 de registros.

creo que depende de una lengua . Cada J2EE (Java Web) aplicación es i18n, porque es muy fácil (IDE incluso puede extraer cadenas para usted y sólo nombrarlos).

J2EE es más barato para agregar más tarde , sin embargo, la cultura es añadirlos a la brevedad posible. Creo que es J2EE porque utiliza una gran cantidad de código abierto y casi todas las librerías de código abierto son i18n. su gran idea para ellos, pero no para la mayoría de aplicaciones J2EE. la mayoría de las aplicaciones empresariales son sólo para una empresa que hablan un idioma .

Además, si usted tiene malas probadores ponerlo demasiado pronto hace que le den informes de errores sobre las etiquetas y las traducciones (sólo una vez hecho traducciones de sierra NO por los desarrolladores). Después de probadores se hacen con ella se tiene aplicación buggy con un excelente soporte de i18n. Sin embargo, podría ser divertido para los usuarios cambiar el lenguaje y ver si pueden utilizarlo. Sin embargo el uso de la aplicación de su trabajo simplemente aburrido para ellos, por lo que incluso no hacen eso. Los únicos usuarios de i18n son los probadores .

string extraño unirse a la cultura no está en J2EE ya que usted sabe que un día alguien podría querer hacer que se i18n. El único problema es la extracción de etiquetas de HTML plantillas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top