Adam Sroka
 
View LinkedIn profileView Adam Sroka's LinkedIn profile

Jan
02
By: Adam Sroka
1/2/10 1:55 am UTC
Topic: No Tags

In 1996 a friend of mine asked me what my New Years Resolution was. I didn’t have one, so I thought one up on the spot, “My resolution is to quit making New Years Resolutions.” I have stuck with it for fourteen years now.

The idea behind New Years Resolutions is great. We should reflect on the year that has past, think about what we would like to do differently in the future, and resolve to make that change. That is a great thing to do. The problem is that when we only do it once a year we tend to fail. Then, we wait a whole year to reflect and do it again.

So, this year resolve to stop making New Years Resolutions. Instead, reflect on your behavior soon, and make changes right then. Change every month, every week, every hour. Soon you will get good at changing and those promises you make to yourself will come true more often than not.

That is the lesson of Agile: self-reflection is hard, and we kind of suck at it. Change is hard, and we kind of suck at it. If we do it more often then we will have to do less each time and it won’t be so hard. If we do it more often then we will get good at it and it won’t suck so much.



Dec
15
By: Adam Sroka
12/15/09 6:14 pm UTC
Topic: No Tags

In his 1986 paper, No Silver Bullet — Essence and Accidents of Software Engineering, Fred Brooks describes the difference between essential and accidental complexity in software systems. Software is complex because what the users need to do is complex. Such complexity cannot be eliminated, but it can be managed, and most of what we do in software development is about managing that complexity.

The goal of Agile Software Development is to deliver a continuous stream of valuable, working software to customers. The challenge in doing that is to find bugs as soon as we create them, fix them, and deliver software that is defect free. This is important, because defects found by customers create a backflow of information that disrupts our ability to deliver value. To some extent this backflow is essential, but by finding and eliminating defects at the source we can keep the signal-to-noise ratio high and get our customers to give us more information about what they need and less information about mistakes we made.

So how do we, simultaneously:

  1. Embrace essential complexity that comes from the user domain?
  2. Eliminate accidental complexity – in all of its forms – as waste?
  3. Identify and eliminate defects at their source?

The Agile approach to managing essential complexity is very close to the approach that Fred Brooks advocated so long ago: Grow the system incrementally. Hide complexity in a modular system with various layers of abstraction – individual ideas are expressed where relevant and viewed as abstractions from the perspective of surrounding modules. All software paradigms, object-oriented, procedural, functional, aspect-oriented, etc. are methods of organizing code into such abstractions. The trick is that we can’t accurately predict where our system will become complex. So, we have to keep our solutions as simple as possible, and hide complexity only where we find it in the course of trying to describe some real world user need.

The implications of this cut across everything we do:

  • Given a user story we should create the simplest solution that could possibly work. This is literally the same thing as saying, eschew accidental complexity.
  • We refactor to simplify the design of existing code. This activity, which is an integral part of TDD, is specifically designed to remove accidental complexity as it occurs, particularly in the boundaries between stories and surrounding essential complexity as it is discovered.
  • We move forward deliberately, in increments, with plenty of slack. We do this because complexity is hard. We need to take the time to look for it and deal with it.
  • We test and refactor mercilessly. Complex things are hard to test. Just like insects are attracted to bright lights, software bugs are attracted to complexity (Essential or accidental.) Like a porch light on a Summer evening, if it’s complex and it isn’t tested I promise you it has bugs.

In Part Two I will address the issue of designing code and tests in a way that:  hides essential complexity, avoids accidental complexity, and exposes most defects at the source.



Dec
01
By: Adam Sroka
12/1/09 5:33 pm UTC
Topic: No Tags

We already know that good unit tests are on FIRE. Here are some characteristics of good code:

Small – Classes contain only a few methods. Methods are no more than a few lines. Together they fit nicely on your screen without scrolling.

Intentional – Every bit of your code reveals precisely why it is there and what you intend for it to do.

Singular – Classes have one responsibility. Methods do one thing.

Tested – Every piece of interesting behavior in your code has a corresponding test (Likely it was written first.)

Encapsulated – Modules don’t know what information other modules contain. They tell instead of asking. They talk only to their closest collaborators.

Refactored – Eventually, code has to change. Good code stays good when it changes because it’s author loves it.



Nov
30
By: Adam Sroka
11/30/09 1:21 am UTC
Topic: No Tags

Agile teams have no leaders, because everyone on an Agile team is a leader. However, leadership is still important. So, how does leadership work if everyone is a leader? Here are my rules:

1) If something needs to be done, do it. Do it very, very well.

2) Never do anything by yourself. Always ask for help. Always give help.

3) Don’t delegate, cooperate. Never tell anyone to do anything that you can do for yourself.

So who is really in charge? The customer is. The customer knows what she wants and what she is willing to pay for. The team must deliver that.

The team gets to decide how to meet the customer’s needs. You won’t always agree. You have to work it out.

Remember that the right people showed up. You will solve the problem to the best of your ability and so will your teammates. Telling them how is counterproductive. If you know how then do it yourself, but involve them.

If you work this way everyone has an opportunity to succeed, to learn, and to grow.



Nov
18
By: Adam Sroka
11/18/09 10:13 pm UTC
Topic: No Tags

Good unit tests are:

Fast – they run in no more than a few milliseconds on typical hardware

Isolated – they remove any dependencies using mocks which verify the way the dependencies are called and stub the return value.

Repeatable – they have no dependence on external state and can be run over-and-over with the same results (Unless the code changes.)

Examples – they demonstrate the way that the code is intended to be used and thus enable Coding By Intention (If you write them first.)

(note: due respect to the author of FIRST but I prefer my version.)



Nov
12
By: Adam Sroka
11/12/09 5:59 pm UTC
Topic: No Tags

Conventional wisdom says that literal values in code are bad and should be replaced with constant fields. The usual justification is that when you need to change the value it is easier to change the value of the constant than to change the literal in the various places where it appears. This avoids the real issue: why is the value appearing in multiple places?

Constants are a deodorant. Rather than using a literal value in numerous places, which is bad, we empower ourselves to reference a static field in numerous places, which is almost exactly as bad. Perhaps instead we should consider what concept that value represents that needs to be reused all over our code and find a way to encapsulate that responsibility.



Nov
09
By: Adam Sroka
11/9/09 7:16 pm UTC
Topic: No Tags

On Agile teams no one owns anything. The team is collectively responsible for what they create.

Agile teams are “cross-functional.” They are “Whole Teams” consisting of a variety of experts with different skill sets.

On the surface it seems like there is an inherent contradiction between the above ideas. At least, there is a conflict.

I am an expert and I want to do the things for which I am an expert. There are other experts and they can do the things for which they are experts. Yet I don’t own any of the work, and somehow I am responsible for what other people do.

The Expertise Exists on the Team

I need to let go of the notion that I am the expert. There are simply a number of things that need to get done, and I should do the next one.  The next one might not be the one that is most comfortable for me.

I think that I am a rock star programmer. I think that I am a lousy interface designer. Yet if the next thing to do is to create an interface then my job is to do that.

But, I don’t know how to do it! Good. It’s time for me to learn. Does someone on my team know how? Maybe I should ask them.

Cross-functional doesn’t mean that someone knows how. Cross-functional means that anyone can do it, and anyone can ask for (and receive) help.

There are lots of benefits to this:

    • Everyone learns the system.
    • Everyone learns how to make the system better.
    • Everyone learns how to ask for help.
    • Everyone learns to help.
    • Everyone learns.