ECO: Categories And Recursive OCL
"Ouch, recursive, don't want to hear it..." - Well, give it a shot... you'll like it, I am sure of it.
Categories pretty much appeared in any model given as an example how to build certain things using ECO. There was a class "Category" mostly all the time. But none of the examples really got into the details how to build a hierarchy of categories. Thus, you could use the "Category" class for navigation in ASP.NET-projects e.g.
Let me give you an example: We want to list all the blogs of Borland employees. So my root category is "Borland". I distinguish in my example between "R&D" and "DevRel". So my second level consists of those two "nodes".
If you clicked on "Borland" and "DevRel" you get something like "> Borland > DevRel" in your navigation, so you know where you are. I heard the term "breadcrumbs" for that kind of caption.
As I am a very lazy programmer I want to let ECO handle most of the maintenance. I just want to specify the names and want to name a certain category a sub-category of another one (of course, with ECO you can also add children to a parent-node, i.e. vice-versa).
Summing up the model: The only non-derived attribute is "name", which identifies the category. All other attributes are read-only and maintained by ECO. ECO can determine the level of a category in the "category tree" and can also return the "full name" (aka breadcrumb) to you. I achieve this using recursive OCL.
Let's have a look at the associations of Category first. There is only one association and it is directed at Category itself. Yes, it is possible, even if it looks funny at first. I changed the multiplicity, so that each Category can have multiple offspring (role: Children), but only one parent (role: Parent). You can change that of course, but this example is already complicated enough if you never handled recursion and ECO. This little trick allows us to access the name of the parent category by specifying "Parent.name".
So I derived the level of a category like this:
And the breadcrumb-String is calculated using these lines of native OCL:
- Level:To understand it, start with one category. Its level is 0. Now think of one category with one sub category. Nothing changes for the "root", but the first child category has the level 1, as Parent.level + 1 = 0 + 1 = 0. That's it. (Call my explanation a poor-man's-proof by induction... ;-) And yes, I know it is not complete or formally correct.)
- Full name:It works the same way as level, but instead of adding 1 to the level on our way up the tree, we add the name of the current category to the full name of the parent node.
Be aware that you must have a starting condition/point. In this case it is that a category does not have any parent and thus is on the root level. Otherwise, you end up with an endless loop.
As always, I created a tiny, simple demo application. I add the following objects to my Eco Space by code:
procedure TWinForm.TWinForm_Load(sender: System.Object;
e: System.EventArgs);
var
cmain: Category;
csub : Category;
csubsub: Category;
begin
cmain := Category.Create(EcoSpace);
cmain.name := 'Borland';
csub := Category.Create( EcoSpace );
csub.name := 'R&D';
csub.Parent := cmain;
csubsub := Category.Create(EcoSpace );
csubsub.name := 'Jonas Högström';
csubsub.Parent := csub;
csubsub := Category.Create(EcoSpace );
csubsub.name := 'Jesper Högström';
csubsub.Parent := csub;
csub := Category.Create( EcoSpace );
csub.name := 'DevRel';
csub.Parent := cmain;
csubsub := Category.Create(EcoSpace );
csubsub.name := 'John Kaster';
csubsub.Parent := csub;
end;
Finally, I built a Winform with a simple grid that shows all the properties of the instances of the class "Category":
One can easily see the possibilities this opens for web site development as you can build your navigation this way. Furthermore, you can include the "Category" class in lots of models. Take note of the fact that this approach is completely "pluggable" into any other model without using any functionality. You also never have to reinvent the wheel again for objects that have these characteristics.
Have a Happy New Year everybody!