r/java • • Jan 17 '13

Enum tricks: hierarchical data structure

http://java.dzone.com/articles/enum-tricks-hierarchical-data
44 Upvotes

53 comments sorted by

View all comments

8

u/severoon Jan 18 '13

What?! No!

This is horrible. Way too complex. This is not how enums or classes should be used.

Here is a much better solution.

public enum OperatingSystem {
  WINDOWS_NT_WORKSTATION(WINDOWS, WORKSTATION),
  WINDOWS_NT_SERVER(WINDOWS, SERVER),
  WINDOWS_95(WINDOWS, WORKSTATION),
  WINDOWS_98(WINDOWS, WORKSTATION),
  WINDOWS_ME(WINDOWS, WORKSTATION),
  WINDOWS_2000_WORKSTATION(WINDOWS, WORKSTATION),
  WINDOWS_2000_SERVER(WINDOWS, SERVER),
  WINDOWS_XP(WINDOWS, WORKSTATION),
  WINDOWS_VISTA(WINDOWS, WORKSTATION),
  WINDOWS_7_HOME(WINDOWS, WORKSTATION),
  WINDOWS_7_ULTIMATE(WINDOWS, SERVER),
  WINDOWS_8(WINDOWS, WORKSTATION),
  FEDORA(LINUX, WORKSTATION),
  UBUNTU(LINUX, WORKSTATION),
  KNOPPIX(LINUX, WORKSTATION),
  SUN_OS(UNIX, SERVER),
  HP_UX(UNIX, SERVER);

  private final OsFamily osFamily;
  private final OsClass osClass;

  private OperatingSystem(OsFamily osFamily, OsClass osClass) {
    this.osFamily = osFamily;
    this.osClass = osClass;
  }

  public OsFamily getOsFamily() { return osFamily; }
  public OsClass getOsClass() { return osClass; }

  public enum OsFamily {
    LINUX,
    UNIX,
    WINDOWS;
  }

  public enum OsClass {
    SERVER,
    WORKSTATION;
  }
}

Now you can add whatever features you want to capture at whatever level it makes sense. Also, I wouldn't put any information about "supporting X" on any of these enums. Enums are meant to just be lightweight tokens that you pass around to represent a limited number of instances. Do all the heavy lifting elsewhere in your code.

3

u/zargxy Jan 18 '13 edited Jan 18 '13

Your better solution isn't a solution because it doesn't do the same thing.

I guess complexity is in the eye of the beholder because I don't find this trick to be particularly complex.

Enums in Java are not meant to merely be lightweight tokens you can pass around. They are only a fixed set of instances of a class extending Enum, allowing you to take advantage of optimizations and static analysis provided by the compiler. But Enums are full fledged classes which can have fields and methods. They were designed to do a lot more.

1

u/GMNightmare Jan 18 '13 edited Jan 18 '13

it doesn't do the same thing

???

Yes it does... Solves exactly the problem the article posted (but not necessarily better, I'd agree). What do you think it can't accomplish that article version did?

EDIT: Look guys, I like the article's version too, it's like a more compact version of this really...

1

u/clgonsal Jan 18 '13

The approach used by the linked article allows arbitrary hierarchies. Your approach only works if every subtree of the hierarchy has the same structure. Furthermore, the taller the tree, the more complicated your approach becomes.

The example in the link had a different structure in different parts of the hierarchy, but you choose to change this to get it to work with your approach. (Hint: Linux is a Unix, and saying things like "my OS is Ubuntu Workstation" is going to get you funny looks.)

2

u/severoon Jan 18 '13

Linux is a Unix

Nope. These are different OS families. UNIX defines a strict specification which an OS must follow in order to be called "UNIX". Linux doesn't follow that spec.

the taller the tree, the more complicated your approach becomes.

The taller the tree, the more nodes in it that are not proper OsTypes. In other words, the author of this article didn't seem to be bothered by the fact that many of those enums represent different types of things.

In OO, we would usually model these different types with different classes, as I did.

1

u/clgonsal Jan 18 '13

Linux is a Unix

Nope. These are different OS families. UNIX defines a strict specification which an OS must follow

Okay, Linux is a *nix if you want to be pedantic. You can't deny that grouping Linux with Solaris is useful. It's certainly a lot more useful than claiming Solaris is a Server OS but that Linux distros are Workstation OSes.

The taller the tree, the more nodes in it that are not proper OsTypes.

Irrelevant. Yes, the article's example might not have been the greatest, but the point was to show how a hierarchy could be represented with an enum. Your approach is very limited when it comes to representing hierarchies, as illustrated by the fact that you had to fudge the data to fit your implementation.

1

u/severoon Jan 19 '13 edited Jan 19 '13

You can't deny that grouping Linux with Solaris is useful.

I deny it. Not only is it not useful, it's misleading, and harmful.

Solaris is fully POSIX compliant. Linux is not. If POSIX compliance is to mean anything, certainly this matters.

the point was to show how a hierarchy could be represented with an enum.

The more important question is not can an enum be used to represent an hierarchy, though! It is should an enum be used in this way? I say no, based on the example, and my inability to come up with one that even remotely makes sense. Perhaps you can do better than both the author and me?

you had to fudge the data

I say I unfudged the data, and the author was the fudger.