Wednesday, April 10, 2013

More UML Associations - Composition

In addition to being directed or bidirectional, associations may be aggregations or compositions.  These special classifications provide more information about the association.

A solid diamond on the composing class’ side of the association indicates composition, as indicated in the diagram.  If that diamond were hollow, the association would be an aggregation.  The next section contains more information about aggregations.



In many books, you read that compositions create containment.  The composing object contains the composed object.  While this description is true, it doesn't help explain the composition relationship or how to use it.  An alternative explanation is that a composing object “has a” composed object, as in “TimeBasedDetector has a Timer.”   Now, this “has a” description also works for aggregations.  So what is the difference and is it important?

The basic difference between aggregations and compositions has to do with where the objects are created.  In an aggregation, the object is created elsewhere in the model.  The links between objects get set during a post-instantiation/pre-runtime setup phase.  For composition associations, the composed object creates and destroys the composed objects.  It also must configure the link relationships.  Typically, one configures composition relations during instantiation, as shown in the code snippet below.

//## class TimeBasedDetector
public class TimeBasedDetector implements GenericDetector {
   
    protected int LastSensorValue;              
    protected Timer itsTimer;         //## link itsTimer
   
   
    // Constructors
    public  TimeBasedDetector() {
        initRelations();
    }
    //Called by constructor to create the timer composition and configure the links
    protected void initRelations() {
        itsTimer = newItsTimer();
    }

    // Construct the timer
    public Timer newItsTimer() {
        itsTimer = new Timer();
        itsTimer._setItsDetector(this); //configures the Timer’s link to point here
        return itsTimer;
    }
    //Configures the link
    public void _setItsTimer(Timer p_Timer) {
        if(itsTimer != null)
            {
                itsTimer.__setItsDetector(null);
            }
        __setItsTimer(p_Timer);
    }
    //configures the link
    public void __setItsTimer(Timer p_Timer) {
        itsTimer = p_Timer;
    }

    // Destructor
    //## operation ~TimeBasedDetector()
    protected void finalize() throws Throwable {
         cleanUpRelations();
        //#[ operation ~TimeBasedDetector()
        //#]
        super.finalize();
    }
    //called to delete the composed class
    protected void cleanUpRelations() {
        {
            deleteItsTimer();
        }
    }
    //sets the links to null so that the trash collection runs
    public void deleteItsTimer() {
        itsTimer.__setItsDetector(null);
        itsTimer=null;
    }

When we look at aggregation relationships, we’ll see that the construction/destruction of aggregated objects is not handled by the aggregating object.  Therefore, the difference between the two is very important for describing how the developers build the code.

Saturday, March 16, 2013

System Engineering Tools Demo -- For University Students


Here is a demo of Systems Engineering tools that I gave to university students today.  Ignore the date on the slides.

I'm not thrilled with the quality, so I will rework the video and post soon.

Monday, February 25, 2013

Bidirectional and Directed Associations

Associations allow classes to interact.  By interact, we mean calling an operation or accessing data.  In code, pointers or references implement associations in object oriented languages.    Functional languages, such as C, use pointers or references when passing data, but only require #include for accessing operations.

Technically, the previous paragraph isn’t right, is it?  Associations don’t allow classes to interact, they allow objects to interact.  UML Links instantiate associations.  That is, an association defines a generic pointer whereas a link defines a pointer to a specific object.  For simplicity sake, though, we’ll continue to discuss this subject in terms of classes and associations.

In the previous diagram, the line between Sensor and GenericDetector represents a bidirectional association.  That means that Sensor “knows” about (has a pointer to) GenericDetector and GenericDetector knows about Sensor.  Sensor refers to GenericDetector with the name itsDetector.  Similarly, GenericDetector refers to Sensor as itsSensor.  So, an object of type GenericDetector could call the Sense operation of an object of type Sensor.  In C++, the code would look like this:

     itsSensor->Sense();

Most of the time, however, only one of the two classes involved in the interaction needs a pointer to the other.  In fact, requiring bidirectional associations is generally considered bad design because it makes the software harder to reuse and to extend.  Instead, use directed associations, as shown in the attached figure.  Here, Sensor can call Reset() or ToggleValue(), but GenericDetector cannot call Sense.

Monday, February 18, 2013

Structure -- Class Diagrams

The interesting thing about structural diagrams is that they look very similar for both UML and SysML, but their interpretations are different.  Let’s start with UML Class diagrams because they are more basic and easier to understand.

Class diagrams, such as the one here, show classes and relationships among classes.  In UML, classes are entities that contain functionality (operations), data (attributes) and relations.  They are not necessarily language (code) classes.  When working in a structured language like C, I use UML to help define and allocate functions to files and variables to structures.

Associations are general relationships between classes.  They come is several flavors that we'll discuss here, but it helps to understand the basics before we get into the subtleties of the metamodel.  The easiest way to understand a relation is to understand how it gets implemented in code.  For simplicity sake, I am going to use C++ terminology and syntax.  The design principles apply to object oriented languages like Java, AND to functional languages like C.

In UML, classes have two primary types of relations:  a class can have an association to another class and a class may be generalized from another class.  Associations are how classes know about each other.  In C++, an association gets implemented as a pointer or reference.  Generalizations show an inheritance.  A class that generalizes another (the child) has all of the attributes and operations of its parent.

More on each of these relationships in the next few articles.

The figure shows these two relations.

Thursday, May 10, 2012

Adding Structure to Our Lives

UML and SysML classify diagrams as showing structure, interactions, or behavior.  Structural diagrams show the system's pieces and relationships among those parts.  Interaction diagrams show the communications among those pieces.  Behavioral diagrams specify how the pieces respond when they receive messages.  (Please note:  I used the term "pieces" specifically because it is not a UML or SysML term.  A piece could be a class, object, file, structure, block, or part) Structure diagrams serve similar purposes in both UML and SysML, it with some important differences.  For Systems Engineers, the entities represent abstract concepts about a system's decomposition.  For software developers, the entities represent code that will be created (i.e., generated or handwritten) to implement the software application. The next few articles discuss structural diagrams.  

Tuesday, April 17, 2012

Coding, designing, and modeling

"How can I do my design when I haven't written the (expletive deleted) code yet?" a former colleague yelled quite irately as I passed by a manager's office.  Now I know Joe.  Yes, sometimes he would start out coding and end up with some useless methods and classes.  But Joe always had an idea of his code's basic structure.  What Joe meant to say was that he could not write the detailed documentation of his design because he hadn't worked out all the details yet.

Unfortunately, many developers look at modeling the way Joe looked at design -- as a documentation step to be completed rather than something that helps the goal of producing properly executing code quickly and efficiently.

Modeling helps developers visualize the structure, interactions, and behavior of the system they are building (NB:  I used the plural because developers seldom work alone.  One must be able to communicate one's ideas;  more on that in another article).

In fact, in a 2008 survey by Scott Ambler found that the vast majority of developers used high level diagrams.  From my own practice, I'm assuming that the majority use class diagrams to define structure. I'll bet that a fair number of developers use some variation of sequence diagrams when discussing interactions as well.  Here is my point:  If you are already using these two common diagrams, why not capture the artifacts in a tool rather than on a white board?  Doing so makes the artifacts reusable and captures the design rationale for the rest of the team (including reviewers and maintainers).

Bottom line:  if Joe had captured his thoughts in a model, he wouldn't have had the scream match with his boss.  He might even still be working there.

Thursday, April 12, 2012

Refining Use Cases with Activity Diagrams

In a previous post, I discussed text based use case descriptions. This post discusses a graphical method:  activity diagrams.

Before discussing the advantages of refining use cases with activity diagrams, let's define activity diagrams.  One of my colleagues describes them as "flow charts on steroids."  Activity diagrams show the possible sequences of activities and the flow of data between activities in a single view.
The rectangles with rounded corners represent activities.  In the software world, an activity would be implemented as a functions or method.  On this diagram, the dashed red lines represent the order  that the actions occur.

Unlike text, graphical activity diagrams are not open to interpretation.  Even people not trained in UML's or SysML's subtleties understand an activity diagrams flowchart-like structure.  Complicated concepts, including exception condition handling, become clear when viewed on a single page.


Note that you may use nested activity diagrams (not what they are called, we'll get to the proper name later) to describe complex actions.

 In summary, the advantages of using activity diagrams to refine use cases include:
  • Graphical representation is not open to interpretation the way text is
  • Shows multiple paths (including exception conditions) in one view
  • Complex actions may be further refined with other activity diagrams