“Object Calisthenics” : Jeff Bay – II

Following my Previous post on this topic, I have been in contact with Jeff via email, and he mentioned that the version of the chapter which is on his website is a preview version and so the published one should be taken as the final version.

Something I mentioned there is a rule which wasn’t included in the final version (it is called “3. No static methods other than factory methods”). Jeff had some interesting comments and it sparked some good discussion between my pair (Steph) and I and so I think its worth adding the result here.

As I indicated, I had been thinking a bit about statics recently and been trying to pin down what I think about them. I was thinking along the lines of “Don’t use statics when you really want an instance” (see below). Jeff made the observation that actually they use statics quite a bit under certain circumstances.

With Jeffs kind permission, I will try to summarise our discussion.

Methods with no side effects

we use static methods extensively. whenever we can have a method that doesn’t have any side effects, we mark it as static so that the ide can alert us to the fact that it is so.

I realised that this is something I also like, if we’ve just written a method and it has no interaction with the state of the object, making it static is a clear indicator at the compiler level that the method has no side effects. I would tend to just do this without even thinking about it, so it was interesting to call it out.

Guard conditions / Encapsulation

bombUnless(isTrue, "the thing was supposed to be false!");

Here, there is a piece of logic which belongs to this class, but doesn’t involve the state of the instance. Steph and I discussed this also.

String params = url.params();
if (params == null || params.trim().equals("")) children.add(sentinal);

Becomes :

if (isEmpty(params)) children.add(sentinal);

I had hinted at this in the previous post, in terms of it being a common pattern. One place it is frequent is in the area of testing and mocking, for example Mockito or JUnit both make extensive use of statics which makes the code easier to read.

Jeff had this to say:

These kinds of minor improvements to code, getting rid of micro-duplication, have given me some of the best gains in my practice. Without static methods and static imports to help reduce the client’s overhead for the method call, it’s hard to make certain kind of improvements worthwhile.

Don’t use statics where you can have an instance

This was my original understanding of the rule “only use statics for factories”. I had been thinking that the intent of the rule was this, so for example:

public void talkToTheService() {
    Result result = SomeService.doSomethingForMe(myArgs);
}

instead of :

private SomeService someServiceInstance = new SomeService();

public void talkToTheService() {
    Result result = someServiceInstance.doSomethingForMe(myArgs);
}

Summary

I’m sure there is more to say on the subject, but I think some of these points are useful. As a general point, Jeff concluded our discussion with:

Static methods should be reserved for things that either touch multiple objects and have no identity beyond the functional cohesion (make it a static method to give the related steps a name) or things that represent generic operations on fundamental types (such as the isEmpty example).

Thanks Jeff!

Share

“Object Calisthenics” : Jeff Bay

I happened to notice the book “The ThoughtWorks Anthology” lying around the office. It contains quite a few interesting articles. One in particular resonated with me.

In Chapter 6, Jeff Bay talks about a set of simple rules for writing OO code, which he suggests you try applying rigorously on a small project (say 1000 lines of code). The article can be downloaded here.

This is a hard exercise, especially because many of these rules are not universally applicable. The fact is, sometimes classes are a little more than 50 lines. But there’s great value in thinking about what would have to happen to move those responsibilities into real, first-class-objects of their own. It’s developing this type of thinking that’s the real value of the exercise. So stretch the limits of what you imagine is possible, and see whether you start thinking about your code in a new way.

What I liked about this article is that it cut to the core of something which I have been working at explaining over the last few months. I sometimes feel like a “purist” when discussing OO design. It is a common situation to find myself defending writing a small class, or encapsulating a String to make a small value object which only has a single attribute. Jeff explains in a great way a few principles and challenges the reader to try them out in a rigorous way, just to see how it works out. This is a great way to present it, its not saying “I know the right way and you must follow the rules”, its suggesting that you should give it a chance and you might begin to see some rewards, or “Try it, you might like it”.

I also liked the fact that eight out of the ten rules were all about encapsulation something I have also been thinking a good deal about recently, prompted by this experience, even to the extent of getting it printed on a t-shirt (but that’s another story).

NOTE:
Since writing this post, I have had a discussion with Jeff via email, the results of which can be found here, this paragraph is superseded.

Another one which isnt actually in the book, but that I have been getting into recently is “No static methods except as factories”, This one is particularly hard to follow when so many libraries use them and its just so convenient:)

He’s not suggesting that these rules are always applicable but I think its interesting to make the effort of taking it to an extreme and see where it leads you, it may open new possibilities when going back to everyday coding.

Share

Restling with Restlet

We have been using restlet (Version 1.1.3) as the web framework on our current project and I thought It might be useful to share our experiences.

Initially we chose it because it seemed a good match to what we wanted to achieve. We wanted to write a pure http interface to our application. Restlet is all about routing http requests to “resources” it maintains the semantics of restful applications and so you have put, post, get, delete methods and resources and representations of these resources. All very restful and good.

It was pretty fast to get going. We knew we were going to use DI in our app and so wanted to configure restlet in that way. Sure enough, there is a spring front controller out of the box.

It also had out-of-the box support for Freemarker. Having used velocity extensively, we had heard good things about freemarker and this seemed a good enough choice as a templating library although we were originally keen to use string template (but that’s another post!).

So we were up and running quite quickly. However there were a few “features” which have made life less than rosy for us. I am going to just briefly list them here. To be fair some of these are due to the Spring integration, which could be avoided.

Inheritance based:

In order to be part of the framework, you have to extend the restlet class “Resource”. This results in several of the issues below.

Verbose spring configuration

Because restlet needs to intantiate new “resources” from spring, it needs to do some of its own injection with things like the response and request (due to the inheritance feature). So you can’t just declare your resource bean in the spring config, you have to wrap it in a class called “SpringFinder”. It ust means that your spring config looks a bit verbose and noisy.

Matching URI patterns:

Restlet has rather a complex URI pattern matcing algorithm. Im sure this has some use somewhere, but involves some kind of weighting strategy (well actually a choice of several). This in itself is not too bad, but to do the simplest thing is not the first configuration. It took a bit of digging about to find out that in order to just exactly match the URI you map in the config, you have to Override the method getMatchingStrategy and return a value.

A suggestion might be to have the routing algorithm encapsulated as a Strategy object. That way, it could come with a default strategy which is just exact matching, and then if you need the more complex algorithm it would be easy to swap in.

We first noticed this when we mapped a uri something like /contextroot/someentitylist/22 if you try /contextroot/someentitylist/22/foobar you dont get a 404, it just goes to your resource.

Complex api

Sometimes things seem a little tricky to do. For example, to get the Http headers from the request, you have to get a Form object which is a bit strange, its like it was re-used just because it sort of looked like a web form, instead of just having a specialised object to represent the headers. I guess that sometimes it seems a little too generic which means you need to do some interpretation of the object model to get what you want.

Noisy logging

We wanted to implement the Cache-Control and Pragma headers. It lets us do it but complains noisily in the log output, on the error stream telling us that we shouldnt do this, because It will be implemented in a future version!!. It logs this at SEVERE level!. This is rather patronising and now fills the log file with noise.

Inheritance based (again)

In order to inform the framework that you allow puts and posts, you have to override the methods allowPut() and allowPost()

All of which led us to create a single derivation of their class and then delegate to new classes of our own devising thus breaking the inheritance tree, or “running away from home”.

Thread Local Storage

While im not necessarily saying TLStorage is a bad thing per se, you do need to be careful in a web app that anything you put on it, you remove at the end of each request processing, because otherwise it just stays there and builds up in the vm. Felix and Martin were looking into some memory leak stuff in our web app and discovered this interesting fact. It was easily fixed by just setting the instances to null at end of request. Maybe we were using the framework incorrectly and so had not called the appropriate sequence, but even so, something so important should be impossible for us to get wrong. I think they used Your Kit for the job which they were pleased with as it pointed them directly at the classes in question.

General vibe

Basically, it feels most of the time that you are being made to jump through hoops to integrate with the framework. I feel that frameworks should be transparent and non-invasive.

What do you think ?

Do you have any experience with Restlet ? Maybe we are just not using it in the right way. I do notice that we are using the stable version so I haven’t looked at what is upcoming.

Share

Deliver or die!

I started writing this post a few weeks ago and since then been in several conversations around the same area, so thought I’d get on an finish it:)

What is the key focus of agile practices ?

To me, it is Delivery of working software.

What do we mean by “delivery” ?

Delivery is software working in production. Even stronger, software that is being used in production.

What does “working” mean ?

This may depend on the currency you have for measuring success. Usually it means improving the bottom line of the company. It might be indirect such as generating interest for a website or simply getting a product delivered at all.

My definition of “Lean” may not be entirely accurate (I’m not an expert) but from my understanding, taking a lean approach, writing the code is only part of the story.

Lean tells us that there is no point in having a backlog of artifacts in the factory if we can’t get them to the customer. We need a good distribution system so that artifacts are pulled down the pipeline as quickly as possible, right from where they are consumed.

For software this means the production environment. Really the production environment, not staging or the ci environment or a dev box.

Setting up the distribution pipeline is as important as any other part of the project. It needs to be automated, reliable and responsive (i.e. as soon as a new feature is required it can be sucked into production as soon as its completed)

Once your delivery pipeline is in place everything else becomes smooth. People stop worrying that they are not going to receive new features quickly and so they feel more able to focus on what the need right now, in smaller chunks which means the delivery system flows more smoothly and the features are produced in a more responsive way.

Share