6

I have a library that defines messages. In my particular instance, it's autogenerated code from an XSD using JAXB (Java). The messages can be very complex, with some members as objects and those objects containing other objects. The objects are both classes and enumerations. The library is a single JAR file with no dependencies, billed as a reusable component for Java applications. The idea is that any Java application that needs to send or receive these messages would use this library to do so. At present, there are 10 messages that are defined, but there are a large number of data types (classes and enumerations) that are also defined in the library that are contained within the messages.

The immediate need is for a graphical application that lets the user construct the messages in the specified format and then publish them appropriately over a network connection. This means that the user would be able to create the 10 messages and populate the various fields that go into them. The result is an XML string that conforms to the schema that can be published to a listening application. The listening application is also generating messages that are also defined in the XSD and the library in accordance with the schema and those must be received.

It is desirable to also be able to create a command-line version of this application that can be scripted. This command-line version is not well-defined, but it could be interactive (with prompts) or simply command-line argument driven to publish the messages.

What would the best approach to building my application around this library?


Two approaches come to mind:

The first approach is a a wrapper around the library that is part of the application build. This wrapper would be almost a duplication of the JAXB library, but it wouldn't invoke the generated data objects until requested. It would be a builder that would also provide validation and perhaps a simplified interface for some of the components of the messages. This could be useful, since the JAXB library doesn't have a concept of validation until the elements are marshalled. Although you can marshall to a default handler as opposed to your output format like a file or stream, but that seems not very useful since the messages you get from validation errors aren't exactly user-friendly. In this approach, the GUI, the text user interface, and the command-line interface would all interact with this application data model.

The second approach would be to organize my user interfaces into different packages. The GUI packages would provide user interface elements that correspond to the fields of each message. The validation rules from the XSD would be applied as validation rules to each field, using things like InputVerifiers, combo boxes, check boxes, and other things that prevent invalid data before it's even passed off to the data model. The text user interface would essentially provide the same thing, but by reading from and writing to the standard input, output, and error streams. I suspect in these implementations, the input classes would correspond to the data model classes 1-to-1 - each input class would be responsible for gathering and validating the user inputs needed to construct a single data element (one class in the data model provided by the JAXB library). I suspect that the textual UI and GUI can share base classes or interfaces that each of the UI classes can inherit from to allow them to be passed into the same controller to read from and produce the appropriate object from the data model. A command-line interface would likely use a command-line argument parser to gather the input, ensure everything is there, validate all of the fields, and then carry out the transmissions or receptions. It would be implemented very differently than the interactive user interfaces.

I'm personally leaning toward the second approach, but I suspect that there may be another, better strategy out there.

4

The interface to build these messages is the same in both the GUI application and the command line interface. For example, both applications can:

  • Add elements
  • Update elements drilled down in the message
  • Delete elements
  • Validate messages

I would design this part first. Design the behaviors that you want to be able to do which would then call the appropriate API calls in your messaging class. You've discussed data validation at length - the validation code would all go within the data model. Don't worry about how the user will be informed of invalid messages yet; you can throw ValidationExceptions that get caught later on in the design.

Once this data model works the way you want it, you can then attach any sort of interface you want that can call these data model methods.

This is essentially option 2, but the distinguishing feature is the order in which you do the work. By designing the data model first, you will discover the various user operations that make the most sense, before you worry about drawing screens or picking command line flags (or whether you want the command line tool to be interactive).

When it is time to design the "View" (MVC definition of the word), start by writing interfaces that will work for both the command line and GUI version. Then you can use JLine or Commons CLI (depending on what you mean by command line) or something else for the former, and Swing or JavaFX or whatever in the latter.

1

I recommend that you make your application in such a way that it is easy to change if the library changes. If you use library components in different parts of your application, and the library changes, you will need to change many parts of the application. In work, we usually use a dedicated layer for performing request to external services (consumer layer) which is strictly isolated from other parts of the application.

What about a mix of your both approaches? Your first approach is somewhat similar to the layered approach I described above, while your second approach is more concerned with validation and reuseability, which seems reasonable. Can you do both while thinking how much work will it require to change your stuff if the library changes? I think this will give you clear separatation of concerns and make your application easier to maintain, and provide appropriate levels of reuseability.

You write that you want to make GUI packages for each message which sums up to 10 packages. I assume you mean Java package. I would have combined packages so that similar stuff was in same package. Eg. GUI in one, command line UI in one and the consumer layer in one.

Maybe all of these suggestions are too complex for your use case. I suggest you take a top-down approach, making skeletons or quickly prototyping both the GUI, command line UI and the library usage (for example just for one message) to see what is beneficial.

UPDATE

Consider if the changes in library are only technical while the library still provides the same functionality – e.g. someone performed refactoring like changing names of classes, rearranged code by moving fields from one class to another, or introduced new classes. You will still be hit by the changes but if you use a wrapper/decorator, you only need to change stuff there. You can still use the existing UIs as they are, you just have to map the data differently and this can be the wrappers job.

If the UIs are 100% reflection of the library, then you also must change the UIs and you get no benefit of using the wrapper, as you have stated. But then, you may use some existing GUI client for calling web services e.g. SoapUI which generates a client for you based on the web service contract (XSD in your case). This requires that the contract follow some standard like WSDL

  • I did mistype. There would be one package for the GUI and one for the command-line argument, not multiple packages. I'm not convinced that creating a wrapper would help if the library changes. I'd have to change the wrapper any time the library changes. Depending on what changes (messages added, messages removed, fields in messages added, fields in messages removed), I'd still have to change the UI layer to add or remove input fields or create or delete UI classes designed to accept the right inputs. The only advantage may be if the message format changes. Maybe I'm missing something obvious? – Thomas Owens Mar 15 '15 at 21:55
  • You are absolutly right about the change requirement in the UIs because they are natural. I have updated my answer to further discuss this. – qtips Mar 16 '15 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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