LabVIEW Object Oriented
System Design
Mikael Holmstrom (c)
Decomposition techniques
Functional
Object Oriented
Mikael Holmstrom (c)
Functional Decomposition
Traditionally used in LabVIEW
Top-Down functional breakdown
Functionality structured into sub VIs
VI 1
VI 2 VI 3 VI 4
Mikael Holmstrom (c)
Functional Decomposition
Globals
VI 1 VI 4
VI 2
Global
VI 3
Mikael Holmstrom (c)
Drawbacks of
Functional Decomposition
Difficult to scale
Difficult to maintain
Difficult to reuse
Mikael Holmstrom (c)
Object Oriented Decomposition
Supported in LabVIEW 8.20
Program structure reflects the problem being
solved
Functions (VIs) are grouped with the data they
need
Mikael Holmstrom (c)
Object Oriented Decomposition
Object Versus Global
VI 1 VI 4
M1 M2
VI 2
Data
M3 M4
VI 3
Object
Mikael Holmstrom (c)
Object oriented program structure
Mikael Holmstrom (c)
Wikipedia says:
“An object-oriented program may be viewed as a
collection of interacting objects, as opposed to the
conventional model, in which a program is seen as a list
of tasks to perform. In OOP, each object is capable of
receiving messages, processing data, and sending
messages to other objects. Each object can be viewed as
an independent “machine” with a distinct role or
responsibility. The actions (or “methods“) on these
objects are closely associated with the object.”
Mikael Holmstrom (c)
What is OO
Izzy Johnston of Girl Develop It says:
“Object-oriented programming is playing with virtual lego. Every lego is
an object and it has something that’s called state, which are basically its
attributes. The lego’s color, its size, whether it has bumps on the top or
bumps on the bottom, whether it can connect to other legos. All of those
attributes are that lego’s state.
Then legos also have behaviour, which nerds call methods. Those
behaviours are, can it be stacked on top of another lego? Can it be stacked
underneath another lego? Is it, at this moment, being stacked on top of
another lego?
Then what you do with all of these legos, is create other methods that say
‘bring all of these legos together and build a ship, then bring all of these
legos together and build a castle, bring all of these legos together and
build another ship.’
Finally, your final method is some kind of thing where the ships are firing
canon balls at each other to get to the castle.”
Mikael Holmstrom (c)
Benefits of object oriented
decomposition
Program structure reflects the problem being
solved
Easier to extend and modify
Easier to scale up
Easier to test
Easier to reuse
Mikael Holmstrom (c)
Object Oriented Basics - Topics
Class
Object
Object lifetime
Class Access Control
Mikael Holmstrom (c)
What is a class in LabVIEW?
A class is a set of VIs and
a type definition (ctl file)
A ClassName.lvclass file
The lvclass is similar to lvlib
– it defines a name space
Mikael Holmstrom (c)
The Class Concept
VIs of the class
Data of the class
Mikael Holmstrom (c)
The VIs of the Class
Defines the features provided by the class
A VI of a class is also called ”method”
Mikael Holmstrom (c)
The Data of a Class
ClassName.ctl defines the class data for
each class
Ex. Engine stores “revolutions per
minute” and “running”
Mikael Holmstrom (c)
Creating a Class
1. Create a class and explore
◦ Project structure
◦ File structure
2. Define the class icon
3. Add a method VI
4. Show the class control and how to create it
5. Add a data element to the class
Mikael Holmstrom (c)
Class vs. Object
The class is the LabVIEW code you see during
development
Objects exists during program execution
Each object contains its own data set as
defined by the ClassName.ctl
Mikael Holmstrom (c)
The Object
Mikael Holmstrom (c)
Object Type Control
Each class defines a unique type
You cannot wire an object of one class into
Method VIs of another class
Mikael Holmstrom (c)
Object Lifetime
LabVIEW objects behave like any LabVIEW
data
they are automatically created when needed
and
destroyed by LabVIEW when not used
anymore.
Forking a wire may create a new object
◦ Object data is copied to the new object
◦ Think of a LabVIEW class like a ”glorified cluster”
Mikael Holmstrom (c)
Who can Access the Class?
The class data is private
Methods can be:
◦ Public
◦ Protected
◦ Private
Mikael Holmstrom (c)
Why is the Data Private?
Answer: To simplify maintenance!
Observation: Complex data structures (e.g.
Clusters) are likely to change over time
What VIs are affected when a data structure is
changed?
◦ For a Class: The methods of the class
◦ For a Type Def: Potentially all VIs in your
application!
Mikael Holmstrom (c)
Why do we Need Private Methods?
Private methods are used like Sub VIs by the
public methods
They structure the code within the class
Mikael Holmstrom (c)
Summary
Class = LabVIEW cluster + VIs
Object – the instance of a class existing
during execution
Each object contains the data as defined by
ClassName.ctl
Method – VIs of the class
LabVIEW classes behaves like any LabVIEW
data – they are by-value
Mikael Holmstrom (c)
LabVIEW is by-value
LabVIEW data is handled by-value
◦ When a wire forks data may be copied
◦ This is true also for LabVIEW classes
Sometimes we need to control when data gets
created
◦ Then we may use reference based solutions
◦ References are used in many LabVIEW VIs
Mikael Holmstrom (c)
Examples of VIs using references
TCP
VISA
File VIs
Config File VIs
Queue
Notifiers
And more...
Mikael Holmstrom (c)
Typical scenario for VIs using refs
Create (or Open) – initializes and returns a
reference
VIs of the class – needs the reference to
operate on the correct data instance
Destroy (or Close) – performs cleaning and
frees memory
Mikael Holmstrom (c)
Why references are used
Reasons for using references:
To control when objects are created (and
destroyed)
To control when objects get copied – or
often: avoid copying
Mikael Holmstrom (c)
A Reference based Class
Standard LabVIEW class:
The wire contains the object
Reference based class:
The wire contains a reference to the object
Mikael Holmstrom (c)
What is a reference based class?
It is a LabVIEW class! With some extras...
A standard LabVIEW class containing an
reference to its data
No worries – it is all LabVIEW, Data is stored in:
◦ A functional global (GOOP 3)
◦ DVR (GOOP4)
A toolkit used for class creation
Mikael Holmstrom (c)
The Data of the Class
Similar to lv class it is stored in a type def
The type def is named ObjectAttributes.ctl
Mikael Holmstrom (c)
Accessing the data fields
Instead of using cluster unbundle-bundle there
are utility VIs:
ClassName_GetAttributes.vi (GOOP3/4)
GOOP3
ClassName_GetAttributesToModify.vi
ClassName_SetModifiedAttributes.vi
Attribute = data field of the GOOP class
Mikael Holmstrom (c)
Creating a Class
1. Create a class and explore
• Project structure
• File structure
2. Create a method
3. Add a data field to the class
4. Modify the data field with the method
Mikael Holmstrom (c)
Object Creation
To create and destroy objects use:
ClassName_Create.vi and
Destroy.vi
These VIs are automatically generated by the tool
Each call to Create returns a reference to a new
object
Mikael Holmstrom (c)
Object Oriented Design
Knowing what a class is...
...how do we structure our program using
classes?
What is a good class?
What is bad class?
Mikael Holmstrom (c)
Some Sample Classes and VIs
Sample LV classes: Queue, Config File VIs,
Notifier, Semaphore
Sample LV VIs: Sort 1D Array.vi, Unbundle By
Name, Get XY Value.vi, Open VI Reference
What is the difference between a class and a
VI?
Mikael Holmstrom (c)
Class vs. VI
The Class – has a specific responsibility
◦ The class name reflects its responsibility
◦ The class methods performs the various tasks
within this responsibility
◦ Class name is a noun
The VI – performs a task
◦ The VI name describes what this task is
◦ VI name is a verb (or includes a verb)
Mikael Holmstrom (c)
Example: The LabVIEW Engine
Monitor Application
Scope: Build an application to monitor engine
variables. Display the variables in a UI.
Variables: Oil temp and pressure, Engine
revolution and torque, cooling water temp
Interface towards UUT: CAN protocol for
automotive industri
Mikael Holmstrom (c)
First solution: A single UI VI
Engine UI.vi – it got a bit complicated but
worked for a while. But now there are some
issues:
We need to support an additional CAN
interface board. Sofar NIs CAN Interface has
been used.
Adapting the UI to this makes the VI too
complicated, therefore classes are used to
improve the structure.
Mikael Holmstrom (c)
Second solution: CAN Driver classes
A class for each
CAN Driver is added
Issues:
The CAN protocol is actually two
protocols: CAN (layer two), and an
automotive specific protocol on top of
that. For example the variable ”Engine
revolutions” is received in four separate
CAN messages which must be merged
into the variable value.
Mikael Holmstrom (c)
Third Solution: A CAN application
protocol class
Abstraction
Aggregation
Mikael Holmstrom (c)
Good news: the application will be
used also in the US plant!
Issues:
In the US, Fahrenheit is preferred before
Celsius for temperature. This affects the code
displaying: oil temp and cooling water temp.
CAN protocol uses still uses Celsius.
Mikael Holmstrom (c)
Design choices
Make a sub VI to transform units. Call it from
the UI VI. Or...
Add a class
The choice is not obvious from current
requirements. First choice seems quicker but,
the gut feeling tells us to choose the second
option, to make it easier to extend and change.
Mikael Holmstrom (c)
Fourth Solution: Handling multiple units
Init – Read Display unit
from File
GetTemp (SI unit)
GetDisplayTemp
(Handles conversion from Volt->Temp)
Mikael Holmstrom (c)
New requirements: All measurements
must be stored
Design choices:
Add a sub VI and call it from UI VI
Add a new class
Extend an existing class
Mikael Holmstrom (c)
Fifth Solution: the data logger
Mikael Holmstrom (c)
Current Engine Example Design
We responded to
changed
requirements
by making
the design more robust
for those kind of
changes.
Mikael Holmstrom (c)
Changes which are easier with the
current design
Adding new CAN Interface boards
Changes in existing CAN drivers
Changes in the automotive CAN protocol
Adding or changing display units
Changing the calculation of the variable
value
Changing file format for the meas data file
Improving the user interface layout
Mikael Holmstrom (c)
Benefits of the improved design
Most modifications and extensions localized
to a single class
◦ Easier to understand how to change the code
◦ Easier to verify the change – test the class stand
alone first
◦ Easier to make the change
The benefits grows with the size of your
program!
Mikael Holmstrom (c)
Summary about Design
A class should have a single responsibility
Have only one reason to change.
Class name should reflect the responsibility or
the abstraction
Always add methods to try out new classes –
each class must add useful functionality!
Class name is a noun – method name is a verb
You cannot design for all future changes
The cost for structure is more classes and VIs
Mikael Holmstrom (c)
Single Responsibility Explored
Has this class a single responsibility?
”Have only one reason to change”
Init – Read Display unit
from File
GetTemp (SI unit)
GetDisplayTemp
(Handles conversion from Volt->Temp)
Mikael Holmstrom (c)
Single Responsibility Explored cont. 1
No! Responsibilities:
Reading default display type from file
Retrieving variable value from CAN
Unit conversion
This class has three reasons to change!
◦ File format change
◦ Changes in CAN class interface
◦ Unit additions
Mikael Holmstrom (c)
Single Responsibility Explored cont. 2
Should TemperatureVariable be split into three
classes?
Not necessarily
◦ Perhaps those changes will not occur
◦ We may be able to cope with these changes within
the class
Conclusion: Don’t redesign if current design
does not cause any problem!
Mikael Holmstrom (c)
Inheritance
Inheritance is a relationship between classes
Both methods and data is inherited from the
parent class
An object will have the data of its class PLUS
the data of all ancestor classes
Child classes can reuse methods from its
ancestor classes
Single inheritance
Mikael Holmstrom (c)
Inherited data
Mikael Holmstrom (c)
Dynamic Methods
Dynamic Methods makes inheritance rock!
A dynamic method is implemented by several
VIs
◦ Potentially one VI on each class in an inheritance
hierarchy
◦ Which one gets executed depends on object type
Mikael Holmstrom (c)
Dynamic Dispatch VIs
Mikael Holmstrom (c)
Wire can carry child class objects
Mikael Holmstrom (c)
Executed VI depends on Object Type
Mikael Holmstrom (c)
Why is this good?
You avoid these kind of case structures:
If type = DS182TempSensor then
call DS182TempSensor_MeasTemp
else if type = EP987TempSensor then
call EP987TempSensor_MeasTemp
...
Mikael Holmstrom (c)
Inherited data
Data is inherited from parent classes
But can it be accessed from a child class?
-> No, it cannot – it is private
It can only be accessed through parent class
methods
Parent Child
Mikael Holmstrom (c)
Accessing parent class data fields
GetGain and SetGain can
be called from child class
method VIs
Mikael Holmstrom (c)
Visibility of methods
Methods can be:
Public
◦ Can be called from any VI
Private
◦ Can only be called from class VIs
Protected
◦ Can only be called from child class VIs
Mikael Holmstrom (c)
Usage of Public Methods
Public
◦ Can be called from any VI
Use Public for the class VIs you intend for any
VI to use
Mikael Holmstrom (c)
Usage of Private Methods
Private
◦ Can only be called from class VIs
Use Private when you create utility VIs
intended only for other VIs of the same class
For example two public methods could use
the same private method to simplify their
block diagrams
Mikael Holmstrom (c)
Usage of Protected Methods
Protected
◦ Can only be called from child class VIs
Use Protected for utility VIs intended for child
classes only
A typical usage is to read-write data fields of
ancestor classes
Mikael Holmstrom (c)
Inheritance for Reference Based
Classes…
Mikael Holmstrom (c)
Recap: What is a GOOP 3/4 Class?
It is a LabVIEW class! With some extras...
A standard LabVIEW class containing an
◦ object repository – to store by reference data
Mikael Holmstrom (c)
Remember? Typical scenario for VIs
using refs
Create (or Open) – initializes and returns a
reference
VIs of the class – needs the reference to
operate on the correct data instance
Destroy (or Close) – performs cleaning and
frees memory
Mikael Holmstrom (c)
Discussion
Why are Create and Destroy called for each
level in the inheritance hierarchy?
Why does Create have the class name prefix
but not Destroy?
Mikael Holmstrom (c)
Aggregation - Topics
The class as a building block
Composite classes
Shared aggregation
Mikael Holmstrom (c)
The class as a building block
Using bricks, concrete, windows and doors you
can build a house
In the same fashion: classes can be used as
building blocks to build composite classes
The composite class uses its components to
provide higher level features
Mikael Holmstrom (c)
Example - Crossing
Mikael Holmstrom (c)
Example - Graphics
Mikael Holmstrom (c)
Forms of Aggregation
Composition
Shared
Mikael Holmstrom (c)
Composition Aggregation
Whole – part relationship
The same object cannot be a part in several
aggregates
The whole controls the lifetime of it’s parts
Examples: Crossing-TrafficLight, Circle-Point
Mikael Holmstrom (c)
Composite Aggregation – Demo
Mikael Holmstrom (c)
Shared aggregation
Same object in several aggregates
Mikael Holmstrom (c)
Shared Aggregation
Whole - part
The same object can be a part in several
aggregates
Only possible for by-reference classes
Mikael Holmstrom (c)
Terminology note
Composition aggregation a.k.a. Composition
Shared Aggregation
◦ Also described in UML as Association
◦ This choice does not affect the implementation
though
Mikael Holmstrom (c)
Shared Aggregation – Demo
Mikael Holmstrom (c)
Examples
Singleton
Active Object
Factory
Observer
83
Mikael Holmstrom (c)
Structure vs. Architecture
(c) 84
Mikael Holmstrom (c)
How do I start using OO?
and when should I use it?
Choices:
◦ Use OO for the major portion of the code or
◦ make a traditional breakdown and use classes for
utilities like: Files, serial communication etc.
Mikael Holmstrom (c)
Summary
OO programming is built-into LabVIEW!
The flexibility and structure gained from OO
is truly amazing
Use it to write ”clean code that works”
Use it to share code between applications
Use it to maintain productivity as the
application grows
Use it because it is fun
Mikael Holmstrom (c)