0
\$\begingroup\$

Let's assume I have an enum type with currency:

public enum CurrencyType {

    USD("American Dollar", "USD"),
    EUR("Euro", "EUR"),
    JPY("Japan Yen", "JPY");

    private final String fullName;
    private final String shortName; // enum valirables can change in the future, so I do not use Currency.name()

    private CurrencyType(String fullName, String shortName) {
        this.fullName = fullName;
        this.shortName = shortName;
    }

    public String getFullName() {
        return this.fullName;
    }

    public String getFullNameLocalized(ResourceBundle bundle) {
        // returns the currency name using some ResourceBundle with localized strings
    }

    public String getShortName() {
        return this.shortName;
    }
}

Now, somewhere in the presentation layer I say:

CurrencyType curr = CurrencyType.EUR;
// ...
labelCurrencyTypeName.setText(curr.getFullNameLocalized(bundle));
labelCurrencyTypeSymbol.setText(curr.getShortName());

in order to see the "EUR" string in an appropriate place.

Everything is perfect, but such approach mixes the Model and View together, doesn't it? CurrencyType is widely used in business logic and this is it's main goal.

What other approach would you suggest? Or maybe my code is not so wrong as I expect?

\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

If you want to decouple Enum and presentation logic, consider using EnumMap . This type of collection is fast and key-safe.

IMO, there is nothing wrong to store short and full currency names in CurrencyType. But localized name (as well as country's flag and other visual aspects) better be decoupled and put into presentation layer. You can use short names as keys for resource bundles.

Furthermore, if all CurrencyType values reproduce currency short names, you can eliminate using dedicated private field for them and use Enum.name() instead.

\$\endgroup\$
1
\$\begingroup\$

Full decoupling would assign arbitrary identifiers to currencies (possibly integers sequentially) and then presentation would map them to 'EUR', 'USD' as well as their names.

However in reality there is no realistic prospect that EUR/USD/JPY are going to change and holding the ISO name 'US Dollar', etc. in the code is a good defensive fall-back if a local name is not found.

So yes, you are mixing business data / presentation and program logic but (in your case) not in a way that is certain to cause you harm.

What you are limiting is the range of currencies. Entries on the ISO4217 list don't tend to change but they do come and go.

What are you going to do when later this year 'NGD' shows up? Your organisation might not be interested in the "New Greek Drachma" but if you're holding EUR assets you might not have a choice! ;)

OK so that's a little speculative, but you get the point...

\$\endgroup\$
1
\$\begingroup\$

Accessing an enum directly from the presentation isn't objectively "so bad." However it suggests an architecture other than MVC such as client-server on the high end or the ever popular BBoM elsewhere.

The leaky abstraction under MVC comes from storing strings in CurrencyType. Unless the business logic requires parsing strings, all the business logic needs is:

public enum CurrencyType {

    USD,
    EUR,
    JPY
}

The missing piece is a clearly defined interface between the View and the Controller.

The controller should pass a value to the view. It could pass 1, 2, or 3 directly from CurrencyType, but that's probably not a good idea for obvious reasons. An alternative is for the controller to pass the tuple of strings, i.e. something that would serialize to JSON as:

{
  "fullName":  "American Dollar",
  "shortName": "USD",
  "symbol":    "$"
}

The point of showing this as JSON is not love of JSON. It's that the MVC architecture should define the Model-Controller and Controller-View interfaces so that the layers on each side can be written in different languages, e.g. SQL->Java->JavaScript.

Each interface should be designed to explicitly serialize and deserialize data in both directions to prevent leaky abstractions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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