As someone who tends towards overdoing it, I have found the Cool Running couch-to-5k plan exceedingly helpful and would recommend it to anyone who’s feeling the urge to get off the settee and hit the tarmac. My usual running sprints (hah) tend to end up with me slogging to hit an impossible target followed by nearly a week of silly walks as my muscles unstiffen. So far I’ve had no post-training side effects, and every session leaves me hankering to get out there and do the next one. This is an addiction I could get used to.
Category Archives: Uncategorized
Er, priorities?
Seems a bit messed up when Scoble leaving Microsoft rates a mention in the UK breakfast news headlines, right next to a slot describing the concern about the state of the US economy. ‘One of the world’s most famous bloggers’? For a definition of ‘world’ that only includes software geeks perhaps.
A word to the wise
Those who do not pay attention to politics shall be at the mercy of those who do.
Phew
The fallout from having to cancel all my credit cards continues. Huge thanks to my hosting provider, JohnCompanies for not deleting my account after an unfortunate confluence of events involving them not being able to bill me for 2 months, and me not checking the email account that they were trying to contact me on. It might take a while for DNS to propagate, but the site is more or less back.
I’ll tell you what I want
What I really really want…
I’d love to see EAR files made more useful by allowing them to be run from the command line. ‘java -ear MyApplication.ear -cp library1.ear;library2.ear’. Even more useful would be to make the default classloader understand EAR files as complete units of deployment, and allow different versions of the same jars to exist within different ear files. Borrowing from J2EE, it should be possible to have a classloader to look inside the local EAR when trying to load a class, and then look in the rest of the classpath. So if MyApplication.ear contains version 1.0.4 of commons-logging.jar and library1.ear contains version 1.0.2, any classes within MyApplication.ear would see 1.0.4, and those in library1.ear would see 1.0.2.
This does mean that if MyApplication was interacting with a class in library1, and tried to reference an instance of a class that was defined in both ear files, a ClassCastException would result, but in my opinion that is not particularly a limitation. If I need to use an API from a library, I should not be concerned with the libraries (or versions thereof) that it chooses to use internally. The present jar based paradigm simply does not allow me that encapsulation.
On setters, constructors and modelling reality
In my experience there are almost no situations where a setter method is a good idea. The wholesale replacement of a piece of an object’s internal state at arbitrary times leads to a class of interaction defects that are horribly difficult to track down. Most of the time solving them involves hooking up the debugger and stepping through going, ‘its fine here. Its fine here. Its still fine here. Its not fine here. Who called setName with an invalid value?’ and then debugging the call history of the method that made the bad call. Or alternatively, knowing that you have to call something like ‘accountService.updateBalance(account)’ before you can say ‘account.getBalance()’ or you’ll get a null back.
A class with all fields marked as final and initialized through its constructor is robust and easier to use than one with setter methods. You know that any time you have a reference to an instance of it, it’s ready to use and you can call methods without worrying about random fields not being set.
Note that just because all the fields are final and there are no setters, this doesn’t mean that the object is immutable. It just means that its behaviour more closely models reality, and your interactions with it will be far more meaningful. account.credit(amount) and account.debit(amount) instead of account.setBalance(amount). The balance is the sum of all the credits and debits, not something anyone can arbitrarily change (although I’d love it if I could just call my bank and say ‘please set my account balance to 1 million pounds’).
Which brings me on to my next point. I often see setters used where information relating to an object is not known at construction time, and needs to be added later. This is usually a symptom of choosing the wrong class to store that data. To continue the bank account example, a bank account (at least here in the UK) has certain properties. It has a sortcode and an account number, and probably an account name. These properties are pretty much fixed for the life of the account. (Sometimes they do change, but that is often dealt with as an account closure and opening of a new account with the funds transferred). There are certain things that an account does not have, which may surprise you.
A bank account does not have a balance. Not in the same way it has an account number. What an account does have is a series of credits and debits over time. When I call up my bank and ask for my account balance, what I’m really asking for is ‘the balance as of right now’. The snapshot of money in and money out since the account was opened that adds up to what is in it today.
Now lets say we want to encapsulate the concept of a balance instead of having to calculate the value from the list of credits and debits. I need the account it relates to, the point in time I’m interested in and, of course, the balance of the account at that time. A Balance class might therefore be constructed as ‘new Balance(Account account, Date asOf, Money amount)’. Those 3 pieces of information combined are immutable. They will never change. No matter how often I check my balance from the 10th of April it will always have the same value.
Thus its fine for a Balance to have an Account (and in fact completely meaningless for a Balance not to have an Account), but an Account does not have a Balance. Getting this kind of relationship right is at the heart of OO design.
A bad citizen in Javaland
You are born with no body parts. One by one, your organs are pushed into you. Should anyone attempt to interact with you before your organs have finished arriving you will die. Luckily this doesn’t happen. Once all your organs are settled you are ready to start a job (life moves fast in Javaland). You ask the universe for the abstract concept of vehicular transportation. The universe gives you a car. You look at the car and tell yourself it’s a motorcycle. You try to climb on the roof and are thrown off. Catching your error you land back on your feet. Finally you try telling yourself the car is a car and that seems to work. You open the bonnet and take out the engine. You reach into the engine and take out the starter motor. You turn the starter motor until the engine starts. You take the steering wheel and pedals out of the car and use them to drive yourself to work.
During the day you need to borrow some money from a colleague. You pick up your colleague, reach into their trousers and pull out their wallet. You open the wallet and pull out some cash. You keep their wallet in case you need more money later. They also keep their wallet, remaining unaware that you have taken out some money and that their wallet is now in two places at the same time. Later, you both attempt to spend the same money twice. The universe explodes and is restarted. An identical copy of you lives your life again. Subtle changes to the fabric of reality prevent the universe from exploding this time. Your day continues.
You leave work with your friends. One by one they forget who you are and leave. You are alone. A man wearing a refuse disposal engineer’s uniform appears from nowhere and assassinates you, placing your body into a recycling bin. Your organs are donated to the next generation. You die. The end.
Enough bad software
I’m sick of it. Enough with the shoddy software. Today I shall be reporting my experiences evaluating Panda Software’s Titanium anti-virus:
Installation crapped out, ‘Pure virtual function call’ error. Made my machine reboot twice, then immediately proclaimed that the evaluation had expired, about 30 seconds after I’d installed it for the first time. Unacceptable.
While I’m on the subject, Norton AntiVirus 2006 should also be avoided like the plague. A friend of mine purchased it, and it proceeded to completely hose his system. The machine would take over 2 minutes longer to boot than before. Excel wouldn’t even start. It took me (someone considered to know a little about computers) nearly an hour to uninstall it. It finally took two safe mode reboots, shutting down (and disabling) half the windows services and two attempts at running the uninstaller to remove that little piece of scumware.
What’s in your wallet?
Yesterday my wallet was stolen during a ThoughtWorks away day, thus marring an otherwise excellent day. I’m filled with impotent rage, but also racking my brains trying to remember what was in my wallet. Which little used credit cards might I have forgotten from my slew of late night card cancelling phone calls?
Do you know exactly what’s in your wallet right now? One thing’s for sure, when the white hot fury cools enough for me to start acting rationally again, I’m buying much smaller wallet that will force me to only keep a couple of cards in it.
Inversion of Control for teams
On the majority of software teams a hierarchy exists. There’s a pyramid of developers, senior developers, tech. leads, architects, project managers etc. The architects design the system and tell the tech. leads what to do, and the tech leads go to their teams and tell them what to do. The most experienced people are at the top of the pyramid (ie. furthest from the coal face), and there is a natural progression down until you get to where the code is being cut by the most junior members of the team. Hmm.
A self-directing, agile, emergent team doesn’t fit this model. When roles are fluid, and more like hats than job titles, a more service-oriented organisational style tends to emerge. The pyramid becomes partially inverted. In a well integrated and happy agile team the developers become the customers of the architects and tech. leads. As issues or design difficulties emerge, the developers seek out the guidance of the tech. leads and architects. The senior technical team members continue to remain responsible for the overall design themes and patterns within the system, but in a more event-driven, iterative way instead of an up-front, top-down imposition of designs that may not fit the reality the developers are working with.
You must be logged in to post a comment.