0

I am currently trying to rework some code on our server that is super non-pretty Java hard-coded mess. The server receives a byte opcode from the user, and then some variable amount of size. The server will then process this information by reading whatever packet type is at the opcode, stored in a large array. Below is what this looks like:

class Type {

    private static Type[] ids = new Type[256];

    static {
        type[0] = new SomeType();
        type[1] = new Another();
        type[2] = new SomeType4();
        // 254 more entries . . .
    }
}

I am trying to look for a more automated approach to this. My first idea would be to create an abstract class PacketType that contained a public static final List<PacketType> packets. Then, in each implementing class in a static initializer, it will add the instance of itself onto the list. There is two problems with that solution however:

  1. The same class initialization code will need to be "copy-pasted" into every implementing class.
  2. The classes will be added to the list in an unpredictable order. The client will not know which packet serves as which byte code.

Another solution that I contemplated was having a PacketKeeper class that has a Map<Byte, Class<? extends PacketType>> and a parallel Map<Class<? extends PacketType>, Byte>. Surely there must be a better, more beautiful solution to this problem I am having in Java semantics. What is the best way to refactor this long chain of intializers?

Will Sherwood
  • 1,484
  • 3
  • 14
  • 27
  • Refactoring might be more on topic on [codereview.se] or [programmers.se] – Arc676 Dec 28 '15 at 06:26
  • 1
    If the byte is used to index into the array, it may be the case that an enum is more appropriate for this. – Makoto Dec 28 '15 at 06:31
  • I was thinking of that, Makoto. However, there would be up to 250 packets. All in one enum? That one file could be thousands of lines! – Will Sherwood Dec 28 '15 at 06:32
  • 2
    Frankly, I don't see how that code is a mess. You have a 256 different objects, all stored in an array, and all implementing a common interface. That's just 256 lines of super-simple code, and the fact that the opcode-operation mapping is at a single place makes it easy to modify and understand. The only slightly better solution I see would be to rely on a dependency injection container (Spring or CDI, for example) that would be able to discover all the Type implementations by scanning the classpath, and would create the list that way. – JB Nizet Dec 28 '15 at 06:43

0 Answers0