Humble Objects

Ego is the Enemy. Ego can cause us all kinds of problems in our personal and professional lives. When it comes to software, it is no different. Objects and VIs that have large egos create problems. One of the problems they cause is that they make it very hard for us to test our code. What does it mean for an object or VI to have a large ego? It means it tries to take on too many responsibilities.

Here is an example of some hard to test code. This method is not very humble.

In the example above, the method is not only writing to the serial port but also formatting the string as well. It is very difficult to test the logic for creating the string because we can’t call it separately. To test it we have to call the entire VI, which requires us to use the serial port. That makes it hard to verify the result (ie. the string that is written to the serial port). It also makes it harder to automate our testing. The solution is to introduce a Humble Object to separate the logic form the hard to test code (in this case the serial port).

Same Code Refactored to use a Humble Serial Port Object.

To make this code easier to test we introduce a Humble Serial Port Object. This object simply writes data to the serial port. That is why we call it humble. It only does one thing.We also extract the string logic into it’s own subvi.

Now we can test the logic for creating the string we are going to write to the serial port.

Now that the string logic is in its own subvi, we can drop it into a test method. Now we can test the logic completely separate from the serial port. We can now run the test automatically on any machine without worrying about serial port settings.

Where else can this idea be used? It works for talking to hardware via serial, TCP/IP, DAQmx, etc. It works for calling DLLs or Python functions. It works for GUIs. It works for databases. I am sure you can come up with other good use cases.

4 Comments on “Humble Objects

  1. This idea has completely changed the way I develop. It use to be stressful to think about how I was going to create a unit test for many of the situations you bring up. Not anymore with the use of humble objects.

    Plus you probably should not be unit testing other client APIs, and this helps with that.

    • I find that in general unit testing makes development less stressful. I know my code works (and I can prove it). I can make changes to my code without worrying about breaking things, and if I do, the unit tests point to exactly where the problem is.

  2. I can see the value in this idea (and really enjoyed your discussion of it in your recent webinar!) but wonder about the formatting VI being public.

    For me, this is a VI used only by the specific instrument class. Obviously making it public allows testing, but I’d rather nobody else saw it or its existence. Am I overly hiding this method (and if so, who/what else really needs it?)

    Community scope gives me one way around this but generally seems an unfortunate (or at least discouraged) tool for testing.

    Are there better options (or just other options) that I’ve missed here? What are your preferences and reasons for your choice in non-example codes?

    Thank you again for all the material you provide – it’s always useful to read more from people who are really doing good work with LabVIEW.

    • Christian,
      I agree with your sentiments. Generally, I find community scope to be a code smell. It always leads me to consider if there is a better way to do it.

      One possibility might be to make a standalone string converter class. Make the class public so you can test it. Then use composition so that serial instrument driver contains in its private data a string converter object. Don’t expose that object.

      Now the one issue you run into is that anyone can drop a string converter object somewhere else. I don’t know how to get around that without making it community scope. Now if the string converter was generic, that probably wouldn’t be a concern. Let it be public and maybe someone has a legitimate use case somewhere else. In this case it is not very generic so maybe community is the way to go. Or perhaps just clearly label what it is for -put in the name of the class ie serial converter for instrument xxx – and don’t care if someone uses it somewhere else. If they do then that is their problem.

      Just kind of thinking out loud here. Hope that helps.

Leave a Reply

Your email address will not be published. Required fields are marked *