Higher and higher
Menu

Web Push?
Collections
IDL Design
Java In Practice
Singleton
Contact Us
-- Home --


Announcements

A new look for a New Year! Help us to reach new summits.


Selected Partners

IDL and Attributes!

This article was written a while back when I was involved in fairly big CORBA projects. The design techniques however have not changed with the advent of EJB and RMI/IIOP. The reader will recognise the use of the design pattern "ValueObject" commonly used in J2EE systems. The rationale for it is explained here.


This small article will discuss some design issues with IDL and attributes. It will also discuss the flexibility versus specificity of IDL design.

The IDL is probably the most critical part of a server, it is its contract. Poorly written, it will jeopardize efficiency of the interaction with the server but it could also ruin any chance of re-use if the interface is too specific to one application. As usual, a compromise must be reached.

We will take the following example:

Iteration 1:

interface A
{
   readonly attribute int a1;
   attribute string a2;
};

Well, I have several issues with this...

CORBA does not allow the server to throw any exception on an attribute; in the likely hypothesis that your server has to go to the database to fetch the attributes of A, this means that you have to design a difficult and dirty kind of mechanism to report the error. So, here is a sweeping statement for you: Never Use Attributes.

Iteration 2:

interface A
{
   int getA1() raises(SomeException);
   string getA2() raises(SomeException);
   void setA2(in string a2) raises(SomeException);
};

Please note that for a1, we have only a getter interface (since the attribute was readonly). Looks good doesn't it? In a pure OO fashion, I would say ok, it looks ok. However in a distributed environment it is not ok. It is inefficient if your object had 10 attributes, the client would have to call 10 remote methods; if your client is based in Singapore that it about 4 sec in network latency alone... just to get attributes, not acceptable!

Iteration 3:

interface A
{
   struct Details
   {
      int a1;
      string a2;
   };
   Details getDetails() raises(SomeException);
   void setDetails(in Details d) raises(SomeException);
};

Hum... In order to efficiently pass the values of attributes, we could define a structure (which is passed by value in CORBA) that contains our attributes. One call and everything is passed to the client, one call and everything is set. Ooops! There are 2 big problems:

How can I enforce that the a2 is readonly? just ignore it? throw an exception is different from the one held in A in the server?

How about robustness to changes? Say I want to add an a3 attribute for a new client/application usign this service:

I cannot do this:
interface A
{
   struct Details
   {
      int a1;
      string a2;
      float a3;
   };
   Details getDetails() raises(SomeException);
   void setDetails(in Details d) raises(SomeException);
};

Simply because it would force me to re-compile and re-release all existing clients. And that is a capital sin as mentioned in another article (it would obviously keep the support guys very busy, but that is not the point). Is it possible to change an IDL without forcing a client recompilation? Yes! How? Adding a method does not force you to re-compile but how efficient can it be?

I could do this:
interface A
{
   struct Details
   {
      int a1;
      string a2;
   };
   Details getDetails() raises(SomeException);
   void setDetails(in Details d) raises(SomeException);
   float getA3() raises(SomeException);
   void setA3(in float a3) raises(SomeException);
};

But then we just revert to the efficiency problem... end of contract!

In desperation, I could do this:

interface A
{
   struct Details
   {
      int a1;
      string a2;
   };
   Details getDetails() raises(SomeException);
   void setDetails(in Details d) raises(SomeException);

   struct SuperDetails
   {
      int a1;
      string a2;
      float a3;
   };
   SuperDetails getSuperDetails() raises(SomeException);
   void setSuperDetails(in SuperDetails d) raises(SomeException);
};

Are you serious you must be screaming! No, I was not! Forget it!

One technique is in fact to "lose" some compilation time safety and go for more flexibility... Imagine that each attribute can be described as a pair: Name-Value we would have:

NameValue (of type)
a1int
a2string

Imagine we have a sequence of those structures. Here is the IDL we would have:

Iteration 4:

struct AttributeS
{
   string name;
   any value;
};
typedef sequence SeqAttribute;

interface A
{
   SeqAttribute getAttributes() raises(SomeException);
   void setAttributes(in SeqAttributes d) raises(SomeException);
};

Ooh God, we have introduced, the terrible CORBA.Any... so what? We have kept the efficient transfer of data (through a list of attributes) and gained the flexibility to let the developer add attributes without having to re-compile the existing clients.

In another episode we will describe how we can improve the interface with Attribute Getter and Setter interface that could return the definition of attributes (readonly or not).

Nice and easy!

Thank you.

Benoît Xhenseval.

© 2003 Xhenseval.com. All rights reserved. Page design by B a s i c T e m p l a t e s . c o m.
Site Meter