Apprenticeship month one report

Posted by Paul Pagel Tue, 01 Jul 2008 01:14:00 GMT

8th Light has an apprenticeship program whereby an 8th Light craftsman will mentor an individual for three months. During that time, the craftsperson becomes responsible for a single apprentice. I am one month into a mentorship with an apprentice. This blog is about observations I have made about myself as a mentor.

Curiosity

He asks me questions that I wouldn’t ask myself. I had him do an exercise about Law of Demeter , to find Law of Demeter violations in my code base. He found something like:

Law of Demeter

“Ted Williams”.to_s.strip.upcase

He was counting the periods, which is what I explained is often good measurement of Law of Demeter violations. Yet this is not a Law of Demeter violation. Each one of those methods returns itself (a string) in a changed state. It is not a string of implementation details- this example is just changing a single object. The pivotal piece of information is that all of these methods on string return the string itself. Also, is anything inside of Ruby core language capable of Law of Demeter? It is unlikely to change, and is there a problem being coupled tightly to your language?

I sometimes get desensitized to the original premises of good development. When I first learn something, I remember the example of the rule more than the value of the rule. The value of learning about Demeter is rooted in encapsulating logic in such a way to hide implementations from an object’s clients. When I first learned about Demeter, all I could do was point out violations. The more I developed, the more it was internalized as a guide for a higher development idea. I want to keep my modules as decoupled as possible. However, that notion only came with development experience. Now I don’t think in terms of violations or non-violations of Demeter when I read a piece of code. It is just ingrained in my developmental context that I should develop my modules in such a way that they are autonomous. This weeds out most Law of Demeter violations by itself. Bringing these premises back up in my development as a craftsman gets my curiosity started. Like a good song or piece of writing, every time I come back to it, I take something different from it, because I am in a state of constant change.

Teaching

Sometimes I forget how important teaching is to the craftsmanship model, because I am still an extreme novice at it. It is one of the steps involved with internalizing development skills. When I pair with my mentor, I am constantly amazed at how he skips steps in the development rational process. Instead of following a linear thought pattern to a solution, it seems there is a giant shortcut in the rational processes I go through. That gap is a lookup table of solutions in his head. It appears so easy and effortless. Teaching is part of a formula that has given him a development context that is superior to mine. The more I am able to teach, the more I internalize the ideas about development.

There is a baseball story from about a year ago. Greg Maddux was warming up before a game and his catcher exclaimed to the pitching coach, “I bet I could catch him with my eyes closed.” Well, after much effort, they convinced Maddux to give it a shot. The catcher was going to call his pitch, then close his eyes. When the ball was about to hit his mitt, the pitching coach with his eyes open was going to yell “now”, whereupon the catcher would squeeze his glove on the ball. Well, on the third try, the catcher caught the ball. The degree of difficulty of the exercise is incredible, but Greg Maddux had spent so many years internalizing the mechanics of his craft that he could effortlessly hit the catcher’s mitt. There probably are only a few pitchers in the long history of baseball who could match that exercise. I am not anywhere near that kind of skill in development, but that is my goal. When you get the mechanics of your craft to be intuition, it frees your mind to think about and solve larger problems. I have been fortunate to spend time with enough great developers to see this mastery in action.

Communication

For me, what is special about teaching is the commitment of thoughts to sound. Forcing something outside of my internal monologue always changes it, even if it is a small change. When I explain something, I often have to explain it multiple ways (this is telling of my communication skills, not of my apprentice’s learning skills). So, the more I am forced to answer questions on the spot, the better I get at quickly thinking through a question and giving a good answer. This dialogue is another one of the mental exercises which translates into my everyday development. It makes me a better pair programmer, better presenter, and better writer. Being able to accurately explain a problem and a solution using the language of software development is a very important tool in being a successful craftsman, and a tool that I fight uphill to improve upon. When I go to a talk at a conference and the presenter hits the problem and solution perfectly, it is a wonderful experience. The same is true when a team member can explain a solution in such intuitive terms that everyone gets it immediately.

Apprenticeship for me is as much about internalizing and expanding my own skill set as it is about expanding my apprentice’s.

Developing against web browser navigation

Posted by Paul Pagel Fri, 27 Jun 2008 15:07:00 GMT

I find while writing web applications that I end up redefining what it means to go “back.” This means where I want the user to go when they hit the back button. The creation of AJAX has killed the behavior of the navigation buttons in the browser. The navigation buttons on a browser are from the time of sundials and static web pages. We live in the world of atomic watches and dynamic content. I don’t want you to go back to the last static web page that was loaded. More times than not, that messes up the user’s experience.

I have seen/implemented some solutions. One that we have used is when the first page is served up you start some kind of memory. Start a stack of the user’s actions, saving them in the session. When the user tries to go back to the main page, they are redirected to the real last page they were at. This is good for AJAX intensive applications. These days I am finding the percentage of AJAX requests is many times higher than AJAX requests when I am trying to create a rich user experience. The problem is you get into situations where the user really does want to go back to the last domain they are at, but your application, very annoyingly, will not let them leave. As a user of the internet, I quickly learned that if I hit the back button many times quick enough, the page doesn’t have time to render the redirect, and I can get back. The fact I even know that is annoying, let alone what it takes away from my application.

Another solution is to have lots of static pages. Don’t let the user get too far without loading a new page. This way the back button can really only do minimal damage. Use lots of client side JavaScript and limit the amount of AJAX calls to the bare minimum. This has become industry standard for web pages which involve payment processing. Since the developers can’t guarantee that a user won’t hit the back refresh / or forward buttons, you have to be able to have some kind of state recovery. If the distance between static pages is short, then you don’t do too much damage. However, this constraint limits what you can do with your web application, limiting AJAX calls.

My favorite solution is to take the browsers out back and teach them about feature envy. They are telling me to serve HTML/JavaScript/Flash content inside their main pane architecture, and they will take care of the rest. Well then, keep your hands to yourself!!! Navigating between web applications(domains) makes sense at some high level, because that is in the job of a web browser. They get you from one web application to another. However, inside of my web application, let me decide what I want the back button to do. I understand some kind of backwards compatibility so the Geocities web page with the contra code on it doesn’t get lost (like we don’t all have it memorized). So, let me turn it off for my domain. Give me a JavaScript API to say what the back button behavior should be or let me at least turn it off. There are some attempts to do just this, but they are not straightforward or part of the core library.

So, this will require all developers of web applications to implement navigation that makes sense within their web applications. Great!!! If they are worried at all about user experience, they have already thought about this and have some solution in place. Getting rid of the back button just gives them more power. I have never met a developer who wouldn’t embrace more freedom in their tools.

Some Thoughts On Software Defects 2

Posted by Paul Pagel Tue, 24 Jun 2008 06:13:00 GMT

Software defects are a part of software. This is a negative subject, but I don’t want to seem like the software I write is full of defects and bugs. This blog is addressing how I have seen teams turn a roadblock into a success. I have read and heard at conferences about teams who take small failures and create a culture of failure around it. Following are some examples of small failures I have seen and great successes built around them. Sometimes I see small failures as a path to larger positive culture changes.

I think it is safe to say all software that is used and sufficiently complex has defects. There are many reasons for the defects. Here are a few of the defect situations I have been in and how our team solved them.

I think the important part I learned after evaluating these is that resolution of these situation needs to be fast and high quality. They need to make the project better off at the end of their resolution. Success for the customer is the only true result of a project, and defects may not be the most ideal path, but they must lead there.

The speed is important, but it doesn’t mean I should rush a solution and throw it in as soon as possible. To me it means giving the defect the red carpet treatment. I am trying to capture craftsmanship in the face of adversity. Every project has its ups and its downs, and a craftsman will take pride in success through any obstacles. Instead of making defects a slippery slope downhill, they are one step back and we take two steps forward.

Bugs

Bugs are a part of every piece of software I have written. That statement sounds a lot worse than it is. I have worked on systems where the requirements are dramatically changed week to week (which can be pretty exciting). There are situations I didn’t take into account, or some behavior I didn’t imagine until a real user started hitting the system. Now, as a developer, I do more mental exercises and think thoroughly through my solutions as I get more experience. This has never made my code bug free. For that reason, my team needs to know how to deal with bugs (I am fairly certain I am not the only creator of bugs).

Here is a line from the Pragmatic Programmer book, “It doesn’t matter whether the bug is your fault or someone else’s. It is still your problem.”

So, the team has a bug list. We list out the bugs as a todo list in basecamp, so they are not so formal they can be forgotten about. Then we try to address them and work on new stories. This worked well enough until there was a big release coming up and our customer came back to us with a big list of bugs. We put them on the list and continued to fix them, as well as work on stories. They were getting completed, but there was never an empty bug list. Then, the customer (who can directly add/edit the bug list) started writing priorities to the bugs. This one is HIGH priority. This one is CRITICAL. This one is IMMEDIATE. I make the suggestion “We need some real tool to manage our bug list,” because I can’t fit all this in my head. There isn’t that much room up there and I need to use it wisely. One of my team members suggested maybe it wasn’t the craftsmanship way to have ANY bugs shipped. I was trying to solve the wrong end of the equation. So, the team lead put forth a no bugs policy that we all agreed with.

You can not pick up a new story unless the bug list is empty.

This made sense to me, but I had reservations about a small/insignificant bug taking priority over a story that is important. To date, this has not happened, and the bug list has stayed near no bugs. That doesn’t mean less bugs are found, it just means they are fixed, and the code is refactored to prevent a future occurrence. Most importantly, some tool to track bugs never made it into our system. That was an idea which would have desensitized the team mentality to bugs, whereas with our policy now we are very sensitive to the issue of bugs. Challenging the craftsmanship of the team members that buggy code is something you should take personally was the right choice. Bugs got a first class ticket to termination in our system.

Now, the definition of a bug versus a small feature enhancement is a fine line. I know I have failed to define it well, and that might contribute to what gets called a “bug”. Often times, the urgency in the customer takes up more mental space than me thinking through it, looking up the acceptance criteria for the story where it was implemented, and going back to the customer and saying, “No, that was clearly not a defined scenario, we are going to need a story to turn that button green.” Now the next time, it is more than turning a button green, but the precedent has already been set. All I have been able to do is to strike a balance based upon how much effort it would take to make the bug/feature enhancement work. If it is a lot of effort, I will double check the bug to make sure it is a bug. If it is, I fix it. If not, I will push back to the customer to write a story card.

Production Support

Once a system goes into production, support begins. Following along with one of Paul Graham’s ideas, we have the developers doing the production support. We are the ones who wrote the system and know the system the best. When I look at a production support request, I can not only solve it, but make sure it doesn’t happen again. Or if it does, make sure it is easy to correct.

So, during our first deployment of a system, a single team member stepped up as the “production support” developer. I don’t know if he embraced it or was cornered to it, but as a craftsman, he took the responsibility and ran with it. As further systems were released, he would sometimes be doing an entire day of production support. Production support can be a lot of debugging and fixing data, which can be fun, but more times than not is tedious and rhythmic. Often times when I saw a production support email, I would look to the “production support guy,” who could fix it in about half the time I could. This seems a lot like a silo to me. Everyone should be able to do production support on any system. I should have to, because it is a perspective of the system that is important to have.

In response to this, we came up with a system of triage. Each day of the week is assigned to a specific developer. If a support item comes up, it is the job of the triage developer to respond to the client/customer we are working on it. If it addressed to a specific person, they will inform them. Otherwise it is on the triage developer’s shoulders to fix the support request before they continue their work for the day. This ensures the client always has an open line of communication with a developer. An email never slips through and doesn’t get addressed. There is clear responsibility to who should be addressing the support item. I know the “production support” developer is in favor of this system. As well as the customer, they ask who the triage is for the day and have no qualms about interrupting their work, as they should.

Communication and Managing Expectations

Recently, I did some integration work with a third party vendor. They were developing their side of the integration at the same time as us. Not wanting to slow development and wait for their functionality, we decided to write a mock server and integrate with the host according to the spec from the third party vendor. We received a story from the customer for that and proceeded to make the client for the third party system calls. We finished our story. In the demo portion of the iteration planning meeting, we could only demo against our mock server. This caused some nervousness in the customer (rightly so). I replied, “Once their side of the system is done, we should be able to send our calls across.” Then we received three more similar stories, but different system calls. We did them, removed the duplication and felt really good about the job we did. The came their test server.

Nothing worked! There were all sorts of communication problems, questions about who implemented the system to what spec, and political questions. Despite us thinking we were in the right, the stories were signed and the customer said, “Well, you said this would work.” At first, I tried to communicate the reason why it didn’t work, and how we can move forward. We came to spend a lot of time on this, and the team felt the integration should be its own story. The customer pushed back, “Well, you said this would work.” There was some tension, because both sides were right. We didn’t believe it was our fault it didn’t work (neither did the customer), but we told them it would. Rather than let out the righteous indignation I was feeling, one of the team members mentioned.

“We should not have assured you it would work.”

That one line brought the real problem to the front for both sides. We didn’t know whether it would work or not, just that we wrote the right code to the specification we had at the time. That code by itself has no value to the customer without it working, though. Once that line was said, everyone in the room sat for a second, then understood. The expectation over defect versus behavior was out of sync. A little ownership over the defect was all we needed to ease the tension and move forward. It is unproductive to get stuck in a stalemate of expectations. When in doubt, the customer is always right.

Older posts: 1 2 3 4