1

I create an application for a system, which consists of several different devices, each of which should be controlled by a computer via one of standard hardware interfaces and could be accessed via Ethernet (Sockets), Virtual COM Port, ready-to-use 3rd party C++ API, etc.).

My application should have GUI to manage all the devices, and some data from devices has to be frequently updated.

Usually each device has its own specific management protocol, which is present as a list of command formats, for example: Header (4 specific bytes), Command code (2 bytes), Data size, Data, Crc, ....

Features:

  • Each device should be controlled by commands
  • Health status of each device should be received periodically and displayed on GUI
  • Usually communication with a device consists of transmit a command and receive an answer.

Problems:

  • No device responds instantly (threads or async is necessary)
  • If device stops working, or loses connection, it is necessary to wait for some timeout
  • "Business-logic" should have easy access to all devices at the same time

Questions: what famous and good solutions (interface skeletons, articles) are already present for such a problem? I don't want to use one "God" class and put dozens of members into it.

1 Answer 1

2

Interfaces

Well clearly the use of interfaces is paramount here. Think about for any given device, the types of requests you might make of it, then create an interface around it. You'd use a factory to instantiate each instance of this interface, but otherwise your program should not care about the nature of the device or which implementation is used.

interface Device {
    Future<Status> getHealthStatus();
    int            getTimeout();
}

If there is some aspect which is particular to a device, such as the timeout should be longer through a smartphone, then have a configurable timeout property which is by default set to a higher value in the factory or in the instance itself. The program handling the request then need only read a device's timeout value to know how long to wait for a request response therefore eliminating the need to handle any device differently.

Futures

Notice that getHealthStatus() returns Future<Status>. By Future, I'm referring to an object representing an asynchronous response. The future instance gets returned immediately (synchronous), however it lets you do work until you need to know the actual response. Traditionally, you would get an instance of Status by calling Future.get(). This makes the current thread halt until the Status instance is resolved. This gives you the flexibility to handle the call synchronously or asynchronously as required (in the former case, you'd call Future.get() immediately after the call to getHealthStatus()).

This concept exists in many languages. In javascript it is commonly referred to as a Promise. Using this to organize your synchronous/asynchronous calls is also important to your program no doubt.

API layer

Up to this point, we've only been talking about internal handling of requests to your program, but it is very helpful to create an explicit API layer meant to deal with the low-level grunt work of the requests and responses and to translate them into simple calls to your internal classes. Ideally handling of timeouts would be dealt with here. Be prepared to handle the possibility of timeouts and retries in this layer. The rest of your program should be abstracted away from this particular aspect. The only way the rest of your program would be made aware of problems is a proper timeout Status instance or perhaps a thrown exception, only after the operation has been deemed unrecoverable.

Conclusion

By structuring your program in this way, you have clean breaks in responsibility and device handling. By usage of interfaces for devices, your program should never care to know the type of device on the other end except during its creation. The use of Futures will make asynchronous calls straightforward and easily manageable. By using an API layer, you effectively simplify the program by focusing on the essence of request and response and allow you to easily adapt your program for future changes.

2
  • Could you please explain or give a link for how does one make a logic on Futures? Mar 21, 2018 at 11:24
  • 1
    @VladimirBershov Here an example in Java. Again, I don't know the language you're using but it's fairly straightforward. Both threads share an instance of Future, and once the value is ready, the one doing the call will assign the internal value of Future. When get is called and result is already present, it simply returns it. Otherwise it'll wait for a notification that value has been assigned.
    – Neil
    Mar 21, 2018 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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