Tuesday, December 20, 2005

What is an object supposed to know?

I must apologies for the long deley between posts, unfortunately, I have just battled to come up with anything interesting to write. Hopefully this post will change this.

I have recently started investigating Enterprise Java Beans. It has been both interesting and frustrating. Entity beans I find to be hugely complex, all the local/remote/home/bean concepts are to my mind, having used JDO extensively, rather complex and difficult to grasp. Let's hope EJB 3.0 is all I'm hoping it will be...

Anyway, back to the matter in hand.

I was reminded of the relationship between what an object does and what an object knows. These two concepts are inextricably linked and should be carefully considered. To take an example from the real world - there are often times when knowledge is specific to the role of that person/entity. The classic - need to know basis. As an employee of a company I am given enough information to perform my set tasks, and no more. There is certain pieces of information which I should not be provided with, because they involve knowledge that is outside of the ambit of my responsibility.

The other scenario where knowledge is important is when I need to find out something. I should immediately be able to deduce the person or entity which possesses that knowledge. The knowledge required should be congruent with the person or entity who possesses that knowledge. It would be inappropriate for the cleaning staff to know the bank account details of the company for instance.

Now let's bring out thoughts into the object space. Like I was saying, I've recently started looking at J2ee and Enterprise Java beans. I'm using the Eclipse Web tools project to do the development. When you request an enterprise bean you have to do a JNDI lookup in order to locate that bean - you provide it with a name, and it returns a bean. When eclipse sets up a bean for you it creates a Util class which knows how to lookup the bean (one util class per bean). Thus this util class not only has the behaviour to lookup the bean but also the knowledge.

Personally, I do not believe a class that uses a bean should be required to know the location of the bean. The reason for this is that a class that uses a bean has a functional job. Imagine you create a class to lookup employee details. This class calls an EJB to achieve this end. The directory information require to locate the bean has little to do with the job which the class is assigned. Thus that knowledge of where the bean is should not be stored in the bean. The class kinda thinks, all I want is a hook onto this bean, I don't want to know where it is, why do I care?

The thing to remember is that a class is defined by its behaviour as well as its knowledge. In other words, looking at the data which a class contains, be it static or dynamic, is a valid and important mechanism for determining what the class does. If a class contains the database connection url, then it clearly must be responsible for connecting to the database. Thus it could easily have two responsibilities (bad idea), some other responsibility which requires a database connection.

One of the advantages of providing classes with data on a strictly need to know basis is that duplication is reduced. If I have a class whose sole responsibility is to acquire a handle onto an EJB, if I wish to change the lookup information for that bean I only have to change it in one place. This is because only one class "knows" that information. The other classes are not privy to that information, why should they be?

In light of this there should probably be more objects in our code, with potentially more static methods as well. On the one project I worked on I implement a help system. I created a class with a number of static methods which contained the code for hooking and displaying the help. I effectively created a help "service". The class was full of static methods - changing the help system was as easy as changing this class.


Peter said...

One problem I always had was where to put your programme-wide logic. Static methods are one way to do it, and a very good way I have found. Another way is to create a Registry (the name comes from Martin Fowler's Enterprise Patterns for Application Architecture). A Registry is simply a collection of static methods that each give you an object. So to get the next invoice number I would call Registry.InvoiceNumberController.GetNextInvoiceNumber() or something that effect. The advantage here is that you would make these objects implement interfaces so you can plug in mocks or nullobjects if you want to. In your main() you set up your Registry with all the relevant implementations you want.

For example, to turn on or off auditing I would set Registry.AuditController = new DatabaseAuditController() or NullAuditController(), and ensure all Audit calls go through Registry.AuditController. These objects are probably very similar to stateless EJB's.

Michael Wiles said...

So you have static interfaces in your Registry... that is a novel concept.

The Registry then holds all your functions - stateless methods are equivalent to functions.

The other day I read a rant about the singleton pattern, could see where they were coming from. This is arguably a better option.

Peter said...

Yeah, I suppose a Registry is actually supposed to store objects in a Hashtable of some sort, but I find it easier just to make static methods that give you a strongly typed object.

Yes, the Registry is really where all my functions go, but the advantage over static functions is they're polymorphic functions.

I've read lots of rants about Singleton too, most of them do make sense and this covers most of the issues I think, but the onus is on the main() to set up the objects.

How important is the programming language?

  Python, typescript, java, kotlin, C#, .net… Which is your technology of choice? Which one are you currently working in and which do you wa...