1
\$\begingroup\$

Recently, I perform re-factor on one of my frequent used custom enum, by removing its getter.

My rational for doing so it.

  1. The enum's custom fields are immutable
  2. Only use getters when it is necessary.
  3. Less typing. Reduce verbosity.
  4. This is a very stable class, with only 17 commits, since 2008. Its getters behavior had never been changed. It merely perform dummy return on its internal data, without any additional logic. (History of Country.java)

Before Refactor

public enum Country {
    Australia("/images/16x16/au.png", "Australia", Currency.getInstance("AUD")),
    Austria("/images/16x16/at.png", "Austria", Currency.getInstance("EUR")),
    ...

    Country(String fileName, String humanReadableString, Currency currency) {
        this.icon = new javax.swing.ImageIcon(this.getClass().getResource(fileName));
        this.humanReadableString = humanReadableString;
        this.currency = currency;
    }

    public ImageIcon getIcon() {
        return icon;
    }

    public String toHumanReadableString() {
        return humanReadableString;
    }

    public Currency getCurrency() {
        return currency;
    }

    private final ImageIcon icon;
    private final String humanReadableString; 
    private final Currency currency;
}

After Refactor

public enum Country {
    Australia("/images/16x16/au.png", "Australia", Currency.getInstance("AUD")),
    Austria("/images/16x16/at.png", "Austria", Currency.getInstance("EUR")),
    ...

    Country(String fileName, String humanString, Currency currency) {
        this.icon = new javax.swing.ImageIcon(this.getClass().getResource(fileName));
        this.humanString = humanString;
        this.currency = currency;
    }

    public final ImageIcon icon;
    public final String humanString; 
    public final Currency currency;
}

I was wondering, do you think this is a good re-factoring approach? Would you accept such re-factoring?

\$\endgroup\$
2
\$\begingroup\$

I guess your question is essentially: why do you need getters for final fields, rather than accessing them directly by name.

One reason is that you won't be able to create custom subclasses that extend the functionality of those fields, because variables cannot be overridden, only methods.

This may seem a moot point with an enum as in your question, because enums cannot be extended anyway. The most extensible setup is when you work with interfaces. You could have a Country interface that includes those getters, and an enum that implements that interface and those getters. Then you could have a CustomCountry that implements the same interface. Of course this extensible setup requires methods instead of variables.

Another reason to use getters instead of variables is that the member variables are too intimate implementation details. In the future you might want to derive these values from multiple other variables, but you won't be able to without disrupting your users, since the original variable names are now part of the public API of your class/enum. By exposing getters instead of the variables directly, you are free to refactor your internal implementation without disrupting your users.

|improve this answer|||||
\$\endgroup\$

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