Friday, November 21, 2008

Why Object Oriented Programming?

Clarity

Object oriented programming expresses the design in terms of the problem domain rather than the programming domain.

There is need for a new software application that obtains configuration information from Automatic Test Equipment (ATE). Thinking about what needs to be accomplished, my first thought would be that a cluster of configuration information would be common to most of the program. So I might write something like this:




Hmm, we have several nested cases. If we printed out the block diagram it would look like this:



Let’s try an object oriented approach to the same application. The first thing we would do is figure out what objects we would need. If we made a top level object, our top level VI might look like this.


The VI is simpler. There are no hidden cases. If we print the block diagram, the above is what we get. Each function is obvious from the icon on each VI. But perhaps most significantly, the conditions that affect the program are now obvious. All the logic depends on two conditions, whether a configuration file already exists and whether the ATE configuration changed. These now stand out in our top level VI.

Thursday, November 20, 2008

Object Oriented Programming Terminology

An object is an instance of a class. Multiple objects can be created from a class, and they will all be running identical code, but each object contains different data. In LabVIEW terms, a VI called by multiple VI’s makes each caller wait for access the same VI (unless the VI is reentrant). Defining a VI as a part of a class means that every object runs the same code, but because of the data storage mechanism and object references each caller may be acting on a different set of data.

Texts on object oriented programming use different terminology, but most will use one or more of the following.

To describe the data of an object:
Attribute
Property
Data
Variable

To describe the actions an object takes:
Action
Method
Behavior

In the discussion of the single element queue object oriented programming technique, the data is a cluster typdef labeled “cluster of private data” and the methods are referred to as method VI’s.

The Contract

Different programming languages have different amounts of support built in for object oriented programming, but object oriented programming is a design concept more than it is a language feature. LabVIEW 7.x has no inherent features to support object oriented programming, but we can still design our software application using object oriented techniques by establishing a contract. The contract is that we as developers will only access an object from outside the class via its public methods, that we will only access the data from within the class using private methods, and that we will never access the data directly.

Wednesday, November 19, 2008

SEQOOP Implementation Details



Organization on Disk

With LabVIEW 8.x the LabVIEW Project can be used to designate folders as public or private. That feature is not available in LabVIEW 7.x, so the software developer must keep VI’s organized in folders. A basic rule is that every class gets a separate folder. The main folder of the class might contain demonstration or test VI’s used to demonstrate how to use the class or to test the functionality of the class. It might also contain a Catalog VI that presents the VI’s of the class in an organized manner, as below.



Below is an example of a folder structure. Note that there are public and private folders.






Public Methods

The Public folder contains VI’s that are intended to be used in an application. Examples would be Set Voltage_PowerSupply.vi, Set Current Limit_PowerSupply.vi, Output On_PowerSupply.vi. Examples of method VI’s for a base class are below.








Private Methods

The Private folder contains VI’s that are only intended to be accessed by VI’s of the class, and not by other VI’s or classes. An example would be a VI for data storage class that converted a tab-delimited text file to an XML file. The VI might be called Tab-Text to XML_DataStorage.vi.

Data Access VI’s

A sub-folder usually present in the Private folder is a folder named Internals. It usually contains three VI’s that other VI’s of the class use to access data. Names of these VI’s would be similar to Get Data_PowerSupply.vi, Get Data To Modify_PowerSupply.vi, and Set Modified Data_PowerSupply.vi. Examples of Data Access VI’s are below. Every time Get Data to Modify_PowerSupply.vi is run it should be followed with Set Modified Data_PowerSupply.vi. Be aware that the data is locked and not accessible by other VI’s until Set Modified Data_PowerSupply.vi is run.



The Data Component

A sub-folder of the Internals folder is the Data Component folder. It contains a VI similar to Data Component_PowerSupply.vi. It also contains a typedef that is used as a constant to control the action the Data Component takes when run. The typedef would have a name similar to Data Component Action_PowerSupply.ctl. The data access VI’s wrap this component to handle data access.

The data that is being accessed is the data contained in the queue. The data type is the type of “cluster of class private data.” This is the data for the PowerSupply class.

The Data Component extracts the class name contained within the object ID from the object reference and compares it to a constant that is the same as the name of the class. In this case it is the PowerSupply class. If the class name is not found within the object ID, an error is generated.

The Data Component has five cases, corresponding to the settings of the Action control. The first case is Create. The Create case creates a named single element queue. The name of the queue is the object ID. The data type of the queue is the data type of the “cluster of class private data” input. The Create case then enqueues an element to set the initial value of the data.


The next case is the Get Data case. It previews the queue element. This allows the data to be read without removing it from the queue, so the data values in the queue are unaffected.




The next case is the Get Data to Modify case. It removes an element from the queue. Since this is a single element queue, the data is unavailable until it is again enqueued using the Set Modified Data case. We have a mutex without having to use a semaphore or other protection.


The Set Modified Data case enqueues the data. The data is again available .


The last case is Destroy. It releases the queue reference.


Object References
The object reference is a cluster made up of two components, Object ID and Class Data Type.

Object ID

The Object Id is a string. An example of the string for a base class would be: “PowerSupply:123456”. The string contains the name of the class, in this case the PowerSupply class, and a numerical portion that is uniquely generated each time a “Create” VI is run.

An example for an Object ID string for a class with two levels of inheritance would be: N6700:234567ProgrammablePowerSupply:345678PowerSupply:456789

The Object ID string is parsed by the Data Component to determine if it contains a valid reference to the class that the Data Component is a member of.

Class Data Type

The class data type is typedef that is a Datalog control containing an Enum control. The Enum is set to the name of the class. A Datalog control is the only way to make a unique data type in LabVIEW. Including this gives the object reference control a unique data type, which prevents inadvertently wiring VI’s from different classes together. Note in the example below that we get a broken wire when an object reference from the ATEConfig class is wired to a VI from the ConfigStorage class.



Creative Commons License
LabviewGeek Blog by C. Allen Weekley is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Permissions beyond the scope of this license may be available at http://www.weekleysystems.com/.

SEQOOP versus GOOP and LVOOP

SEQOOP is Single Element Queue Object Oriented Programming

GOOP is Graphical Object Oriented Programming. It is a toolkit developed by Endevo in Sweden and distributed in the USA by VI Engineering. Versions are available for LabVIEW versions 7.0 and later.

LVOOP is the native LabVIEW Object Oriented Programming included in LabVIEW versions 8.2 and later.

LVOOP Advantages
- Native to LabVIEW, no toolkit required
- Object wires for different classes can have a different appearance

LVOOP Disadvantages
- Only supports By Value, no native By Reference implementation
- Each branch of an object wire creates a new copy of the data
- Classes are easily corrupted, and if that happens the entire class must be written again.
- Requires LabVIEW 8.2 or later

GOOP Advantages
- By Reference implementation
- Good tools for building classes and editing icons en masse
- Endevo offers a UML toolkit that works with both GOOP and LVOOP classes
- Versions available going back to LabVIEW 6.0

GOOP Disadvantages
- Creating a class makes many VI’s that are related to class handling, but do not relate to the problem domain
- History of broken features when LabVIEW version changes
- May not handle a very large number of classes
- GOOP Toolkit and UML Toolkit must be purchased and licensed

SEQOOP Advantages
- By Reference implementation
- Simple, no password protected VI’s, implementation is clearly visible in LabVIEW
- Queues are fast and robust
- Works with LabVIEW 7.x and LabVIEW 8.x without modification

SEQOOP Disadvantages
- New classes must be manually created (but perhaps some template VI’s could alleviate this)
- No tool for editing icons en masse
- Does not perform dynamic dispatch

Crosslinking, Namespaces, and Naming Conventions

A good feature of LabVIEW is the use of plain English names for VI’s. This makes it more programmer-friendly, particularly when one is reading someone else’s software. Crosslinking has been a historical problem in LabVIEW programs, as it can be in other languages. This happens because VI’s in two different sets of software are given the same name, for example “Initialize.vi.” If a project is loaded and that uses Initialize.vi, and then a second project opened that has different VI that also has the same name Initialize.vi, the second project will find Initialize.vi already in memory and link to it. Then if the second project is saved the link to the wrong Initialize.vi is saved.

Other languages use namespaces to try to prevent this kind of crosslinking. National Instruments addressed this with LabVIEW 8.x, which provides namespaces using the LabVIEW project. There can be an Initialize.vi in two different projects, but the LabVIEW Project effectively provide a separate namespace for each project, so there is less chance of crosslinking. We have ongoing projects in LabVIEW 7.1 because of test equipment constraints, so a convention has been adopted to reduce the chance of crosslinking. This is simply to add a prefix to each VI using the software part number and an underscore. Now instead of having VI’s in two different locations named Initialize.vi, we have a VI named CA789267_Initialize.vi and another named CA578923_Initialize.vi. Now we have little chance of crosslinking, because the VI’s have different names, and it is clear at glance which one belongs to which project.

Now, using Single Element Queue Object Oriented Programming, we also need to uniquely name each VI with the name of the class it is part of. We accomplish this with a suffix. If we had two DMM classes named HP34401 and Keithley2000, there would be a VI in each class to set the range, and they would be named Set Range_HP34401 and Set Range_Keithley2000. Again, the possibility of crosslinking has been reduced and it is obvious which class the VI belongs to. If these VI’s were part of a development project, they might be named NewProject_Set Range_HP34401.vi and NewProject_Set Range_Keithley2000 until the project has been assigned a software part number, then changed to CA678354_Set Range_HP34401.vi and CA678354_Set Range_Keithley2000.vi.

By the way, do not try to look up any of the above software part numbers. They are fictional and used just as examples.

How can all the above renaming be easily accomplished without individually opening and re-saving each VI? There is a tool to copy and rename the VI’s in entire hierarchies of folders on the LAVA forum at http://forums.lavag.org/GOOP-Tool-to-copy-classes-t1460.html.

Steps to Create a New Class

Make a copy of the entire folder hierarchy of an entire class.

Rename all VI’s to change the suffix of the VI names from the old class name to the new class name.

Edit the icons of all VI’s to reflect the new class name.

Change the string constant in the data component to the new class name.

Edit the Class Type typedef control so that the name in the enumerated type is the new class name.

Edit the “cluster of private class data” typdef to use the data for the new class.

Delete existing method VI’s and create new methods appropriate to the new class.

“By Value” versus “By Reference"

This subject is discussed in courses and tutorials for many different programming languages. C++ can use either, but Java only uses “By Reference.” “By Value” means that the data is passed to a function, and when the function modifies the data it is not modifying data anywhere else. “By Reference” means a reference to the data is passed to a function, and when a function modifies the data it is modifying the original data store.

The implementation in LabVIEW 8.5 is “By Value.” The object reference actually contains the data. This can be seen because “Unbundle By Name” can be wired to the object reference to directly access the data. See the example below. Also see “LabVIEW Object Oriented Programming: The Decisions Behind the Design” at the following link: http://zone.ni.com/devzone/cda/tut/p/id/3574.


The “By Value” nature of the LabVIEW 8.5 OOP implementation is also shown in the following example:


If this was a “By reference” implementation, the lower “Set Numeric” VI would set the value to 9, but because it is a “By Value” implementation it sets a copy of the data to 9. The value on the upper branch of the object reference wire is not affected. The “Get Numeric” VI returns a value of 5, even though dataflow is controlled so that it executes after the lower “Set Numeric” VI. With the “By Value” implementation whenever a wire branches a copy of the data is created.

With the Single Element Queue Object Oriented Programming, the data is stored in a named queue with a unique ID. The object reference wire does not contain the data, but contains a reference to the queue that stores the data.


In the example above we see that even though the object reference wire is branched to a “Set Voltage” VI that set the voltage value to 9, but the original object reference wire is connected to the “Get Voltage” VI, the value has been set to 9. Branching the object reference wire does not result in a copy of the data. There is only one copy of the data, and it is accessed by a reference to a value. (Also, note that because we are actually using a “By Reference” paradigm, we need to create and destroy the object reference.)




Creative Commons License
LabviewGeek Blog by C. Allen Weekley is licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License.
Permissions beyond the scope of this license may be available at http://www.weekleysystems.com/.

Tuesday, October 21, 2008

Presentation on LabVIEW Object Oriented Programming

Here is a copy of a presentation about GOOP (Graphical Object Oriented Programming) I made at a LabVIEW User Group meeting in Orange County, California, in 2004.


GOOP

Graphical Object Oriented Programming

Allen Weekley July 29, 2004


OOP Languages
•Object Oriented Programming is a design method, not a language

•Some languages have support for OOP built in

•OOP can be used in LabVIEW with the GOOP Inheritance Toolkit

•Toolkit was created by Endevo in Sweden and is distributed in USA by VI Engineering


Benefits and Goals of OOP

•Natural

•Reliable

•Reusable

•Maintainable

•Extendable

•Timely


Benefits and Goals of OOP

•Natural
–Instead of programming in terms of software constructs, you program using the terminology of your particular problem –You can model a problem at a functional level instead of an implementation level

•Reliable
–The modular nature of objects allows you to change one part of a program without affecting other parts
–You can easily test OOP classes as independent modules

•Reusable
–Modularity allows you to easily reuse code –Inheritance allows you to extend existing objects
–Polymorphism allows you to write generic code
–Natural terminology makes code easier to understand
–Improving the code within an object will benefit all code that calls the object
–Encapsulation keeps calling software from breaking because the interface does not have to change when the implementation changes

•Extendable
–Inheritance allows you to easily create new classes from existing classes

•Timely
–Natural software simplifies the design of complex systems
–Multiple programmers can easily work on the same project because each task can be a standalone object that can be developed and tested independently


OOP Paradigm

•OOP is “Real World” –The goal is to program in terms of the problem to be solved rather than the requirements of the software environment

•An object holds state and behavior

•OOP is a contract –Access to data is only through the object interface

•So, behavior goes along with data
–Methods :: behavior
–Attributes :: data

•Access to an object is only through the interface –A method accesses attributes


Object Interface

•What is an interface in LabVIEW?
–Attributes are a cluster –Methods are VI’s

•Access is only through methods –In LabVIEW a method is a VI

•There are both public and private VI’s
–The contract is that a user of an object uses only public VI’s
–Private VI’s are to be used only within the object


Class

•A class is the design of an object

•A class defines the attributes and behaviors shared by a type of object

•A class is like a template or cookie cutter


GOOP Classes and Objects

•In GOOP
–A class is a group of VI’s on disk
–An object is the dynamically created references and data space

Object

•An object is created by instantiating a class
–In LabVIEW a “Create” VI is run that produces a unique refnum
–The reference is typed for the class
–Connecting to VI’s of any other class will produce an error at design time (the “broken arrow”)
–Each instance has its own set of data (a copy of the “attributes” with values unique to the instance)

•The using program can create multiple instances, each with its own data space, without any special programming


Class and Object Example

•A system may use two HP34401 DMM’s, say serial number 5683 and serial number 5798

•Two instances of the HP34401 object would be created from the HP34401 class

•If you ask each object for the serial number, one object would return SN 5683 and the other object would return SN 5798

Using GOOP Objects

•The paradigm is similar to file I/O functions
–File: Open – write data – close
–Object: Create reference– execute method – destroy reference


Object Oriented Concepts

•Encapsulation

•Inheritance

•Poymorphism


Encapsulation

•Data is isolated within the object

•Access from outside the object is only through a defined interface

•The implementation of the object can be changed without affecting the code that uses it, as long as the interface is not changed


Inheritance

•An class can inherit methods from a base class

•Less programming is required because code is reused


Polymorphism

•Methods can be redefined in subclasses and dynamically bound at runtime –
A method in a base class that is called by sub class reference will first check to see if a sub class method exists and run it; if not it will run the base class method

•Code is easily extended because you only have to write new methods for the things that are specific to the subclass; the rest of the base class can be used without alterations

When To Use GOOP

•Use GOOP for
–Large projects
–Multiple developers
–Projects that you know will have many changes


Object Oriented Design

•UML – Unified Modeling Language
•Less formal design methods


More Information

•Endevo – Developers of GOOP Toolkit
–www.endevo.se

•VI Engineering – US Distributor of GOOP Toolkit
–www.viengineering.com

•Open Source GOOP Toolkit
–http://www.openg.org/tiki/tiki-index.php?page=OpenGOOP

•White Paper on GOOP Inheritance Toolkit
–http://www.endevo.se/default.asp?lang=eng

•GOOP Application Note
–AN143

•GOOP Tutorial
http://zone.ni.com/devzone/conceptd.nsf/2d17d611efb58b22862567a9006ffe76/5d7db42c91f392fc86256aae00463d78?OpenDocument