Charleston SC JUG Meeting Tonight

We will be having another installment of the Charleston SC Java Users Group meeting tonight. I will giving an introduction to Grails presentation.

Swing by if you are going to be in the area!

You can get directions and more info here.


Decomposing UML

I have been working on a project for the past couple months in my spare time. The problem is that with a new baby, the Java Users Group, maintaining my design patterns references (Version 1, Version 2), this blog, and work I have had no time over the past month to actually work on it. The other night I managed to find some time to work on this for a while, only to realize that I had stopped in mid-implementation with only a class diagram and my memory to work from. I should have documented the requirements better from the beginning but since the application is for me and I planned on finishing it quickly I didn’t see a need.

So I found myself the other night with a pretty complex class diagram with no explanation of what the various classes, attributes, and associations signify. Oops. So to figure this out I came up with a method of supplementing the class diagram that ended up working pretty well for me. I have not seen this used anywhere else so I’ll stamp my great big ™ on it. Hopefully you will all find this as useful as I did.

Lets just work through a quick and dirty contrived example:

post.gif

While it is pretty easy to implement this actual data model, it is considerably more difficult to apply business rules to the application based on just this. So I took my diagram and worked backwards in a couple parts:

Part 1: Class cases
This part defines the cases when each class will be created, updated, and/or destroyed. The notation is simply to use the class name followed by a description. Each description should start with the words created, updated, or destroyed so that a quick glance will tell the meaning of the line. If creation, updating, or destruction does not occur, just leave it off.

So in our scenario, we would have:

Person

  • Created when a new user signs up for the site (will be locked until authentication
  • Created when an administrator adds the user via the admin console.
  • Updated when the user or admin changes aspects of the person profile.

Feedback

  • Created when an attendee enters feedback for the meeting they have attended.
  • Updated if the attendee wishes to update their entry.
  • Updated by admins if content needs to be cleansed.
  • Destroyed only if the attendee chooses to erase the feedback.

Meeting

  • Created when a meeting is scheduled the admin will create the meeting through the admin console.
  • Updated only by admin in the event that details about a meeting change. After the meeting date, no changes can be made.

Attendee

  • Created when a person attends a meeting and “signs” the check-in form.

Part 2: Relationship cases
This part defines the cases that relationships would be created, updated, or destroyed. While this will prove useful for all associations, it will prove more useful for those where the association exists independently of the classes involved. The descriptions are the same as in part one in that they should each begin with the words created, updated, or destroyed. However, the notation is a bit different in that the relationship must be captured in the notation. To signify this we will use the two (or more) objects involved in the relationship, connected by a line. I used a slightly different notation as it is plain-text compatible, however using the UML connector notation would work just as well.

To define a one to one relationship, you would simply link the two objects with a line:

OneObject —– AnotherOneObject

To define a one to many relationship between two objects you would use an open bracket at the end where the many relationship is:

OneObject —-< ManyObject

To define a many to many you could use a couple different notations:

OneObject —-< ManyObject >—- AnotherOneObject

or
OneObject >—< AnotherOneObject

Finally, to note realizations you use the same notation, only with a dashed line:

RealizingObject – – – RealizedObject

So in our case this would yeild:


Person – – – Feedback

  • Created when a person, who is also an oragnizer (aka admin) reviews the feedback.
  • Destroyed at the end of the viewing – this is not a physical link between the two classes.

Person —-< Attendee >—- Meeting

  • Created each time a person attends a meeting.

Attendee —– Feedback

  • Created when a person writes feedback for a particular meeting.
  • Destroyed when a person decides to erase the feedback.

By using this notation I can document the purpose of each class and relationship as well as the conditions in which is created, updated, or destroyed. By working from this I can now quickly determine what business rules I need to implement in order to maintain the proper relationships and objects within the system. While this is a pretty simple feat with this contrived example, it becomes significantly more complex when you have 20+ classes and the same number of associations and references.


Closures

Closures (aka Blocks) are essentially blocks of code that can be passed as arguments to a function or method. Unlike method pointers, anonymous classes, and other similar things, closures have the unique ability to be able to see the value of variables in the same scope they were created in. For example, if you declare a variable on one line and a closure on the next, the closure will have visibility of the variable when the closure executes, assuming it is passed into the closure.

Martin Fowler has a great example of this. To pull only certain items out of a collection in Java you’d have to do something like this:

public static List<Item> getItemsWeCareAbout(List<Item> orig) {
  List<Item> toReturn = new ArrayList();
  int val = 230;
  for (Item item : orig) {
    if (item.meetsConditionWeCareAbout(val)) {
      toReturn.add(item);
    }
  }
  return toReturn;
}

However, the same code in Ruby can be done like this:

def items_we_care_about(orig)
  val = 230
  return orig.select { |i| i.meetsConditionWeCareAbout val }
end

The Ruby version utilizes closures in that we can pass a block of code into the select method. The actual closure is the code within the curly braces ({..}). This code simply says that each item ( |i| ) that returns true from the meetsConditionsWeCareAbout method should be included in the return collection. Also note that the variable declared in the method is passed into the closure, meaning that the closure has visibility into the variable each time it is executed, not just when it was defined.