Simple code that works is only considered a bad thing by programmers who either don’t care about maintainability, or like to hide their inadequacies behind complex solutions.
During a pairing session today, we spotted some duplicated code and a period of refactoring ensued. The code in question related to some simple DB queries – the code for getting a connection, returning results and cleaning up was duplicated, with only the query and the exact part of the result set required being duplicated. We already had some code which could be used to remove this duplication – previously someone had written a DB visitor which was being used internally in a test class.
Extracting the visitor code out into a class in its own right was trivial. What was not was replacing the repeated code. After 10 minutes of head-scratching we had to ask ourselves the question “is this still refactoring”?
Let’s look at what we had done – we’d extracted out our visitor code to make it an object. The existing code using the visitor still worked. We couldn’t get other code using our visitor happily quickly. We decided to leave it and move on – the rational being that refactoring should be something quick you do in the normal test-code-refactor process. If you can achieve a quick win that improves code outside the scope of what you are working on, then great – but when improving code outside the purview of your current task takes too long, it feels like going off at a tangent.
Continue reading…
A largely unenjoyable couple of hours was spent tracking down a nasty little issue surrounding classpaths in cygwin. First a little background. On Windows, if you want to specify a classpath, @java@ expects it to be a series of semi-colon separated paths, like so:
set CLASSPATH=c:libsome.jar;c:classes;.;
On Unix, @java@ expects a colon separated list:
export CLASSPATH=/usr/lib/some.jar:/home/export/myarea/;.
I’m playing around with using a shell script to run my app on windows, however I’m using cygwin as I hate writing bat files. This is a bit of a problem however – cygwin expects Unix format paths, but we’re still running a Windows version of @java@. Once I’d worked out that this is what was causing the strange ClassNotFoundExceptions, a quick google turned up @cygpath@, which can translate from Windows to UNIX paths (and vice versa). So, when invoking @java@ in my shell script I just changed:
java -classpath $MYCLASSPATH org.package.MyClass
to:
java -classpath `cygpath --path --windows $MYCLASSPATH` org.package.MyClass
Next up, I can change my script to work on Unix by conditionally invoking @cygpath@ only if I’m running in a cygwin bash shell.
No posts from me in a while which has mostly been down to playing sys admin at my current client – more on this in a while no doubt. In lieu of anything of greater interest, I thought I’d remind you of two upcoming events for your calendar, if you happen to be in London in the next couple of weeks.
Firstly, the monthly “Java meetup(London Java Meetup – 23 August 2004)”:http://web1.2020media.com/j/jez/javanicuscom/londonjava/ will be on the 23rd of August. I’m hoping for something a little more laid back than last months mammoth affair as I hardly got to talk to anyone. No real topic, but expect talk on Java, beer, blogging and state machines.
Running both this and next Wednesday, is Geek Night London. More of a techy affair than the Java meetup – and non-Java specific too, it involves a bunch of us working on Open Source stuff, talking about it, and normally eating pizza. I’ll be working on either “JBehave”:http://jbehave.codehaus.org/ or “DamageControl”:http://damagecontrol.codehaus.org/ depending on how I feel. If you want to pop by for either this or next week, then stick your name down “on the Wiki”:http://geeknight.thoughtworks.com/index.php/GeekNightLondon.
I’m hoping to have another successful GeekNight tonight. It’ll be more development focused I expect – I’ll be working on a UI for JBehave (with a view to creating an IDEA plugin) and no-doubt others will be doing development they’d appreciate help with. If you fancy coming along, pop over to the wiki and “put your name down”:http://geeknight.thoughtworks.com/index.php/GeekNightLondon28July2004. More details can be found “here”:http://geeknight.thoughtworks.com/index.php/GeekNightLondon.
@PicoUnit@ has been developed with a view to reduce the amount of setup within specifications, using Picocontainer to instantiate and pass in the required dependencies. One use is to locate test data from an external source and pass it in (this example is showing PicoUnit working with JBehave):
class ProductCode {
public final String productCode;
public ProductCode(String productCode) {this.productCode = productCode;}
}
...
public class ProductTest implements picounit.Test {
public void testProductHasNonZeroPrice(ProductCode productCode, Verify verify) {
verify.that(new Product(productCode.productCode).getPrice() > 0);
}
}
Continuing a series of write-ups on the presentations made at “Geek Night”:http://geeknight.thoughtworks.com/index.php/GeekNightLondon last week, “Nat Pryce’s”:http://nat.truemesh.com/ latest project OO-Matron is next up.
Rather than the evolutionary approach of JBehave, OO-Matron might potentially be revolutionary, or might just be too complicated for people to use – I’m still undecided. It’s designed to replace existing Mocking API’s, whilst at the same time adding the ability to enforce system-wide invariants to your tests, which in turn can be used to provide system documentation.
Continue reading…
At last Wednesday’s “Geek Night in London”:http://geeknight.thoughtworks.com/index.php/GeekNightLondon, we had a presentation of three related software development projects. I’ll give a brief write-up of each of them, starting with “JBehave(Codehaus – JBehave)”:http://jbehave.codehaus.org/.
JBehave has been written as a replacement for JUnit, with a view for better suiting Test/Specification/Behaviour Driven Development (someone please write a book and rename this!). The first thing apparent from looking at JBehave, is the change in language:
public class TimerSpec {
public void shouldMeasureAPeriodOfTime() throws Exception {
// setup
Timer timer = new Timer();
timer.start();
// execute
// TODO make this not time-dependent - could possibly fail
Thread.sleep(10);
timer.stop();
// verify
Verify.that(timer.elapsedTimeMillis() > 0);
}
}
I’ve been looking to simplify some exception handling code recently, namely I wanted to get rid of much of the defencive exception handling placed in event handlers in a Swing UI. Code like this:
public void actionPerformed(ActionEvent event) {
try{
//Do something
...
}catch(Exception e){
//handle exception
...
}
}
With the perceived desire nowadays amongst the unwashed (blogging) masses to simplify the way their code acquires dependencies (whether it be via setter or constructor or ego injection), a recent problem made me take a step back and look at the problem from a slightly different angle – before you start wondering about how to acquire your dependencies you should really be asking questions of yourself as to why you need those dependencies, and whether or not in your drive to simplify one piece of code you end up complicating the system as a whole.
Lets take the scenario I’ve been looking at recently. We have a @View@ object that represents a domain object. Next we have a @Viewer@ – this object is responsible for providing a display environment for the view. From time to time, a @View@ might need to display an error – this is something the @Viewer@ handles for it. Lets look at one approach to giving @View@ access to @Viewer@
public class MyView implements View {
public void doSomething() {
...
//Report error
Viewer.instance().displayError(errorMsg);
}
}