views:

72

answers:

1

I have a situation in Java where I have an external device that I want to communicate via serial I/O. I know how to do this, but I'm now in a refactoring mode to make sure I've got a maintainable software package, & was looking for advice on what to do / not to do at a high level (specific questions below)

Conceptually, let's say I have a low-level DeviceIOChannel interface with several methods (getInputStream, getOutputStream, and some other ones for controlling connection / disconnection detection, etc.), implemented by one or more classes that handle the I/O for various data link types (RS232, TCPIP, etc). Some of my software, let's call it a Device class, is devoted to managing the I/O (parsing the input, constructing output, managing low-level state machines), but without knowing the details of how DeviceIOChannel does its thing (so I can use it with RS232 or TCPIP without having to change the Device class). So I'll probably pass in DeviceIOChannel as a parameter to Device's constructor. I also would like to expose some sort of data model to the outside world.

  1. Does my partitioning of DeviceIOChannel / Device sound right?
  2. Device needs to be doing some things actively on a worker thread. What's the best way to set this up? Should I have it create and manage its own Thread or ScheduledExecutorService? Or should I pass in a ScheduledExecutorService as a construction parameter?
  3. any thoughts (links to good articles on the web would be ideal!) about how to whether or not the Device class should have a startup() method distinct from construction? (doing all the initialization in construction makes me nervous... seems like class instance construction should be quick, and then lengthy stuff should be reserved for an init or startup phase that comes later.)
  4. What about whether to have a Device class with a pair of shutdown / restart methods, vs. no shutdown + requiring a new Device instance to be created?
  5. I'm still new to MVC architecture: would it make sense to create a DeviceDataModel interface that Device implements, or should I have some separate class DeviceDataModel that somehow has two-way communication with the Device class?
+1  A: 

To answer your question one point at a time.

  1. Yes, it does sound reasonable.
  2. Yes, passing an abstraction for your threading will definitely make the class much more testable. Two dependencies in a constructor doesn't sound unreasonable.
  3. Having a startup method adds more overhead (on method calls you have to check if startup was called, you can't assume it), however I agree that such network activity on a constructor always looks weird to me when I see it. I think it is really a matter of style, but one advantage of a separate method is that if you need to debug or log state before starting, your Device class can express its configuration as an instance, rather than making it impossible for something else to get a handle on the object.
  4. I think the answer to this question depends almost entirely on how you handle #3. An API with no surprises would not have a way to restart if it started in its constructor, and would have a way if it started via a method.
  5. Given the network IO nature of this class, a DeviceDataModel interface is going to make the rest of the code much more testable. However, it need not be implemented directly by the Device class, but rather returned from a method of the Device class as an inner class, so it could communicate with the device class easily, but still be something that can be mocked or stubbed during testing. At least, as long as serialization of the the DeviceDataModel isn't a requirement.
Yishai
thanks, it really helps to have feedback like this!
Jason S