Saturday, March 31, 2007

The shield of YAGNI

YAGNI (you ain't gonna need it) is a good principal, but like anything, too much of a good thing isn't very good at all.

Yagni is a tool to keep us on track, to help us make decisions and guide us in our development. Like any other practice, it does not stand on its own without logic and reason. Sometimes its thrown around like my parents used the phrase, "because I said so." And while that works well for a crying three year old who wants to stay up late, any catch all phrase is dangerous.

When I am writing code, I add abstractions I don't need. You can argue this goes against yagni, because you don't need it (and you ain't gonna).

These abstractions are not there to support behavior that may exist in the future. They are added because, when things change (and they always do), it has ALWAYS been a lot more painful when they did not exist.

There is a very distinct difference between this and adding extra functionality or abstractions to enable change you think will happen.

This is an important difference.

Next time you are having a discussion and yagni is brought up, think about which one is driving what you supposedly don't need.

Tuesday, March 27, 2007

Xbox is Down!

And the oblivion expansion, Shivering Isles, comes out today.

What timing... not like I'd be playing anyway, being that I'm at work and have to paint my living room when I get home :(

Bonus Session

Oksana and my session about pair programming is now featured on the bonus session page for devteach, check it out!

Friday, March 23, 2007

I am no electrician...

Considering the amount of time I spent as an undergraduate designing analog circuitry, I thought I'd be a decent electrician.

This couldn't be more wrong.

1. My dexterity skill is low, maybe a 9. I'm a klutz, have poor motor skills, my hand writing is illegible, the list goes on. This does not work well for wire manipulation. Actually this does not work well for manual labor in general.

2. Theoretical knowledge of electricity doesn't help much; it may even hinder you (it hinders me). In general, I like to explain everything, my husband calls this phenomena, Wendy's wack a** theories. I think coming up with connections and reasoning (more like randoming) is a lot of fun. With electricity, my theories are convoluted, usually involve Ohm's law, and are ALWAYS wrong.

3. I lack patience and after failing at wiring a circuit I start hacking away at it, just trying to make anything work... Constantly running back and forth to and from the circuit breaker. Like hacking code, this just wastes time and leads to poor quality. Not the best sacrifice when it comes to electricity in your home.

Recently, I've spent a great many hours changing a light fixture, outlets and switches around the house recently and I've come away with this knowledge:

1. A voltage tester is a worthwhile investment. I don't own one, but I really, really should. Its like coding without a debugger and with no TDD, a debugger would be quite useful.

2. Before you replace existing circuitry, study the current setup carefully before taking it apart. Otherwise, you will be confused by the 8 wires available when you only need 2.

3. Like working with other peoples code, working with others peoples circuits is scary, and things built a long time ago were built, well, oddly. Keep this in mind.

4. Refactor existing circuitry one switch, outlet, etc at a time. Its annoying, because you need to return to the circuit breaker a lot (unless you live on the edge), but at least you are always in a working state and you know when you broke your circuit.

5. If you are replacing an outlet with two pairs of wires, it is either powered by separate circuits or powering something else. You can check the hot side of the circuit to see if the bridge connecting the top and bottom is there -- if it is, then the bottom wires are being powered by this outlet, and you don't need to remove the bridge on the new outlet. If its not, remove the bridge on the new outlet. If you get this wrong, things will break.

6. Having a pair working with you is priceless. They can call 911 for you. And I was told this afternoon that your dog doesn't count (unless it knew how to call for help).

7. No matter how annoyed and frustrated you are, its never a good idea to do one more quick "test" without turning off power at the circuit breaker.

If I approached circuitry like I approached software, I would be a much better electrician! I suspect applying agile and xp methodologies work very well for all home improvements. I hope I remember this tomorrow morning!

Wednesday, March 21, 2007

DevTeach here we come!

If you missed Oksana and me at Code Camp (or just can't get enough), we'll be hosting a session on pair programming at DevTeach in May!

Scott Bellware put together an excellent Agile track, and its going to be a great event.

If its not on your schedule, you're not thinking about missing a conference that features speakers as exciting as Oksana and me, are you?

Tuesday, March 20, 2007

I'm an abstract thinker

You know those idiot savants who see numbers as colors and can do complex multiplication? I'm kinda like that... I don't think of code or abstractions, I just know them immediately for every problem I encounter... kinda like seeing numbers in color, though I'm far from a programming idiot savant.

I see connections and patterns in everything, and I spent a lot of my early development days building frameworks. This was fun. At one of my previous jobs, I built so many frameworks, they created an unrelated (successful) product leveraging the frameworks from the original (also successful) product. There was a third, but I wouldn't call that as successful; its scope and complexity were too large and initial requirements were unrealistic (though I do think a poor developer is working on it and cursing me at this moment, sorry Eli).

I digress...

At Oxygen, we don't build frameworks, we use other peoples. In the beginning of my career I used many c++ libraries and frameworks that made my life more difficult than if I wrote the code myself and I stayed away from using other people's code -- it never did exactly what I wanted, it was buggy, and I had to take time to learn how to use it.

However, Kris and Luke are really good at finding the right frameworks and learning how to use them. This makes using other people's code a lot more approachable and I've grown to love some, like Castle.

Here are just a few reasons to use other people's frameworks:
1. The code evolves for you
2. Luke and Kris will figure out how to use it*
3. Respect from peers who use the framework (oh, you use castle, you must be extra cool and smart! -- I don't know if this happens in real life, but you never know)
4. Common language between developers
5. Global reduction of rebuilding of the wheel (wouldn't it be great if we shared all our code?)
6. You don't have to rewrite it when you change jobs

Here are some reasons to write your own:
1. It works exactly how you want to and you can change whatever you want (yeah, you can do this with open source, but I'm lazy and don't want to work in other peoples stuff :P)
2. You don't need to learn how to use it
3. Its fun
4. Pride of writing something cool (this can be misinterpreted as stubbornness or vanity so I would leave this one on the down low)
5. You could contribute it to open source and be super nice and cool :)
6. It doesn't exist

*You don't necessarily need someone named Luke and/or Kris on your team, just someone who's patient and interested in learning how to use other people's work :)

Whats in a name?

English is ambiguous. It is easy to misinterpret well formed sentences not to mention variable or class names.

As developers, we put the definition of a class in its name. Its a good practice. It enhances readability. Its a difficult skill to master, but important.

While a good tool for readability, it is not a substitute for documentation or a complete way of understanding a class' responsibilities or interactions (tests work great here). Even if a class is named well, it can still be misinterpreted and we enter a dangerous path when we rely on names alone.

English can't be taken too literally and what means something to someone means something completely different to someone else. I'm not sure English will ever be enough context to understand a class... With resharper, I'm a big fan of ctrl-b (go to definition), ctrl-alt-b (go to inheritor) and ctrl-alt-f7 (find usages), this is a quite a useful and quick way to explore code and can take even less time than analyzing a name!

The other day I read some bizarre, but entertaining and artistic naming conventions and I found readable and more enjoyable... interesting idea; I wonder if it would ever catch on :)

Monday, March 19, 2007

Depressing blog?

One of my fellow developers told me this blog has been depressing... making them feel that we aren't quite the snazzy agile team.

I understand why they feel that way.

In the spirit of agile, I write openly about our shortcomings. In many companies people are reprimanded or even fired for pointing out issues internally, forget about posting them publicly.

I would not show weakness in our agile group if I were not confident in our teams spirit, devotion, intelligence and adaptability. We all love and appreciate the agile practices and I feel very lucky to work with such a talented group.

Agile is a great tool, but its difficult. It takes effort. Its frustrating. Like anything worth doing, you have to work at it. And like anything you love, sometimes you write about why its so great and sometimes you need to write about why its so difficult.

Wednesday, March 14, 2007

where do the bugs go?

Our 45/55 resource split (or lack of resources) has become apparent on our new product development. We spend 45% of our time on new product work (a very exciting WPF application, Ript) and the other 55% on internal enterprise work (to keep the tv station up and running). This split yields about 4 development days on Ript during each two week sprint .

We're all excited about Ript and want to share it with our friends and family. This gives us extra drive to complete the list of stories left for release!

This drive coupled with the lack of time has become evident in a recent spike in bugs and refactoring cards. The goal of the current sprint is stabilize the application, because we ended our last sprint with an unreleasable application. So, our burndown for the sprint included every known bug in application.

Our burndown looks something like this:
Sprint goal: Stabilize application -- fix 18 open issues
Bugs fixed so far: 26
Bugs left: 16 (I told you that last release was unreleasable!)

Because our goal is stabilize the application, we're treating the bugs as stories and adding stories to the sprint as bugs are found.

How did we get here? We are all profession, strong developers who are very committed to quality...

What went wrong?

Well... we've been "finishing" stories when they aren't really "done."

This isn't happening because we are lazy or over worked or don't understand the requirements, but because we are so desperate to move forward in the project.

When you have a 2 week iteration, even if you don't spend all 2 weeks on the project, you want to finish 2 weeks of work. Especially after a few weeks of enterprise work that take up more than 55%...

Enough explaining why we have bugs...

What was this post about anyway? Oh yeah... making bugs stories...

I had an ah ha moment the other day when I was thinking about where bugs belong in the sprint backlog. As a developer and a user of an application, I don't want any bugs. Our customer proxy may want features before bugs are fixed, but we may want to fix bugs before adding new features, because the bug could be a smell of a bad design or some needed refactoring... basically prioritizing bugs difficult!

Have you seen this bug rating system before (or something similar)?
Priority 1: Application crashes, no work around, data corrupted/lost
Priority 2: Application crashes, work around OR bug, data corrupted/lost, no work around
Priority 3: bug, no data corrupted/lost, no work around
Priority 4: bug, data corrupted/lost, work around
Priority 5: UI interaction, nuisance, no loss of data or work

This makes prioritizing bugs easy, but there are a lot of times a priority 5 issue, which is usually considered releasable, could be the downfall of an application. Meanwhile there could be a random crashing issue that occurs on one machine that gets fixed first because it is priority 1... not to mention, its so random it takes days to track down (there goes an entire sprint!)

Not only do these make little sense for prioritizing your sprint, they also offer no help when it comes to quantifying the impact of bugs on the teams velocity...

Introducing my new system of bugs:

Rules:
1. All bugs are stories
2. Like other stories, they are prioritized by the client and estimated by the team
3. If a bug appears as a direct result of a story completed in the sprint, it is added to the sprint and impacts velocity
4. Every sprint there is a small timebox to fixing/investigating bugs that the client hasn't included in the sprint (this doesn't affect velocity and the sprint should be planned accordingly)
5. Although the client prioritizes the backlog, the developers should feel confident about their codebase and may request bugs get fixed ahead of higher priority stories

What do you think?

The main idea is that bugs, like anything else, need to be user facing and should impact your velocity and sprint planning.

Like some other things, bugs happen :)

Tuesday, March 13, 2007

xkcd

Robert recently posted about a web comic he found and I love it!
Some of my favorites:
fun with resistors
sometimes math is useless
pair tactics

Thanks Robert!!

Monday, March 12, 2007

Continuous Integration, revisited...

Sorry for the delay... I was sick with a broken dev machine, and without our source tree for reference, my knowledge on the subject is, well, not quite there...

Oxygen was setup for continuous integration before I started, so I know the "how" it works, but not the "why."

Before I started, I never had continuous integration setup (wow, I didn't know what I was missing!), so I don't know if my previous organizing methods would have worked so well... (even if I did really like them)

On to the point...

We use subversion for source control and have a build server running CruiseControl. We try to keep the build machine clean, so we're confident we have the project dependencies under control. The build machine does not even have Visual Studio installed -- just the .NET SDK so our projects can be built on the command line.

As for the development tree, its pretty simple:

1. Project Root
a. lib (Oxygen libraries)
b. tools (3rd party libraries) -- references like mbunit or rhinomocks and tools needed to build (like nant, msbuild...)
c. src (project source code)

There are some other folders in the root, but they are specific to the project, like documents or media... All references are to assemblies in lib or tools, never the GAC, this minimizes dependencies that need to be installed on the build server.

The only other file of note in the project root is our build file, which is a NAnt script. This script has several targets, like compile, unit-test, setup-dev-environment, install, cruiseconrol, etc (such a pain to write, but well worth the effort!) The cruisecontrol target, compiles, runs tests, builds installers, deploys installers, runs metrics, sends us result emails and has our bunny tell us updates.

So, "D", I hope this satisfies your curiosity about our development tree! If you have more specific questions, please let me know :)

Wednesday, March 7, 2007

Sprint Planning

At the end of every sprint review, we have our sprint planning meeting... This is our most painful meeting. We've done a lot to mitigate the suffering and the pain has lessened in return. However, our process, like any, is not without flaws and some planning sessions just plain suck.

During sprint planning we review the user stories in our backlog. For our enterprise projects, Salim, our SCRUM master, keeps track of the stories and priorities and the rest of the developers usually know whats going on too. For the new product development our client proxy, Ilio, manages the backlog, which is always well thought out and organized.

Before the review, the developer's knowledge of the stories is anywhere from nothing to very familiar. The more unfamiliar we are with the stories, the more painful our meeting.

Makes sense, because unfamiliarity and uncertainty go very well together, and uncertainty, while unavoidable, makes for long conversations and design talk. Too many unknowns during one sprint review makes us desperate to end the meeting.

The meeting is suppose to go like this:
1. Salim reads a story card
2. On the count of 3 we hold up an estimation card (very easy, easy, medium, hard, very hard and unknown)
3. Salim writes down the estimation
4. repeat

This process repeats until we've estimated more than an iteration of work.

Seems pretty simple, right?

Except, it only happens that smoothly when:
1. The story and solutions are well known
2. Everyone is focused

Sometimes the process is more like this:
1. Salim reads the story card
2. Ilio is asked to explain what it means
3. Ilio explains the story
4. Someone disagrees with Ilio about some behavior on the card
5. Ilio explains the logic again (he's so calm its amazing) and if necessary goes to Bob, our user interaction guru
6. Salim asks if people are ready to estimate
7. Someone answers, "what story are we doing?"
8. The card is re-read
9. On the count of 3 we hold up an estimation card
10. There are only 2 estimations that match, the others range from easy to question
11. The highest estimation explains their reasoning
12. The lowest estimation explains theirs (unless they changed their minds)
13. Salim asks if we want to re-estimate
14. On the count of 3 we hold up an estimation card
15. Kris or Luke make a final decision if we don't agree
16. Salim writes down the estimation
17. repeat

That took a lot longer to read, no? Believe me it makes the meeting take a lot longer too!

Does this make you think we're disfunctional? I think we'd be disfuctional if it always went perfectly... That may sound odd, but its conversations like these that bring interesting design discussions, find issues we missed, discuss user interactions we don't like, etc. These are important conversations to have.

When planning gets filled with unknown stories, we'll have 15 minute meetings each day to discuss stories for the next sprint. This helps, but is difficult too, because its another meeting to fit in during non-war room hours and there is very little time as it is...

I think we all decided that we'd rather have one long day of meetings (which we're having anyway) and a slightly more painful sprint planning than think about sprint planning every day of the week.

At the end of it all, we just want to code :)

Tuesday, March 6, 2007

Development tress and continuous integration...

Oksana, who doesn't have a blog to answer this on her own, is very disappointed I have not responded to the comment asking how we setup our development tree for continuous integration...

Well, its war room hours and I haven't had a chance to respond, so this post serves as a reminder, that yes Oksana, I will respond... back to coding :)

InternalsVisibleTo

At the chat on mocks, I mentioned you can test "internal" methods in your test fixture even if it isn't in the same assembly as the class under test (CUT). I used the wrong terminology (of course) and called it making the assembly friends, so if you spent the last few days googling that, my appologies :P

Testing internal methods comes in handy quite a bit:
1. Testing things that you don't want other assemblies accessing
2. Testing state machines or some other context of a class that you wouldn't otherwise expose
3. Using partial mocks

So, how do you let your test assembly access you internal methods?

Its quite easy, first you'll need your test assembly to have a strong name. Once thats done, you need to add one line to your CUT's AssemblyInfo.cs file.

[assembly: InternalsVisibleTo("TestAssembly, PublicKey=yourpublickey")]

For those of you used to 2003, you give your assemblies key files in the properties of the project and not in the assembly info :)

Saturday, March 3, 2007

Failing at TDD

Someone asked for more clarification about how I failed at TDD... I gave reasons why I failed, but no measurement of success. In the class, I had said that I failed until I finally changed my way of thinking and actually got what test driving is all about...

But I was thinking about this statement on the way home and this isn't true. Even after I understood how to test, my classes under test would outgrow their test fixtures because I wasn't in the habit of writing tests first or the tests were too rigid to change or I just wanted to get something to work really quick without having to write a test... a little extra code here and there eventually leads to a lot of failing tests, ignored tests, ignored assemblies and then total failure...

A few years ago I was lucky enough to have lunch with Bob Martin and we had a long talk about discipline. I would argue that this is the most important attribute for test development (he really knew what he was talking about, how little I knew then).

I finally considered myself successful in TDD when I had several projects that were test driven, and continued to evolve test driven as well... i.e. I was finally successful when my tests were refactored with the rest of my code, my tests continued to drive change and it wasn't painful.

Hope you had fun at code camp



For everyone who sat in on our talks at code camp, thanks for being a great audience. I'll post some notes, answers to questions and code samples in the near future.

We hope you had fun and maybe learned a thing or two :)

Thursday, March 1, 2007

Killswitch Engaged tonight!

I've been looking forward to this for the past two months! I haven't been excited for a concert in a while, so its nice to have the teenage excitement of seeing one of your favorite bands :)

The show comes during a tough week because I'm still adjusting to my training schedule for team in training and Oksana and I have been working late for our Code Camp presentations. I'm still looking forward to it though!