I am Paul Wilson; Mere Complexities Limited, sells my consulting, coaching, and coding services. I am passionate about Agile, particularly Test Driven Development.
Java Generics
Andy Swan has decided that Java Generics are probably not worth the extra complication. Interestingly a lot of the arguments against generics could be (and often are) used against strong typing in general - it does not seem catch many errors / it is all covered by xUnit tests etc..
Having to cast to use the collection classes breaks the strong typing of Java. It also gives the impression that it is ok to cast - it usually is not. I blame non-generic collections for this kind of thing:
Item item = itemRepository.findItem(itemId);
((ItemImpl)item).setMarvinIdentifier(marvinId);
Apart from collections, however, I can't remember having felt the need for Java Generics. I wonder if it would have been better to just have built dynamic arrays and a typed version of a perl\ruby style hash into the language.
Cynefin
A few weeks ago I attended a
Cynefin certification course in Greenwich. Cynefin draws from the fields of social complexity, narrative, cognition, sense-making, knowledge-management and more to produce a mangagement consultancy framework.
Origins
Cynefin is the brain-child of
Dave Snowden. Cynefin and Dave spun off from IBM in 1994. My strong impression from the course is that the Cynefin and Dave Snowden point of view are the same entity.
Philosphy
The Western (enlightend) view favoured by most official management and traditional software development is reductionist: that the whole is simply the sum of all its parts. Given enough knowledge and analysis all can be calculated and predicted from first principles. This is a world of cause and effect characterised by
Laplace's Demon.
An intellect which at a certain moment would know all forces that set nature in motion, and all positions of all items of which nature is composed, if this intellect were also vast enough to submit these data to analysis, it would embrace in a single formula the movements of the greatest bodies of the universe and those of the tiniest atom; for such an intellect nothing would be uncertain and the future just like the past would be present before its eyes.
There is a post-modern view of nature that interaction of the parts produce something more than their simple sum. In this model, essential information is lost by "divide and conquer" approaches to analysis and management.
Cynefin takes a lumpy view of its universe: some things are amenable to reductionism; other things require a more complexity based approach. However while recognising the existence of the former, it concentrates on working with the latter.
[Work in progress - I plan to add more on Cynefin Domains and Components later]
[I should add this is my take on Cynefin - I may have got some stuff entirely wrong]
Easy Peasy Mock
For various reasons, that I may go into later, I gave up
Jmock a few months ago. I still find that
fake implementations are useful to have in the testing toolbox. Here is a simple way of faking a subset of interface implementations: for example we might just want to fake
getParameter from
HttpServletRequest using a
Self-Shunt.
public class TestSomeWebThing extends TestCase
{
private String _parameterNameUsed;
public void testSomeServlet() throws Exception
{
HttpServlet testee = new MyServlet();
testee.service((HttpServletRequest) DummyProxy.dummy(HttpServletRequest.class, this),
(HttpServletResponse) DummyProxy.dummy(HttpServletResponse.class, this));
assertEquals("expectedParam", _parameterNameUsed);
checkTheOtherStuffHappened();
}
/**
* Implements method from HttpServletRequet
*/
public String getParameter(String parameterName)
{
_parameterNameUsed = parameterName;
return "mavis";
}
........
}
Here is an implementation for DummyProxy:
public class DummyProxy
{
public static Object dummy(Class implementMe, Object partial)
{
return Proxy.newProxyInstance(implementMe.getClassLoader(), new Class[]{implementMe}, new Handler(partial));
}
private static class Handler implements InvocationHandler
{
private Object _partial;
public Handler(Object partial)
{
_partial = partial;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Method equivalent = findEquivalentImplementation(method);
if (equivalent == null)
{
throw new UnsupportedOperationException(method.getName() + ":" + args);
}
return equivalent.invoke(_partial, args);
}
private Method findEquivalentImplementation(Method method)
{
Method[] implementations = _partial.getClass().getMethods();
for (int i = 0; i < implementations.length; i++)
{
Method implementation = implementations[i];
if (methodNamesMatch(implementation, method) && methodParametersMatch(method, implementation))
{
return implementation;
}
}
return null;
}
private boolean methodParametersMatch(Method method, Method implementation)
{
return Arrays.equals(method.getParameterTypes(), implementation.getParameterTypes());
}
private boolean methodNamesMatch(Method implementation, Method method)
{
return implementation.getName().equals(method.getName());
}
}
}
Kathy Sierra
How does Kathy Sierra manage to write such well-written, content-rich, and
frequent blog postings?
This latest, tips for teachers, is spot on (again).
Life's a backlog, and then you .......
well, let's not get too depressing......
Just back from the
Cynefin course with a big bunch of consolodation, evaluation, and futher reading to be done. Plus I really ought to get a summary of my experiences here. I still need to sort thoughts and experiences out from
XP2005 the other week. I've got
Fitnesse, and
FitLibrary to get to grips with,
Ruby on Rails to learn, and there's the
XP Wednesday stuff as well. I really need to get some fiction \ literature read soon, as well. I've DVD's unwatched. I also need to make time for family. Sleep's needed too.
I'm going to try a life
backlog. Wonder if I need to estimate.