Archive for June 2006
Nothing big has been going on today, although a few little things of interesting note.
Recently I’ve taken a strong interest in testing techniques and improvements, especially in the area of slow tests, as well as what can be done to improve our test coverage as well as make tests more automated and less dependant on external resources. Anyhow, there’s a couple interesting tools I came across this evening:
I was a little bored this evening, and couldn’t get my self to concentrate at all in my attempts to get some reading done (between Domain Driven Design, my SCJP study guide, or Atlas Shrugged), so in an attempt to pass time I decided to install linux on my laptop… again.
I’ve had quite a few different versions of linux installed on this laptop, from Mandrake, Debian, Ubuntu, Red Hat, and even Gentoo (which sadly took me eons to get a working system in place). With most of these I usually spent a good week setting things up, and always ran into a few small problems. With the exception of Debian, I was unable to configure power management correctly, leading to heating issues. I never could get wireless to work. And my graphics acceleration was always subpar.
SO, with recent disatisfaction with windows on this laptop (it’s ran mysteriously slow and, for reasons unknown to me, my laptop has suffered from heating issues again) I decided to go ahead and put a unixy system back on it to satisfy the geek in me. I wanted to install FreeBSD, but feared it may be like installing gentoo from scratch again. I thought I’d try a different distro, and decided to give Mepis a try.
I must say, I was THROUGHLY impressed. It detected and configured everything correctly, from my sound, graphics card (which all other distros required me to download a seperate intel 845 driver just to use the full screen), power management, and, amazingly, my wireless card was detected and worked without a hitch! Within an hour from putting the disc in I had a complete working system that works perfectly, with the exception of the horribly looking fonts under fluxbox (I’ve fixed it by installing a few pacages, but initially it was quite ugly).
Overall, it’s nice to have linux on my system again … I’ve missed it these past six months.
This afternoon I decided to try out the Blackjack TDD exercise again in php, and decided to go ahead and write a quick and simplistic interface to it, and put it up on my website to play around with. It was a fun waste of two hours, but what I’m happy about is that I have something to play with, although it’s broken in some ways. You can’t split. You can refresh the page and hit even after the game has completed. But the basics do work.
It’s actually been a fun little project… I’m thinking of spending the afternoon tomorrow extracting some rules out of it (and creating some) and implementing a rule processor to alow games with different rule sets (i.e. dealer must hit on soft 17, spanish 21 rules, etc). I’ll probably also implement a betting system and the capability to split hands and double down. Adding the capability for multiple players might be a fun addition to add in the near future as well.
Anyhow, for those who are interested, you can play with it here.
Wow. Every now and then when you think you know everything something just pops up and suprises you. I’ve recently been studying to take the Sun Certified Programmer certification exam and, even though I thought I knew enough to just go in and take the exam, I decided to go ahead and spend 25 bucks and buy a study guide off of amazon.
Although at first it was a light read, and I find myself skimming sections, I keep coming across interesting and useful features of the language I was unaware of, and sometimes even find myself kicking myself when I realize I came up with half assed solutions that the Java API already solves.
The most interesting features I came across so far were the Comparable and Comparator interfaces. Sure they’re simple, and braindead obvious to use, but I never knew of them before, but I’m glad I do now.
Sometimes when I work on completing stories for an iteration, I get a little sidetracked designing my object model a little too well that I actually impose a lot of work. For example, as I recently tried a TDD exercise using blackjack, I got a little too carried away with designing a Deck object, a shuffler, dealer and player objects, and a table object that players and dealers could fire and recieve events from (i.e. when a player hits, it fires a hit event to the table, which is routed to the dealer, causing the dealer to draw a card for that player if it was their turn). Finally, I even plugged in a rule processor for the table, allowing tables with different rules such as “Dealer does not hit on soft 17″ and “Dealer Must Hit on Soft 17″.
As you can imagine, this took quite awhile to implement before there was a playable demo, an entire rainy Saturday to be exact. A far cry from my goal of completing a TDD exercise in less than 2 hours. Which made me realize something. By keeping things dead simple, perhaps creating a game object with hit, stay, deal, and finish operation, it was doable to create a playable blackjack demo in less than 2 hours, perhaps even less than an hour … it’s not pretty, but there has been Verifiable Business Value delivered.
Which is what is important when working on an iteration … doing the simplest thing that works while providing business value. You provide the verifiable business value first, then refactor to mae the object model more flexible and decoupled. The primary aim is to have something at the end of the iteration that you can show to your end users and even let them play around with while awaitng the next release (or, if you truely are agile, allow them to verify that the business value for this iteration has been met).
Just remember that you can always refactor.
Cory Foy recently blogged about how little developing software has to do with technical skills, and how much more it has to do with dealing with people… and he couldn’t be more on the point! Good software is never developed in a void, it is instead a process of collaborating with other developers, end users, and people familiar with the domain logic that is represented in an application.
A developer today is not some anti-social person who only speaks in binary, locked away in some cubical or back room hiding from the sunlight writing code madly without meeting the end users. The truth is quite different. Today, a developer is required to be a social as possible and is required to be able to level with end users and domain experts. As Eric Evans illustrates quite amusingly in his book Domain Driven Design, not using domain language during discussions with users results in much confusion:
User:So when we change the customer’s clearance pint, we need to redo the whole routing plan.
Developer:Right. We’ll delete all the rows from the shipping table with that cargo id, then we’ll pass the origin, destination, and new customs clearance point into the Routing Service, and it will repopulate the table. We’ll have to have a Boolean in the Cargo so we’ll know there is data in the shipment table.
User:Delete the rows? Ok. Whatever.
Domain Driven Design, Tackling Complexity in the Heart of Software – Eric Evans, pp.28 – 29
The most important part of a developer’s job today is to understand the domain of the application they are building, and the ability to create software that represents that domain. But it takes much more than understanding the domain, it takes understanding the domain from the context of the end user. Even if you model the domain of your application to perfectly reflect the real world, it may hold true that all the end user needed was a small subset of it, or it needed to be done from their point of view, not how it exactly is in the real world.
A developer is also required to be quick on their feet, and to be very agile. You have to meet ever changing requirements, and you must be adaptable enough to change anything to meet those requirements. To quote Thomas L. Friedman from The World is Flat, a Brief History of the 21st Century,
“As the playing field is leveled, and the world becomes flatter, you better become flat, or you’re going to get flattened.”
Recently I stumbled upon SÃ©bastien Gruhier’s excellent Prototype Window Class for javascipt and I must say… it’s quite impressive. I’ve created draggable windows in the past, but it is quite a bit of work and SÃ©bastien’s class is a welcomed addition to those of us who like to create richer web UIs in our free time (like me!).
This evening I was browsing some of the recent posts on the amsuing thedailywtf.com and was amused by a post that detailed a certain programmer’s predecessor’s trials and tribulations trying to fulfill the requirement to”programmatically send an email in .NET” and the source control log that details the programmer’s frustration of trying to send an email under windows 2003 by programmatically manipulating Microsoft Outlook.
Yes. Manipulating the UI of Microsoft Outlook to send an email. From .NET.
But it doesn’t end there, the programmer has a difficult time getting around Outlook’s “anti-hijacking feature” that prompts the user to click yes if they want to let the program send the email. So he goes back and forth to the drawing board, struggles with a custom coded attempt to trick Outlook, then finally reveals the solution:
2004-12-07 16:22 — Install, on the server, a newly purchased program called ClickYes that automatically clicks “Yes” to those dialogs.
After I stopped laughing, I did a little google seatch and discovered, yes, there IS a program called ClickYes! And it’s at version 2.2! I really couldn’t stop grinning, especially when I saw the hundred dollar server license fee and the fact that it also has an API hints that sadly a lot of people have used this as a “solution” to their “problem” of programmatically sending an email.
If only he had spent a second to use google.
Let’s face it… one of the most important concepts (imho at least) in test driven development (and unit testing in particular) is the use of mock objects in your tests. Why are mock objects important? Well, when we examine what a unit test is, it’s a test of a unit of the software system under test (SUT). When we’re unit testing code, we’re only interested in the behaviour of the code under test, not the collaborators and other resources that the SUT may use.
In addition to mocking out other objects in order to isolate the SUT, it’s also a good idea to mock out external resources as well. Rather than make actual database queries, one might mock the dao to return expected (and hopefully unexpected) data in order to test how the SUT utilizes it. And certainly if the system under test is responsible for sending out 3,000 email notifications, we don’t want those emails being sent out every time we run the test (especially if we run the test after each small change)!
I thought it would be an interesting exercise to show how to mock out an object in a test the manual way, by creating an object that simply subclasses and overrides the method that does the work we want to mock and using it as an inner class in our test. So to begin, I wrote up a simple DAO that is responsible for fetching an rss feed and returning an rss Channel object that contains data about that channel. So first I started with a simple test case and wound up with this end result (after taking the many small steps of course ):
One thing that has been bothering me a little as of late is the misguided dislike of UML I have observed amongst some XP users. As an example, at work the other day I was reading through Object Design: Roles, Responsibilities, and Collaborations (an excellent book by the way), one of my co-workers (who just started) asked me about it, and noticed the page I was on showed a nice sequence diagram and commented he likes interaction diagrams, but they assume that you have the rest of the system fleshed out in UML.
Of course, I noted that’s not really the case, yet when another co-worker joined our discussion, he glanced at it and instantly focused on the “UML sequence diagram” portion under the illustration and instantly replied “Oh, that uses UML. UML is generally frowned upon in XP”.
And how wrong that is! When I’m trying to convey the sequence of events in a system to someone, I find it very helpful to draw out a sequence diagram that illustrates what’s going on. And for this I don’t need the system fleshed out in a class diagram, I don’t even really need to use class names … simply referring to roles in the system can be adequate. One can convey the same information on a whiteboard without using UML, I just find it convenient to use UML because it provides a common vocabulary. Likewise, I might use a class diagram to quickly sketch out the hierarchy of a system, but omitting unimportant details (and usually a throw away sketch or whiteboard drawing).
But, back to the question… why the hatred against UML by some agile developers? I think the reason behind this is that UML is occasionally associated BDUF (Big Design Up Front), a big no no in XP. BDUF implies that you do EVERYTHING (class diagrams, sequence diagrams, entity relationships, documentation, etc) up front before writing a single line of code, and then even worse generate your code from the model you designed. The reason this is bad is because it’s a lot less agile … it almost locks out changes in requirements and when requirements do change (as they are destined to do) they become more expensive to implement. I would guess those that have experienced BDUF would have quite an aversion to it because of the results it tends to yield.
Of course, what it all boils down to is how to best communicate your ideas to others. While clear cut sequence and entity diagrams are in my opinion the best way quickly flesh something out, a majority of the time quickly scribbled words, boxes, arrows, and stick figures (which exist in UML anyway, hehehe) with someone telling a story describing what is going on can be good enough. Which is what really matters … that which is good enough to convey information correctly in a format that others can easily understand while keeping the nasty technical details to a minimum.