Friday, 4 July 2014

Friday, 20 September 2013

If You Value Someone, Set Them Free

Earlier this year I did my first proper conference presentation: "Why Do I Hate Unit Tests" at Devoxx UK (you can view the slides here) and I absolutely loved it. Since then I've been trying to persuade some of my more talented colleagues to engage in public speaking, be that internal talks, lightning talks, local or national conferences. 

For one reason or another, getting developers to speak in front of a crowd is difficult and was originally going to be the focus of this post, but while I was thinking about it I realised that I know people who have been in the industry as long as I have who have never even been to a conference, never mind speaking at one!

So lets say we have a manager, "Bob" and an engineer, "Dave", and Dave wants to go to a conference. When Dave goes to Bob and makes his request I have no doubt that the first question Bob is going to ask is "why?"  If Dave is prepared he'll have the list of sessions and what the benefits of each are, but here's the kicker: 

The sessions you attend are only a fraction of the benefit you get from attending a conference

And here's why

Happiness

Engineers, at least in my experience, want to go to conferences, and when you give someone something they want it makes them happier, and when people are happier they're more motivated and more productive*.  Make it a conference in a foreign country and those benefits are increased even further - you're letting your employee know that you value them and are willing to invest in them

Creativity

Do you know what engineers do when they're together outside of work? They talk about work! When I'm stuck on a problem, I'll grab a colleague, go for a smoke**, talk about the problem and usually come up with a solution.  Go down the pub on an evening and engineers are still problem solving, they're just bigger problems. Send two or three guys away to a conference and you'll be surprised what they can come up with when unencumbered by the daily job.

Raise your Company Profile

Wouldn't it be great if people wanted to come and work for you instead of you having to go and look for people? If your staff enjoy working for you and they're out at conferences telling other people how much they enjoy it, your chances of attracting talent increases. If you're doing cool shit, have your techies speak at conferences and get the message across even more. If your staff aren't happy and you don't want them selling, well hell, you've got much bigger problems than I can help you with. 

Networking

For me this is by far and away one of the biggest benefits of a conference - meeting people. Personally I just like meeting new and interesting people, but even if you look at it from a cold, hard, logical position, isn't it better to have a much wider pool of talent from which to draw on? Like I said before, techies like to talk about problems, but when they know someone who specialises, that's the person they'll go to for help!

I'm writing this sat on a plane returning from #AgilePrague and I met some absolutely awesome people there. Fun people, smart people, people who are industry leaders and hey, even a guy who played in a kick ass 80s hair metal metal band! But they all have one thing in common- I'd have met none of them if it wasn't for a conference. 

*Don't believe me? Try reading some books on motivation, I recommend Delivering Happiness and Drive

** Any non smokers who think its unfair that smokers take so many breaks: we may be away from our desks, but we're still working, so ner.

Tuesday, 10 September 2013

A Tale of Two Recruiters

Whether you're trying to find a new job or you're a hiring manager trying to fill a position, at some point in your career you're going to have to deal with recruiters.  For both sides, recruitment is difficult, and professional recruiters should be there to help make it a lot easier.  When you really think about it, recruiters should be the heroes who getting you a job with your ideal company, or finding you just the right person to fill your vacancy. In reality though, it's usually a different story.

A while back I was chatting with a friend about recruitment and she told me a story of an email she received from a recruiter via LinkedIn for a completely unsuitable position.  She asked the sender if they'd even bothered to read her CV to which she got the reply that he has too many to read all of them.  Not only is it incredulous that a professional (and I use that term loosely) recruiter is essentially asking other people to do their job for them, but in this instance they obviously haven't done even the most basic of checks as that friend was Trisha Gee.  For those who don't know Trish, she's exceedingly well known in the Java community, presents at conferences worldwide, an organiser at Devoxx and a JavaOne Rock Star! so there's no excuse for this behaviour.

More recently I had another recruiter approach (through a personal channel no less) wanting to work with us and insisting they had talent they absolutely knew would be suitable for us.  The thing is, we're picky about the people we hire and look for very specific traits, and this company has no idea what they are.  When pushed about how they could find exactly the people we want, the response was just the typical agency line about how they've been in the industry for years, it's what they do, yadda.  Here's a little tip for any recruiter out there reading this - I've heard this before, everyone has heard this before, why don't you try telling me something I haven't heard before? How about telling me exactly how you'll match up the candidate to the role? How about telling me why they're the best person on the market*.

I think the worst of these I've ever seen was an unsolicited CV land in my inbox for "the best infrastructure guy in London".  The funny thing is, that CV belongs to a friend of mine, who had no idea his CV was being sent to me, didn't want his CV sent to me (he's Windows, we're *nix) and certainly was not working exclusively with that agency.  After I forwarded the email to him he wasn't working with that agency at all.  As someone looking for a job, do you want an agency flinging your CV around like this?

At the beginning of this post I said that the reality of recruitment was a different story, usually. I say usually because there are /some/ recruiters who are actually good, and it's after you've dealt with them you see how the others are no better than car salesmen or estate agents (sorry guys, but you know exactly what you're like).

When I had Barry from RecWorks ask if I'd mind help them with their marketing by just sending out a tweet with a specific hashtag, I considered it a pleasure to do.  RecWorks has recruited some of our best developers and if I was looking for a job I wouldn't use anyone else as they actually bother to figure out what everyone wants. They invested a fair amount of time finding out what kind of people we want to hire, the skills they need, what drives them and what's most important to us. They also do the same thing for their candidates and when the two align, then, and only then are we introduced.  This isn't isolated to a single employee either, it's the company ethos.  When we're not hiring we don't get annoying "checking in to see what your recruitment needs are" emails, and they don't try and poach staff for other companies.

No spam. Nobody unsuitable.  That's how to do recruitment properly.

On a final note, if you've ever been to a LJC event, you have RecWorks to thank for that, they started it.  How many recruitment agencies can say that?

* It's funny how all agencies seem to have an exclusive on the best guy on the market right now





Saturday, 23 March 2013

assertThat(testing, rocks()):

I've been into unit testing for well over 10 years now and TDD for quite a lot of that time.  Back when I started it wasn't really such a big thing and finding JUnit listed on someone's CV was quite rare - this is back when the only book you could get on the subject was Junit Recipes. These days it's pretty much ubiquitous, at least among Java developers, you can buy a whole raft of books and everyone claims to be doing TDD.

Those that know me are aware that I am somewhat of a testing nazi, insisting things are done "The Right Way" and always trying to push my testing knowledge to the limit.  Coupled with my many years of experience, I have a lot to say on the matter.  Over the next few months I plan on telling you all about what I've learned during this time.  I have made many mistakes over the years, and I see these mistakes being made repeatedly by other people, mistakes that lead to brittle, unmaintainable tests which suck to work with.

In the meantime, I'm presenting "I Hate Writing Unit Tests, How Come Everyone Else Enjoys It?" at Devoxx UK at the end of March.  If you find writing tests painful, time consuming or you just don't see how you can write clean, maintainable unit tests - come along, hopefully you'll learn something! I'll be covering:

  • Test naming
  • How to verify your tests
  • What you should/shouldn't be testing
  • Removing duplication
  • Test isolation
  • Mocks vs Fakes and when to use one over the other


If you're not already signed up, you can get a 15% discount using the coupon below.

See you there!

Tuesday, 5 July 2011

Nobody expects the unexpected invocation

  
unexpected invocation: someObject.someMethod()
no expectations sepecified: did you...
- forget to start an expectation with a cardinality clause?
- call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!

This one always gets me. I don't know why as I've worked with jMock long enough now to know how to type it out, but this is invariably the problem:
  
context.checking(new Expectations() {{
oneOf(mockObject.mockMethod()); will(returnValue(expValue));
}});

Maybe it's years using EasyMock, but I nearly always place my brackets wrong and forget to close the cardinality clause, so the above becomes:
  
context.checking(new Expectations() {{
oneOf(mockObject).mockMethod(); will(returnValue(expValue));
}});

Remember - oneOf(object), not oneOf(object.method). D'oh.

Wednesday, 12 January 2011

Listen to the Words I'm Saying With My Mouth

Multithreaded code is at the crux of any server developers toolbox and alot of times the producer/consumer pattern is used. I've seen a lot of implementations of this and typically the developer will use a shared queue for communication.

To draw an example, if we were to write a process that will read lines from a file, reverse each line and write it to another file, we might have something like this:-

  
public class QueueBasedReverser {
private static final int QUEUE_SIZE = 100;

public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("inputfile");
FileWriter writer = new FileWriter("outputfile");

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(QUEUE_SIZE);

LineProducer producer = new LineProducer(queue, reader);
LineConsumer consumer = new LineConsumer(queue, writer);

new Thread(producer).start();
new Thread(consumer).start();
}
}

public class LineProducer implements Runnable {
public static final String POISON_PILL = "_THIS_IS_THE_POISON_PILL_MESSAGE";
private final BlockingQueue<String> queue;
private final BufferedReader reader;

public LineProducer(BlockingQueue<String> queue, FileReader reader) {
this.queue = queue;
this.reader = new BufferedReader(reader);
}

@Override
public void run() {
String line;
try {
while ((line = reader.readLine()) != null) {
queue.put(line);
}
queue.put(POISON_PILL);
reader.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

public class LineConsumer implements Runnable {
private final BlockingQueue<String> queue;
private final BufferedWriter writer;

public LineConsumer(BlockingQueue<String> queue, Writer writer) {
this.queue = queue;
this.writer = new BufferedWriter(writer);
}

@Override
public void run() {
String line = null;
try {
while ((line = queue.poll(1, TimeUnit.MINUTES)) != LineProducer.POISON_PILL) {
writer.write(reversed(line));
writer.newLine();
}
writer.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private String reversed(String line) {
return new StringBuffer(line).reverse().toString();
}
}

This is a fairly typical implementation making use of a shared bounded queue for communication and a poison pill to signify the end of processing. This is problematic as the queue and the poison pill are both leaking implementation details about both the producer and consumer and has tied them both together quite tightly.

Those who have some experience with UI programming should be well versed in the notion of adding listeners to be notified of when events happen, and this is a pattern we can apply on the server as well as the client. The idea here is that the producer raises an "event" when it wants to tell the world something, in this case that it has read a line from the file. The consumer can register itself as a listener for this event and respond by writing the reversed string to the output file.

 
public class ListenerBasedReverser {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("inputfile");
FileWriter writer = new FileWriter("outputfile");

LineProducer producer = new LineProducer(reader);
LineConsumer consumer = new LineConsumer(writer);
producer.addListener(consumer);
producer.readFile();
}
}

public interface LineReadListener {
void lineRead(String line);
void allLinesRead();
}

public class LineProducer {
private final BufferedReader reader;
private ArrayList<LineReadListener> listeners = new ArrayList<LineReadListener>();

public LineProducer(FileReader reader) {
this.reader = new BufferedReader(reader);
}

public void readFile() {
String line;
try {
while ((line = reader.readLine()) != null) {
for (LineReadListener listener : listeners) {
listener.lineRead(line);
}
}
reader.close();
for (LineReadListener listener : listeners) {
listener.allLinesRead();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void addListener(LineReadListener consumer) {
listeners.add(consumer);
}
}

public class LineConsumer implements Runnable, LineReadListener {
private static final String POISON_PILL = "_THIS_IS_THE_INTERNAL_POISON_PILL_";
private final BlockingQueue<String> queue;
private final BufferedWriter writer;

public LineConsumer(Writer writer) {
this.queue = new ArrayBlockingQueue<String>(100);
this.writer = new BufferedWriter(writer);
new Thread(this).start();
}

@Override
public void run() {
String line = null;
try {
while ((line = queue.poll(1, TimeUnit.MINUTES)) != POISON_PILL) {
writer.write(reversed(line));
writer.newLine();
}
writer.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private String reversed(String line) {
return new StringBuffer(line).reverse().toString();
}

@Override
public void lineRead(String line) {
try {
queue.put(line);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public void allLinesRead() {
try {
queue.put(POISON_PILL);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

In this implementation we're still using a bounded queue and a poison pill, but this is now completely internal to the consumer and we have the option to change the implementation without touching any other part of the system. The producer and consumer have no shared information or implementation.

The keen eyed among you may have noticed that the actions of the producer and consumer are now also decoupled, meaning the producer has no knowledge that input is being read from a file, it can come from anywhere! The LineProducer also has the ability to be used to read any file, with different listeners attached to do processing.

Another not so obvious benefit of this approach is we can add multiple listeners. If we want to track how many lines per second we were processing, we can just implement a new LineReadListener to handle this logic and add it as a second listener without affecting the line reversing. This gives us a really nice separation of concerns and lets us adhere to the Single Responsibility Principle alot easier.

Saturday, 7 March 2009

Follow the Brick Road

Recently I was writing a training course on unit testing and wanted to drag some real-world examples in from our existing codebase. A fairly simple task you would think; just copy the files you need and any immediate dependencies and off you go.

And therein lies the crux of the problem. Dependencies.

As I was teaching about unit testing all I really needed was the class under test and any data beans it would need to get it's job done. 2 or 3 classes tops. So I start by bringing in the first dependency, then the dependencies that class has, then the dependencies those classes have. After I got to 320 classes I gave up and went with different approach.

Remember the big ball of mud I showed you previously, well there you have a living, breathing example of it.

The class I was testing was a wrapper over a 3rd party library so itself should be a fairly straightforward piece of code, so why on Earth was it reaching back into the core code so grotesquely? Because the classes it made use of were concrete dependencies.

How do we stop this from happening and get back to a nice, loosely coupled system? It can be fairly simple really; just introduce an interface here or there and inject it instead of instantiating a concrete implementation.

public void SavePersonAction {
public void savePerson(Person person) {
new PersonDao().save(person);
}
}

public class PersonDao {
public void save(Person person) {
// Db code here
}
}

Becomes...

public void SavePersonAction {
private PersonDao dao;

public SavePersonActon(PersonDao dao) {
this.dao = dao;
}
public void savePerson(Person person) {
dao.save(person);
}
}

public interface PersonDao {
public void save(Person person);
}

public class DbBasedPersonDao implements PersonDao {
public void save(Person person) {
// Db code here
}
}

Easy eh?

When you're sat there coding away and think to yourself “do I need an interface for this?”, if your code is providing a service, behaviour or access to something- in essence, anything that isn't a data object, work to an interface.

What does it cost you? Virtually nothing.
What does it give you? Plenty.

A common thought process I see is to only introduce an interface when there is the possibility of multiple implementations, and sure, you have to do it then but why stop there?

Working to an interface allows you, the developer, to specify exactly what an implementing class should do. You get to specify the contract, rather than relying on the default behaviour provided by the only implementation.

In the case study above a single well placed interface injected into the class would have enabled me to just copy 1 class and 2 interfaces instead of half the codebase. Surely that's got to be a win?