2

I am writing a rather complicated translation module which essentially translates between a form of logical representation and Java code. It spans several classes which are all decoupled from each other.

My problem is that I need to keep track of a rather extensive set of keywords which need to be inserted, for example, into variable names. These keywords must be accessible to all classes in the module, and be easy to change.

I understand that the use of globals is a red flag as far as design goes, but would it be acceptable in this case to create a class which does nothing but provide static access to said keywords? For example:

public final class KeyWords {
    public static final String SELF = "self";
    public static final String RESULT = "callResult";
    // etc
}

My own thoughts is that it would work somewhat like a simple config class. I find this a lot more reasonable than using, for example, a mediator or passing some other bucket class between method calls, since the data is rather well defined and, importantly, not subject to modifcation during runtime.

OR, would it be better to put all these keywords into an interface instead, and let all my class inherit this? While it could work, it just does not feel right.

csvan
  • 8,782
  • 12
  • 48
  • 91
  • 2
    Those aren't "global [variables]". Those are "constants named by a stable identifier". Definitely *do not* [ab]use interfaces like that. –  Feb 08 '13 at 03:51
  • 1
    Per your second suggestion: http://stackoverflow.com/a/2659740/29995 – Rob Hruska Feb 08 '13 at 03:52
  • Thank you for the correction. As I do not usually program like this I have probably missed out on the definitions. So they would be considered globals only if they are volatile? – csvan Feb 08 '13 at 03:52
  • @RobHruska - thank you for that. I just knew it felt like an antipattern. – csvan Feb 08 '13 at 03:54
  • @chrsva I would only consider them problematic if they were updatable (or mutable). Because they are constant primitive values I would argue they do not represent "singleton pattern", although I'd imagine someone would try to shoehorn them into DI :D On the flip side, however, consider *localizable values*, in which case my view would differ. –  Feb 08 '13 at 03:54
  • Another issue: should these keywords truly be constants? What if you wish them to change later? Would it be better to store them in some file, perhaps a database or XML file, that is then read and used by the program? – Hovercraft Full Of Eels Feb 08 '13 at 03:55
  • @HovercraftFullOfEels - they are strictly bound to the module, and are not meant to be modifiable in any other context than re-compilations, since there should not even be a need to change them - I just need convenient access to them. From the users perspective, there is no purpose at all to modifying them either. – csvan Feb 08 '13 at 03:59
  • Right, I didn't mean for them to be modifiable by the user, but by the programmer if desired. They smell like data to me, not code, and data should be separate from code. – Hovercraft Full Of Eels Feb 08 '13 at 04:02
  • @HovercraftFullOfEels - I see, so you would recommend moving them to an XML (or equivalent) file and just load them at runtime instead? – csvan Feb 08 '13 at 04:03
  • 1
    Yes, but note that I am not a pro at this sort of stuff. This is more my intuition than a professional recommendation. – Hovercraft Full Of Eels Feb 08 '13 at 04:05
  • @HovercraftFullOfEels, ok, it does make sense though, I will look into it. Thanks a bunch! – csvan Feb 08 '13 at 04:07
  • Also consider using `int`s instead for == comparison and other benifits over `String` – tckmn Feb 08 '13 at 04:12
  • IMO externalizing these to a file isn't a really good idea. These look like they'd be stable and the fact that they're `static final` means that they're eligible to be inlined to client classes instead of needing a field dereference. – Geoff Reedy Feb 08 '13 at 04:26

2 Answers2

4

This isn't the worst thing ever, but it's somewhat out of date. If you're using Java 1.5 or above, an enum would be better; it gives you type safety, for instance.

public enum KeyWord {
    SELF("self"),
    RESULT("callResult")
    ;

    public String getKeyword() {
        return keyword;
    }

    private KeyWord(String keyword) {
        this.keyword = keyword;
    }

    private final String keyword;
}

You're right that the "tuck them into an interface" approach doesn't feel right; an interface is about specifying behavior, which a methodless interface with static finals does not provide. Since Java 1.5, you can use static imports to get the same benefit without that "code pollution."

yshavit
  • 42,327
  • 7
  • 87
  • 124
  • Assuming they really are an enumeration - in which case I couldn't argue against this. –  Feb 08 '13 at 04:37
0

If you are going to be using the same set of keywords, across multiple classes that don't inherit from each other then I would suggest just creating a static class that reads in a text file that has all of these keywords in it.

If you use this method then you can use the "code once use everywhere" ideology that the pros always drone on about.

-Create a static class

-Read in a text file that has all your keywords saved in it

-write a couple functions that retrieve and compare keywords

-Use it in every class you want without worry of fragmentation.

Using this method also makes updating a snap because you can simply open the text file change add or delete what you want then it is fixed in every single class that implements it.

DotNetRussell
  • 9,716
  • 10
  • 56
  • 111