Friday, January 30, 2009

Waiting for the clashes

Next weekend the RBS Six Nations will begin with England hosting Italy in Twickenham, Ireland hosting France in Croke Park and the Grand Slam Winner Wales visiting Scotland in Murrayfield. Starting to feel the excitement...

Singletons?

...any global data is guilty until proven innocent
(Martin Fowler)

If you want to be a good software designer, don't optimize code prematurely. [...] If you use the Singleton pattern out of habit, because it "makes your code more efficient", you're prematurely optimizing. You suffer from Singletonitis
(Joshua Kerievsky)

I'm not afraid of a few globals. They provide the global context that everyone must understand. There shouldn't be many though. Too many would scare me.
(Ward Cunningham)

The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object.
(Kent Beck)

I mean, it looks like we're not lacking literature on the subject, are we? I wonder why so many people are just too busy with their Singletonitis to consult it (Kent Beck gave a hint on this).

Tangled and circular dependencies

Back to the cyclical dependencies problem I wrote about one year ago, the other day I finally tackled it (15 years spent playing rugby must have taught me something), as it was left hanging in the air for too long. We started out like this:

Basically project B uses the domain model and persistence services from project A, which in turns uses transport services and a the domain model from project B (no, it is not the same as above, because the model B is just based on model A but it is managed from a different perspective). Let's not forget to say that presentation, model and services are all tangled.

A disclaimer: this is not what I'd call a refactor, just a different way of organizing projects thanks to NetBeans features (no Maven complexities, thank you).

I first extracted the core domain classes of project A used in project B and moved them to a new project, let's call it A Core, then had both project A and B depending on this one. Sounds easy, but it wasn't... it was quite long and tiring, and it required a little tweaking each now and then, just like the subsequent passages. That lead me here:


Now that could look good, but even if it is better it was not enough because of some legacy installations in which Project A must be compiled using JDK 1.4 and run on a Tomcat 4, but project B has a JDK 1.5 source level (Tiger, or whatever it is called now) and runs on a Tomcat 6. This forced me to extract from Project B all classes on which Project A depended to move them on a new project, let's call it B core. Nip and tuck, here and there, to land that prince with the perfect hair, and here we are:


Now all cyclical dependencies are gone. Packages with the very same name exist in different projects, leading to a namespace which "doesn't talk" to the developer; on the other hand this can bring a lot of confusion, even if the compiler understands everything perfectly. That's where fun begins... I just began scraping the surface, now we have to dig in deep. The first step will be choosing the right names for packages, so to convey the rationale behind their repositioning. The next one will be moving related classes left untouched by the dependencies game but logically belonging to one of the "core" projects. Other steps are still up in the air...

Moral: always clean up your mess. BTW, it does not matter if you just inherited it. Now it is yours, and it is you the one who has to deal with it. Leave spaghetti to gravy and keep them out of your code. There must be a reason if they say "clean code that works" and not just "code that works"...

Wednesday, January 28, 2009

Coaching your team

I stumbled upon this survey on Marsha's site and found it quite interesting as it was an occasion to stop and think how I'm doing.

The results tell me "You were meant to be a coach". That's nice, but it is just a start. The survey actually focuses on ideal characteristics of a good coach, but to really get to the point you have to ask yourself how you fit in. You have to walk the walk, not just talk the talk. So, do I always behave the way I should?

All I can say in all honesty is that I love coaching. But it is looking at how other people improve that you can say whether you're effective or not. So, if you want to improve, you have to help other people to improve themselves. Tricky, isn't it?

Tuesday, January 27, 2009

Motivating people

Peopleware is a great book. It says a fundamental thing: people are the cornerpiece of every company. That's good, as it is very important to recognize it, but it is always somehow bad, as dealing with people is one of the most difficult task we have to face. Yet, we face it each and every day.

Every now and then you have to clear the air a little, and this can be painful, but collaboration between people is one of the key factors to success.

As dealing with people is difficult, you have to motivate everyone, choosing the right stimulus for each of your collaborators. And, being your collaborators people, that is damn hard. It is always nice when your professionality is acknowledged, but that can be not enough. Someone wants to feel they are in charge. Someone wants more training. Someone wants a private office with plants. Someone wants a younger secretary. Someone wants an armchair lined with human flesh or a fish tank full with swimming accountants.

Most people think of money as the ultimate resource, but if you think it will suffice... well it won't. Besides, Choosing a job only on money is often a bad choice, as many other factors have a great influence.

That said, no one would be unhappy if they were given a raise.

I surely wouldn't.

Friday, January 23, 2009

The birthday greetings kata

On February the 14th the milano-xpug organized a kata whose subject was proposed by Matteo on his blog to introduce the exagonal architecture.

Unluckily I couldn't attend the meeting in the flesh, so I just decided to try the kata out here on my own. I first started from scratch, thinking it would prove more fun; then, as I was taking quite a different approach - you could also say that a whole different design was emerging - I decided to get back and start from the original code provided and refactor it to try and focus on the architectural issues which were the aim of the exercise.

Even if I think this exercise to be quite simple, I decided to post a trace anyway because someone might still find it useful. You can never say!

The heart of the application is the BirthdayService class, whose responsibilities consist in identifying employees whose birthday falls on a given date and sending them a greeting message.

This is the public method, called by the acceptance test:


I know it looks odd, but I've had enough of escaping characters and trying to format code to make it look nice, so I hope you will forgive me.

Anyway, the sendGreetings method parses an input file, creates employees, checks if they are eligible for a greeting message and delegate the actual sending of the message to a private method:


Seems a great bunch of things for a single class... let's try to sort it out. First I decoupled the service from the file with the employees' names introducing the interface EmployeeRepository, with the method getEmployees, then I wrote a FileSystemEmployeeRepository that implemented it. The repository was then injected into the BirthdayService via constructor by
the acceptance test. At this point the code looked like this:
...
List<Employee> employees = repository.getEmployees();
for (Employee employee : employees) {
if (employee.isBirthday) {
//compose message and call method that sends it
}
}
...
Still I thought that the check on the date of birth could be done by the repository itself, so I changed the interface adding the new findEmployeesBornOn(OurDate) method and changed the code so that it looked like this:
...
List<Employee> employees =
repository.findEmployeesBornOn(ourDate);
for (Employee employee : employees) {
//compose message and call method that sends it
}
...
Maybe not a very big change but I think it was worth it, as now the code is cleaner. Then there was the messaging part. First of all I decided to introduce a new BirthdayGreeting class, that produces a message body, a fixed subject and a recipient starting from an employee; at this point I extracted the interface SimpleMessage that exposes these three strings. The code had become
...
if (employee.isBirthday) {
SimpleMessage greeting = new BirthdayGreeting(employee);
sendMessage(smptHost, smptPort, "sender@here.com", greeting);
}
...
Still I had to resolve the dependency from the SMTP, so just like I did for the repository I introduced the MessagingService interface with the sendMessage(String sender, SimpleMessage message) method and injected it into the BirthdayService via constructor from the acceptance test. Some nip and tuck to move the body of the sendMessage method from BirthdayService into a new EmailService, implementer of MessagingService, and voila, the new BirthdayService code:
public void sendGreetings(int month, int day) {
List<Employee> employees =
repository.findEmployeesBornOn(month, day);
for (Employee employee : employees) {
BirthdayGreeting greeting = new BirthdayGreeting(employee);
messagingService.sendMessage("sender@here.com", greeting);
}
}
I also changed the method parameter from OurDate to month, day. Now we have a simple and decoupled service that can focus on its true responsibilities: ask for all people who should receive a greeting, create a new message and delegate its sending.

One might wonder whether the sender belongs where I put it, or if the service should directly instantiate a BirthdayGreeting with a new rather than getting it in some other way. But maybe that's going too far.

BTW I also decided not to use the Employee.isBirthday() method and I created a value object called IsBirthday, created with two parameters representing month and day, with the boolean method forEmployee(Employee). The code in the repository now looks like this:
public List findEmployeesBornOn(int month, int day) {
List<Employee> list = new ArrayList<Employee>();
IsBirthday isBirthday = new IsBirthday(month, day);

for (Employee employee : employees) {
if (isBirthday.forEmployee(employee)) {
list.add(employee);
}
}
return Collections.unmodifiableList(list);
}
That's all folks... maybe I'll manage to post the complete code here, where you can find some other (and more accredited) solutions produced by people who actually were there.

Friday, January 16, 2009

Star Wars retold by someone who has not seen it

Continuing the Star Wars series, here's a simple animation that pictures the original trilogy as told by someone who has not actually seen it save for some pieces in open order.



One of the things that made me laugh the most was Amanda spelling "HanS solo" in a very German way... priceless!

The original post is to be found here: Star Wars: Retold (by someone who hasn't seen it) from Joe Nicolosi on Vimeo.

Tuesday, January 13, 2009

Suggestions in NetBeans

NetBeans 6.5, just like some earlier versions, has a nice feature that points out low level suggestions, tips or hints, showing a differently colored bulb on the left of your code, just before the line numbers (if you use them), e.g. if you override a method in a subclass the IDE suggests to add the @Override Annotation, or if you invoke a method that could throw an exception the IDE provides you with the choice to declare that it throws the exception or to surround the statement (or the whole block) with a try/catch block.

Until this afternoon I clicked the bulb and selected the appropriate choice, each and every time blaming the disconnect/reconnect pattern between keyboard and hands that everyone hates so much. I won't say mice are for losers, but once you're using the keyboard you should stick to it. Ever heard of how context switching makes you lose time? It holds true for your hands as well.

Then I was feeling something was in the air, and I had a revelation. Why didn't I seek the NetBeans shortcut card (Help - Keyboard Shortcuts Card)? And so I did, and even if the search was fruitless it laid the seed: my answer was peacefully waiting for me in the complete keyboard shortcuts specification.

Now, a happier and wiser man, whenever I spot that bulb I just hit

ALT + Enter

and there you have it... Isn't it wonderful? Now I'm going to glance over the list and find out more (not so) hidden treasures... oh by the way try to expand the newo template :-)

Monday, January 12, 2009

FTP in Java

This one is a reminder as well; the example is not complete but I'm sure that it will be enough to get to the point.

FTP is not directly supported in Java, rather it is disguised behind a URLConnection. Once you've opened the connection you just access the appropriate stream and normally use it:

URL url = new URL("ftp://username:password@your.host/complete/path/to/remote/file");
URLConnection connection = url.openConnection();

To "get" a file you use the input stream:

InputStream is = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(is);

then you create a writer...

FileWriter writer = new FileWriter(new File("complete/path/to/local/file"));

and flush what you read:

int tmp;
while ((tmp = reader.read()) != -1) {
writer.write(tmp);
}

aren't we forgetting anything? oh yes, clean up the room:

reader.close();
writer.close();

The dual "put" operation requires an output stream:

OutputStream os = connection.getOutputStream();

and the core of the transfer loop would simply be

os.write(tmp);

Ok, the read-and-flush code is quite ugly, one would problably wrap the reader in a BufferedReader, append and flush instead of directly writing and stuff, but for version 0.1 it will suffice.

For most advanced needs it is always possible to use the Commons Net.

FTP on IIS

Just a reminder for my colleagues, no detailed stuff, so if a bunch of crackers enters your site I will not consider myself responsible :-)

To configure FTP access on a Windows host (assuming a default FTP server is already up and running):
  • Create an "FTPUsers" group, or something similar; this will contain all users that will access your preciousss files and folders (hiss as Gollum when you read this)
  • Decide which folder on your hard drive will contain the files... and, please, do not use the default one :-) This will be your ftp root. Give the FTPUsers group read permissions.
  • Create a user, remove it from the default "Users" group for added security and add it to the FTPUsers group.
  • Create a new folder in your ftp root; this will be the default folder for your freshly created user.
  • Give that user the appropriate NTFS read/write permissions on the folder
  • Create a new virtual directory in IIS pointing it to the folder you just created, naming it after your user; in the FTP Properties / Security Accounts tab disable the "Allow Anonymous Connections" checkbox.
  • Finally, test the connection... No TDD on this :-)
This reminds me of when I was younger, so much younger than today... at least at the time this was in my job description :-P

Monday, January 5, 2009

A new Sun Certified Specialist for Netbeans IDE

Last Saturday I received the examination score report for the exam I sat for a couple of months ago and... I passed, so now I'm entitled to (trumpets and fanfare) proclaim myself a Sun(TM) Certified Specialist for NetBeans(TM) IDE. My congrats to Stephen Chamberlain who adds this cert to his SCJP.