Archive for the ‘design’ Category

SSSs = Smart, Stupid and Super-smart

Tuesday, November 20, 2012

We need developers who are:

  • Smart in writing their code, so that it will be simple
  • Stupid in reading and understanding code, so that they won’t tolerate a mess
  • Super-smart in transforming code, so that they can take a mess and make it better

I think that the “stupid” one is the most important of them all. Please don’t try to be smart when you read code.

Corollary: also the code should be as stupid as possible, because otherwise it will be undistinguishable from magic and magic requires smart people to understand (but we need to transform in our stupid nemesis when we try to understand code).

Say “NO” to magic in your code.

Fowler’s keynotes at Agile Tour Toronto 2010 (with mind maps!)

Thursday, November 18, 2010

On October 20th I attended the AgileTour Toronto 2010 conference with a colleague. Well, calling it “conference” is a bit generous but I’m not unhappy about it. It was warm and cozy. I’ll explain more in details in some other posts.

For me, the big highlight of the day was Martin Fowler‘s keynote. Let me rephrase: Fowler gave 3 keynotes in one, which is nice because it’s not too boring and it flows smoothly.

The essence of Agile

In the first keynote Fowler wanted to clarify his view on Agile, talking about its essence. His motivation was to steer clear of a phenomenon that he calls Semantic Diffusion: when you start being successful at innovating and modulating a message, people try to copy you without deeply understanding what you’re doing, just by mimicking your work and distorting your ideas badly. There’s not a lot that we can do about it, with the exception of reminding people about the core principles at the root of what we are doing.

So he wanted to characterize Agile first of all by difference, talking about traditional plan driven methods. In a plan driven method, success is achieved when you do something according to the plan. This is not absolutely impossible per se, but it requires at the very least that the requirements are stable. The bad news is that outside of very limited and insignificant niches, there is NO such thing (and we all know it very well).

So Agile methods are characterized by adaptive planning, which means continuous planning and release early and often. These qualities together constitute an evolutionary design approach, which I’d prefer to define differently and at the software design level in terms of responsive design, but that’s fine, I can take this.

Fowler also briefly mentioned a quote from the Poppendiecks, which sounds more or less like this: being able to deal with a lot of changes in requirements is a competitive advantage. This is a fairly powerful tool in your hands, so use it wisely.

Another fundamental quality of Agile is its focus on people. We all know that after the industrial revolution the way we intend work has been shaped too much and for too long by Taylor and his stopwatch, the so-called system process. This has greatly slowed down the evolution of knowledge work and it has taken a long time and great minds like Deming and Drucker to correct these problems and show a different path. As Deming said, “A bad process would beat a good person every time”. So Agile methods are characterized by putting that good person at the core of the method and allow her/him to shine and do great things, rather than suffocating her/him with bureaucracy.

Because of this, Agile methods need to be adapted to the specificities of the people and their organization, while maintaining the other characteristics mentioned above (while this is fundamental, it is also another contributor to Semantic Diffusion, but again we can’t do much about it). So, Agile methods are characterized by self adaptivity. As Kent Beck says, “In software development, “perfect” is a verb, not an adjective”. This means that the process is never static, but it is continuously verified and improved, always striving for perfection (but of course never achieving it fully).

Mind map of first Fowler's keynote

This is the mind map that I have taken live during first Fowler's keynote

Continuous integration & delivery

In the second keynote Fowler focused on continually adding value to a system.

He started by describing an experience so common if you have developed software for a living in the previous millennium: if you have worked in an environment that doesn’t adopt continuous integration then you know that a project can be easily doomed, staying in integration mode for a very long time.

The idea is simple:

  • Individual developers work on their own code, that is they develop feature independently
  • Towards the end of the project they put everything together and of course nothing works

The metaphor is having 2 teams digging a tunnel into a mountain from 2 opposite sides and failing to meet in the middle. I actually have seen something like this happening in big construction work in Italy. It’s scary.

Even when versioning systems became popular, people tended to do feature branching more than anything else:

  • Every developer has his/her own branch, defined for the feature that he/she is developing
  • Because integration is difficult and painful integrate less often
  • Because integration happens less and less, when it actually happens is more difficult and painful

This brings to what Fowler calls big scary merges, where you merge together a lot of files, even through sophisticated tools that do that automatically for you and from a text perspective the code seems good, but what about the semantics? You need tests to tell you whether the merge was good or not. And you have a lot of red bars for a very long time, because no tool can automate a slight change in the semantics of the protocol between two classes, for example.

The amount of pain that a team gets grows exponentially with the amount of time that incurs between integrations. I mean, more pain = more time & more bugs = more costs & fewer opportunities to generate revenues.

In the Agile world, typically when something hurts you wanna do it more often. What does this mean? It means that when something is problematic, we want to make it simpler, less expensive, so rather than hiding our head in the sand and try to procrastinate the pain as much as possible, we prefer to tackle it right away and make it better before it’s too late.

So, we want to do continuous integration many times a day, which is exactly what happens at my main gig (my beautiful day job) and in many other companies. I’d say that continuous integration has become more or less mainstream these days, which is good. For example, yesterday we have integrated our code something like 30 times. Integrating means compiling, building all the artifacts, running various kind of checks and thousands of tests. All this is entirely automated.

A bad consequence of feature branching, by the way, is that it encourages avoiding code/design improvement (because it’s painful). So the code quietly rots, day after day, to the point where it becomes a big steaming pile of PUT HERE YOUR FAVOURITE EXPRESSION. Been there, done that, never want to do it anymore in my life.

En passant, Fowler recommended Paul Duvall book on continuous integration.

Towards the end of this part Fowler spoke about continuous delivery, which is a big topic. For the non technical people out there the basic idea is to stretch continuous integration into the actual deployment. How can you do that? By building a pipeline of machines where:

  • The code is automatically compiled and unit tested => this should take less than 10′
  • Artifacts are generated into a repository
  • Artifacts are taken and deployed in a different environment where all functional/acceptance tests are executed in a timeframe that can be measured in hours for complicated systems
  • The next stage is typically the one where performance tests are executed to ensure that the system is still executing in an acceptable way and again it can take hours, even more than the previous stage
  • If everything is fine the code can be automatically deployed in production in a controlled way, where you do smoke tests to see that nothing is horribly broken

Fowler emphasized that while the last step can be typically controlled manually, and it may vary a lot from org to org (eg: you can’t do it automatically if you have to ask for permission to a committee in a bureaucratic organization), the infrastructure should be in place to do it automatically, with a simple click of a button. As Fowler said: “There should be no technical reasons impeding an automated deployment, while it’s perfectly reasonable that there are business reasons to batch many commits in a single deployment controlled manually”.

Of course Fowler recommended Jez Humble book.

Mind map of second Fowler's keynote

This is the mind map that I have taken live during second Fowler's keynote

Continuous delivery pipeline

A sketch of continuous delivery pipeline depicted by Fowler

Effort, quality and feature development

This third part can be summarized with the following quote: We need to put less effort on quality to put more effort on feature development

At a first glance, this seems sacrilegious, but if you think about it, it doesn’t talk about results, it talks about effort. Hence, it’s actually good to achieve high quality without putting into it much effort, so that we can concentrate on devoting this effort to more labour intensive feature development. Or anyway let’s put effort where our labour is more likely to pay us back directly.

Fowler started by mocking Uncle Bob and his preaching attitude towards quality. It was actually very funny and I think that Fowler is right. Nevertheless, in all fairness Uncle Bob makes the point that all effort devoted to quality pays you back in terms of sustainability and efficiency over time. But certainly he deserved to be mocked, even though with a great deal of sympathy.

Fowler wondered whether quality is tradable. He makes the distinction between internal and external quality:

  • Internal => It’s not visible, it’s about software design, cohesion and coupling, code, architecture, etc. It’s like the engine of the car, it’s a kind of magic, hidden under the hood, if it’s not in order all of a sudden the car will break and you’ll be left counting on your feet only
  • External => It’s the classic concept of quality in terms of visible behaviour or features of a system, what customers and end users experience out of it

Fowler’s point, and I can’t agree more, is that while external quality is tradable, internal quality is not. Now, we should open a big parenthesis here, related to the differences between startups and sustainable development, the cost of missing opportunities, but for now bear with me. Let’s just say that in the long run, internal quality is overall not tradable. I think that we would all agree on that.

Fowler goes on with his Design Stamina Hypothesis, in order to explain what I just briefly synthesized. The graph from Fowler’s article says it all I suppose.

The idea is that beyond a certain critical mass, the only way to have your system growing linearly with your effort is to keep things in order in the house. Otherwise, development slows gradually.

Then Fowler talks a little bit about the Technical Debt metaphor, that I will explain more in details when talking about another session. Just think that every bit of cruft that cripples into the system is going to sediment and accumulate and you’ll have to pay it back like accrued interest on the principal. It’s a very powerful metaphor that explains well certain phenomenons happening on aging code bases.

Lastly Fowler put up a nice table that tries to classify the different ways in which a team can get in Technical Debt.

Reckless Prudent
Deliberate no time for design ship now and deal with consequences
Inadvertent what is layering? now we know how we should have done it

I think that he was being nice, because I would have used Incompetent instead of Inadvertent. Anyway, the only quadrant where eventually can be temporarily acceptable to be is Deliberate/Prudent, but you don’t wanna stay there for very long. Certainly never Reckless.

So, in the end, the conclusion is that to put more effort into feature development you have to put more continuous effort into internal quality, without compromising in the long run, or this will slow you down more and more and more. I don’t remember if Fowler explicitly said that but that was clearly the whole point.

Mind map of third Fowler's keynote

This is the mind map that I have taken live during third Fowler's keynote

To recap, an enjoyable keynote, or series of keynotes if you prefer, delivered by Fowler in a very pleasant way. For me, they keynote alone was well worth attending the conference.

Guide to Test-Driven Development on ThinkCode.TV

Wednesday, April 21, 2010

Guide to Test-Driven Development

It is done: a few minutes ago the English catalog of ThinkCode.TV has gone live! We are 2 days later on our original plan (oh boy, you have no idea of the amount of glitches, 3rd party service disruptions, personal tragedies, Murphy’s law manifestations… that we have incurred into in the last few weeks), but at this point it doesn’t matter anymore. What matters is that the catalog is out and we can finally get feedback outside of the Italian technical community.

While some videos are derived from our Italian catalog, translated and narrated by an English mother-tongue speaker (David B. Harris, who happens to be a colleague, a good friend and an outstanding author as well), there is some original content that is not available in the Italian catalog too. For example, Renzo Borgatti has updated his screencast about MacRuby and HotCocoa to the latest version and David, as hinted above, has started his course about FOSS Document Management tools.

We are proud to offer subtitles for every video. I personally know English-speaking geeks who like subtitles in any case, at the very least because they can be searched and they can provide an alternative way to browse a video. On the other hand, we are convinced that a lot of people who are not too comfortable with Enligh-only content will benefit from the possibility to read the subtitles to catch even the tiniest detail.

With regards to my stuff, the first lesson of the Guide to Test-Driven Development is available. I’m very excited to see what the reaction of the community will be. Only in the last few days we are starting to see some excellent screencasts popping here and there, but nothing yet to my knowledge that resembles a complete approach to TDD like this course. The Italian version of the guide is one of the bestsellers of the Italian catalog and I hope that it will go well in English too. There are currently 3 lessons available in Italian (with the 4th one coming very soon), so you can expect a steady flow of lessons.

There are a lot of other screencasts that I’d like to produce, touching mainly on topics like OOP, design, refactoring and testing. So many things to do, so little time. 🙂

Coming soon, apart from continuing on the courses that we have started, we will have a great introduction to HTTP, an excellent course on Smalltalk and an interesting screencast covering how to upgrade a webapp to upcoming Rails 3.0 release. So, enjoy, give us feedback, and stay tuned!

If it’s for test then it has to be good

Wednesday, March 25, 2009

You are dealing with some old code: it’s not too bad, you have definitely seen much worse. There’s a class within a home-grown framework that doesn’t allow you to test some application code. You spend some time understanding how to change things to make it more testable. After a while you come up with the idea of adding a method to that class solely for testing purposes – it’s not a fantastic thing, but the alternatives are frightening and this will make a lot of code much more testable. Because you are a good person you want to make it very clear that that code is intended to be used for testing only, not in real life:

public void setMickeyMouseForTest(Class cheeseClass,
                                  String cheeseName, Mouse mouse) {
    cheeseClass = resolveAssociatedClass(cheeseClass);

    if (getLocalFactory().getCheeseName(cheeseClass) != null)
        throw new RuntimeException("Use standard setMickeyMouse instead");

    mouses.put(cheeseName, mouse);
}

This method is similar to the real thing:

public void setMickeyMouse(Class cheeseClass, Mouse mouse);

Method setMickeyMouse determines cheeseName by calling getLocalFactory().getCheeseName(cheeseClass), while method setMickeyMouseForTest assumes that cheeseName is not set (even stronger: if it is not null it throws an exception) => instead, it uses the parameter provided in the call.
In the end, the difference between the two lies in the way a certain condition is handled in the code: the method written for testing purposes is capable of dealing with an exceptional condition differently. You’ve created that method exactly to simplify the amount of setup required for tests, so that it doesn’t matter if getLocalFactory().getCheeseName(cheeseClass) is not capable of providing a cheeseName.

So, the code is committed, lots of tests are now possible, the team celebrates your genius.

Some weeks later you’re pair programming with a colleague. You’re still dealing with the same framework, but this time it’s a different corner-case. After lots of mumbling, back and forth, debugging sessions, you superficially look at the signature of that method, obviously without remembering what you have done a month before. You just vaguely remember that it was capable of dealing in a better way with a corner-case. And the method is called “…ForTest” so it has to be good, in the end we are testing indeed.

It doesn’t work. An exception is thrown. The exception hints to “Use standard setMickeyMouse instead…“. Oh gosh, let’s take a look: ops, I know what it is, we’ve forgotten to set cheeseName for cheeseClass in the local factory. Let’s do that.

<type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type> <type>

Damn, it’s still not working. What is it happening?!?

<debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug> <debug>

It’s very strange.

getLocalFactory().getCheeseName(cheeseClass) is not null, so how can it possibly say that it is null instead?!?

<more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug> <more debug>

Oh my gosh! The exception is actually thrown WHEN getLocalFactory().getCheeseName(cheeseClass) is not null, not viceversa!

What happened is that you and your colleague just wasted 20′ because you misread “!= null” (reading “== null” instead). What does that tell you?

It told me a few things:

  • Managing null values is always evil and error prone. At the very least, checking for a null disrupts the business logic and it makes the code less readable, ultimately more likely to break.
  • It’s too easy to misread a check based on != vs ==. Not only that: the fact that an exception is being thrown if the expression evaluates to true hints that the check is to verify if the value is null, because that is what you would typically do when you are adding a guard to your code. Which brings me to the next point.
  • Moreover, the intent of the code is not clear. It’s not enough to call a method “somethingMeaningfulForTest“, that is the suffix “ForTest” is misleading if the method is not truly applicable for every test. This is even reinforced by the fact that the exception message is not enough communicative.
  • As usual, test code has to follow the same standard of quality as application code, which means readability, expressiveness, simplicity, lack of duplication. This is particularly important for accessory code that is written to support tests.

So, in the end, how should that method be called? What about:

public void setMickeyMouseForTestWhenThereIsNoAvailableCheeseName(
    Class cheeseClass, String cheeseName, Mouse mouse);

The underlying precondition is that method getLocalFactory().getCheeseName(cheeseClass) returns null for this code to execute properly. This should be made clearer with a checked exception being thrown by the method, or, even better, by a custom annotation that marks the method with the defined precondition. In Java land this doesn’t go very much beyond documentation purposes for a variety of reasons:

  • First of all there are limitations on the attributes that an Annotation can exhibit. Specifically, only String, Class and primitive types are allowed, not even object version of scalar type like Integer can be used.
  • Second and foremost, annotations can be queried to provide metadata about code, but they don’t really affect code execution. An annotation is useful only to the degree it is recognized by the runner executing some code. There is in the end no native and effective support for Design By Contract in Java and there will probably never be. A useful result can be achieved by combining together AOP with Annotations, but I have mixed feelings about it => in the end I always have the impression that the mumbo jumbo typical of the supporting infrastructure it’s there just to circumvent a limitation that should be inherently addressed by the language itself.

Or shouldn’t it?

Using functors to handle test connections

Thursday, October 9, 2008

A few days ago I was working on some functional tests that have the following structure:

      public void testSomething() throws Exception {
        // 1. istantiate the system
        // 2. interact with it through the UI
        connectDB();
        // 3. assert the state of the system by examining the DB
        relinquishDB();       

        // 4. interact a bit more through the UI
        connectDB();
        // 5. assert again the state of the system by examining the DB
        relinquishDB();        

        // etc.
    }

Some notes about them:

  • Tests are implemented with JUnit 3.8.2, but this is irrilevant to what will follow.
  • The application is a webapp implemented with a proprietary web framework.
  • Those tests are implemented running the servlet engine in process through ServletUnit.
  • The DB is interfaced through a proprietary framework and it is accessed behind a mock JDBC driver that works translating SQL statements in memory.
  • The state of the system is examined by fetching either an Entity or EntityList, abstract classes that represent respectively a single record or a collection of records in a table.
  • Methods connectDB() and relinquishDB() are used to manage the test connection, which needs to be different than the one used by the application for structural reasons.

All the tests that follow the above structure inherit from an abstract TestCase which implements its own setUp and tearDown, treated like template methods whose behaviour can be refined further (for example, choosing to install a different mock DB). connectDB() and relinquishDB() use connection parameters that are potentially established differently for every test, but in reality they are seamlessly copied over from test to test.

While this structure makes sense, I thought that repeating connectDB() and relinquishDB() several times in the test is extremely annoying. It would be nice if we can wrap some logic into a block that takes care of the repetition for us: calling connectDB() first, executing our code and then calling relinquishDB() in the end. If I was programming in ruby, that would have been extremely easy to implement with proper blocks, wouldn’t it be? Well, in java is not that difficult either, if you tolerate the syntactic noise of course. Let’s see how.

To start, we can define a Functor interface that can be used to implement a block without parameters:

public interface Functor<T> {
    T exec();
}

Now we need to wrap a bit of logic around it that takes care of connecting the DB and relinquishing it afterwards:

public class Fetcher {
    public static <T> T queryStateFor(Functor<T> f) {
        connectDB();
        T result = f.exec();
        relinquishDB();
        return result;
    }
    private static void connectDB() {
        // ...
    }
    private static void relinquishDB() {
        // ...
    }
}

The actual implementations of Fetcher.connectDB() and Fetcher.relinquishDB() are fairly trivial and the methods are in reality inlined: I’ve written them in a Compose Method style just to make them easier to understand and to trace back Fetcher structure to the test structure above.

The Fetcher can be used in the following way (assuming that it is imported statically in the test case):

    public void testSomething() throws Exception {
        // 1. istantiate the system
        // 2. interact with it through the UI
        final PurchaseOrder po = //...
        PurchaseOrderStatus status = queryStateFor(new Functor<PurchaseOrderStatus>() {
            public PurchaseOrderStatus exec() {
                return po.getLastStateChangeStatus();
            }
        });

        // etc.
    }

As you can see, this refactoring is not about saving keystrokes.

A developer was asking me which kind of advantage this style achieves over the other. In general, I think that functors are a powerful tool, often underestimated in statically typed languages like java. But these are the reasons why I think they are particularly relevant in the context of queries and tests:

  1. Avoid repeating connectDB(); … relinquishDB(); without the introduction of methods that would have to be rewritten for every test.
  2. Ensure that queries for checking purposes correctly connect to the proper DB and relinquish it in the end.
  3. Make the test more readable, without hiding relevant details (connecting and relinquishing the DB are irrelevant details to the test, only the query matters in the eyes of the reader / maintainer).
  4. In general, make the test less dependant upon lower level details whose relevance is marginal.
  5. Using a functor the query can be executed as a generified method, hence it definitely scores better in terms of type safety.

I’ve also thought about any disadvantage:

  1. The syntax looks a bit odd for the java world, but it’s not entirely a stranger.
  2. Current functor implementation can handle only one result per call, but it can certainly be extended and in general it doesn’t hurt significantly calling several functors in a row.

And you? What do you think about this way of handling a test connection to the DB?

PS: While I think that this style provides a better alternative to repeat calls to connectDB() and relinquishDB() all over the code, there’s actually a simpler way to solve the problem ==> the tests can be provided with their own connection that has nothing to deal with the connection handled by application code running in the servlet engine (credits to Mark for recognizing it). Nevertheless, functors are a powerful tool typically neglected in the java world and they definitely deserve more attention in situations like this one.

The consequences of shipping

Thursday, September 11, 2008

A friend of mine pointed me towards one of last Kent Beck’s mini-essays: Just Ship, Baby. While reading it I felt more and more surprised: I was hoping to find a controversial but sophisticated provocation directed towards those who hide behind the process and fail to deliver because of it. That can be quite common among those teams that are approaching agile methods for the first time and fail to understand and embrace the pragmatic essence of methods like XP. It’s a kind of error that can happen frequently for teams coming from a waterfallish culture and it’s always done in good faith. The rules are tools and they change over time, based on the circumstances.

Despite his good intentions, though, I think that Beck has failed to ship the right message, so to speak: the examples are quite misleading because when I’m exploring a technology that I don’t know well enough, the right way to go is spiking and prototyping until I get the answer that I’m looking for. Under these circumstances, only at a later stage it makes sense to apply TDD, typically when you have played enough with the technicalities of the specific API. Certainly, this shouldn’t happen anytime sooner than when you feel safe filling the gaps related to the expectations in your tests. So, I’d say that Beck’s problem in this case has been VIOLATING what I consider one of the implicit rules of TDD: don’t write your tests until you have enough understanding of the modelling mechanisms of the API / framework / system you are dealing with. TDD can be used to explore those mechanisms, but that’s a completely different story.

There’s actually even more there: if I’m just interested in evaluating the feasibility of something, then a throwaway prototype seems a better idea. When you have confirmed the feasibility, and only after that, then you make tabula rasa and develop your system applying TDD consistently. No shortcuts, but different approaches depending on your intent. I don’t think there’s anything new in this.

Going back to Beck’s essay original intent (as I understand it), I think that the target has been missed: the issue whether you follow the rules or you deliver the system has not been addressed. First of all, it’s a faulty dilemma if you put it like that. If there’s one thing that agile methods have taught me it’s that delivering a system and/or completing a project are the result of trade-offs, continuous negotiation, constant planning throughout the entire project life, reassessing current status and goals based on feedback. But let’s put all those considerations aside for a while and let’s consider a situation where a short-term deliverable can be achieved if some of the practices are relaxed. In this situation, the team incurs typically into some significant technical debt or, even worse, the external quality of the system is severely affected. What should you do? Well, it depends and as usual it’s a judgement call.

There are situations in which it makes perfect sense and it buys you time to clean the system immediately afterwards. I haven’t seen this happening many times, especially because it requires a perfectly healthy, open and honest environment, but I accept the idea that it can happen. On this subject, for example, there was a blog post by James Shore a couple of years ago which triggered an interesting and lengthy discussion in the XP mailing list.

There are other circumstances where the system can already be so compromised that no more design debt can be tolerated or the lack of correctness of the software can cause financial loss (or worse). My experience is that this is much more likely to happen and when it does its consequences can be devastating. Saying “Just ship, baby” can have catastrophic effects and it’s ultimately irresponsible.

It’s so annoying having to test all that code and solve those bugs. Real programmers write correct code and eventually solve bugs instead of sleeping. That’s what we are paid for, aren’t we? I fear that Beck’s post can ultimately feed the despicable culture of Macho Programming.

Delivering software is not like winning a football game: it has consequences that need to be taken into account. In sports, when a game is over, it’s over: unless you have broken the law, got some dope or other things that have nothing to deal with sport itself, every game is self-contained.

Software development though it’s different. More than often the consequences of your actions come back at you, sometimes in very unpleasant and everlasting ways.

Missing MethodTimer.computeTotalTime() in Implementation Patterns

Thursday, March 13, 2008

While preparing a review of Kent Beck’s Implementation Patterns book for stacktrace.it I stumbled upon a missing detail in Appendix A (Performance Measurement): where is the implementation of MethodTimer.computeTotalTime()?

I didn’t pay much attention while reading the book: Appendix A is one of my favourite chapters because you can finally see what Beck means in practice, but I haven’t really considered all the implementation details, only the overall philosophy. For the review I decided to go deeper and I couldn’t really understand what happened to MethodTimer.computeTotalTime(). In addition, until you realize how that method should look like, maybe you find yourself in troubles trying to fully grasp the design. I certainly did. Google didn’t help (I guess that Beck for whatever reason didn’t want to publish the code), so I did it by myself.

 private long computeTotalTime() throws Exception {
 	long start = System.nanoTime();
 	for (int i = 0; i < iterations; i++)
 		method.invoke(instance, new Object[0]);
 	return System.nanoTime() - start;
 }

This is not rocket science of course, but I had a few false starts before getting it (also because I made a few mistakes copying the code from the book and I was misled by the results). Hope it can help you as well.

qixweb home page

Monday, September 4, 2006

Thanks to Andrea Vaccaro, finally qixweb has its own home page at codehaus. It’s pretty simple and basic, but it gives you an idea.

(more…)

TDD live demo in ruby

Sunday, January 15, 2006

Marco Abis has published all the stuff related to the Second Italian Agile day. This means that there’s also the zip file of all the steps related to my session.

I have collected all the different versions of the code that I was developing during my session, I have cleared them a bit (ie: I have removed insignificant steps, typos, etc.) and I have written a small comment for each step. What I have obtained is a sequence of 49 steps, made by 42 live steps and 7 offline to complete the work. What’s interesting is that first file was saved at 3:40:48 PM, while the last file at 4:41:06 PM ==> it means 42 steps in 62 minutes. Steps have not all the same length of course, but I can assure you that there are always less than 3 minutes between one step and the next one.

(more…)

Jim Freeze talking about writing DSLs in ruby

Thursday, December 29, 2005

Jim Freeze has an interesting post about writing DSLs in ruby. Check What is a DSL? – O’Reilly Ruby:

The third time around, after the Ruby DSL hype had been going around for a while, I decided to use Ruby. This time, I was able to create the DSL in about five minutes. It was readable, and I was able to focus on the end users frame of reference.

The moral of this story is, don’t write a mini language if you don’t have too. And, don’t settle for a simple DSL when a full featured one is needed. Consider extending a GPL into a DSL. Particularly an expressive language that is good at creating a readable DSL — like Ruby.

(more…)