0
\$\begingroup\$

I have a class which represents some translations of a keyword.

public abstract class Name {

    private String name;
    private String name_de;
    private String name_it;
    private String name_fr;
    private String name_hu;
    private String name_cs;

    public Name(String name_key, String name_de, String name_it, String name_fr, String name_hu, String name_cs) {
        super();
        this.name = name_key;
        this.name_de = name_de;
        this.name_it = name_it;
        this.name_fr = name_fr;
        this.name_hu = name_hu;
        this.name_cs = name_cs;
    }

Each translation has to be an own field because of saving purpose. The problem here is that I cant make sure that for instance the german translation is really the second parameter.

I was thinking about to create an own Object for each translation, but seems a litte bit of overhead. Are there any other options to represent a translation class?

\$\endgroup\$

closed as off-topic by Emily L., Sᴀᴍ Onᴇᴌᴀ, 200_success, Alex L, Gerrit0 Dec 18 '18 at 5:04

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Emily L., Sᴀᴍ Onᴇᴌᴀ, 200_success, Alex L, Gerrit0
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ In internationalisation, the number of languages should ideally be open-ended, with a fallback, as the name here. So just name, and such. Resource bundles, .properties or ListResourceBundle (java arrays) allow such a more generic approach. \$\endgroup\$ – Joop Eggen Dec 17 '18 at 13:06
  • \$\begingroup\$ A fluent builder can make your code more readable and safe. But nothing will prevent someone to pass a wrong value. new Name.Builder(key).deutch("..").italian("..").build() \$\endgroup\$ – gervais.b Dec 17 '18 at 14:01
  • \$\begingroup\$ @gervais.b A builder is a good approach. Its more important to make clear which value belongs to which language. If a wrong value will be passed, its not the fault of the code. If you would like to create an answer, I will accept it. \$\endgroup\$ – Patrick Dec 17 '18 at 15:00
2
\$\begingroup\$

A fluent builder can make your code more readable and safe:

new Name.Builder(key)
  .deutch("..")
  .italian("..")
  .build();

However nothing will prevent someone to pass wrong value.

\$\endgroup\$
3
\$\begingroup\$

You haven't given much context about how you intend to use this class, which is always important. In my experience (echoed in comments), there's not much use case for needing all translations of a string at one time. The use case is more typically that you need to render the UI in a particular language, so you need a bunch of German strings but none of the other languages. Also, you want to be able to easily add support for additional languages, ideally without any code changes. That's what resource bundles are for, it seems like you are trying to reinvent the wheel here. If you think that resource bundles don't solve your problem, you should give more context.

\$\endgroup\$
  • \$\begingroup\$ I do not have much experience using resource boundles, but I already say that I need every attribute because of saving purpuse. I am not able to change the structure. \$\endgroup\$ – Patrick Dec 17 '18 at 17:46
  • 1
    \$\begingroup\$ "Saving purpose" is pretty vague. How would this class be used? What does the save function look like? Where does this class get its data? Why does it need every translation in a different field, rather than a map langId -> translation? \$\endgroup\$ – Pierre Menard Dec 17 '18 at 17:55
1
\$\begingroup\$

In addition to @gervais.b's great answer, you can for instance use some kind of Map to store translations for different languages. Of course instead of using strings for keys like "de", "it", "fr" it will be safer to use enum for indication of different languages.

However nothing will prevent someone to pass wrong value.

It is possible to implement some mechanism in build() method to check if all enum values are covered and are correct. Here is some reference how to iterate over enum

You can also simplify the builder a little bit:

new Name.Builder(key)
  .translatedAs(Languages.DEUTCH, "..")
  .translatedAs(Languages.ITALIAN, "..")
  .build();
\$\endgroup\$
  • 1
    \$\begingroup\$ My remark about the fact that nothing can prevent someone to pass wrong value was not about ensuring that all translations are filled in. But more that you cannot prevent someone to pass "Bonjour" in English. \$\endgroup\$ – gervais.b Dec 17 '18 at 19:49
  • \$\begingroup\$ @gervais.b You are right. But in that case it is at least possible to minimize the probability of human error by providing clean API. \$\endgroup\$ – mpasko256 Dec 17 '18 at 20:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.