Showing posts with label scrum. Show all posts
Showing posts with label scrum. Show all posts

Saturday, July 18, 2015

Design and Architecture in an Agile Environment




I have worked in several "scrum-like" agile environments over the years. I say scrum-like because each adopted some of the principles, but was unable to embrace all. In almost every case the biggest casualty tended to be an inability to totally isolate the development team from shifting priorities in the middle of a scrum. This is a difficult problem to address, particularly when working with exceptionally demanding customers, and perhaps a topic for another day. Another possible discussion item is whether or not "partial-scrum" is scrum at all.

One of the industry trends with agile environments is to tradeoff up-front design and architecture for an "emergent design" iterative environment where coding starts immediately. However, I would argue that agile does not, and should not, imply that there is no up-front design. Iterative development does not mean that you should rewrite the entire system in every iteration. Nor could anyone reasonably argue that this is an efficient use of the team's time. Yet, if you jump into implementation without any design the chances of "coding into a corner" greatly increases, potentially producing exactly this type of situation.

So we shouldn't give up design and up-front thought any more than we should give up good coding standards. Fast development does not have to equal reckless development. A technique I have used in some organizations is to have one or two senior developers/architects sign up for design and architectural tasks as deliverables for the sprint. These deliverables can be tracked much like any other deliverable, and are as integral to the sprint's success as code and QA deliverables. The end-result should be a light design in some electronic format, with buyin from the team and stakeholders.

The only real disconnect with the scrum process of adopting this technique is that typically the one-or-two people working on this task have a different focus from the rest of the team. This work is synergistic, however, as it results in a better definition of development backlog tasks for subsequent sprints. From this perspective, the team performing these tasks could be their own scrum, but often this is not practical because of how small the team is (could be one member) and because the members will often also take other tasks from the ongoing development sprint.

Another approach that I have seen work is to break up chains of sprints with planned one-or-two week intervals for the team to do design and architecture of  backlog items and cleanup work from prior sprints as needed. Whether this work is considered a sprint or not is up to the team, but I have found that occasional "unstructured" time is also useful for a team.

"Does design and architecture play a role in scrum? If so, what techniques have you seen work and which have you seen not work?"

Saturday, June 27, 2015

Balancing Performance with Code Readability

Image result for balance

This is a topic much discussed in the industry and the position I take is a common one: Code first for readability and support, refactor for performance as necessary. There are notable exceptions to the wisdom of taking a readability-first approach. In general you will know if your code is one of these exceptions. It could be graphics-intensive operations, operations widely used and distributed in libraries, and similar situations where you know critical paths through the code a priori. For the 90% case, where squeaking out every nanosecond of performance is not critical I like to use the following steps:
  1. Write code to be as readable and supportable as possible
  2. Validate that the performance is acceptable
  3. If performance is not acceptable, profile to find the hot spots
  4. Identify techniques for improving performance of these hot spots
  5. Using the Strategy Pattern
    1. Extract each module to  be refactored into a separate component and introduce a simple factory to serve up the existing implementation
    2. Introduce a higher performing implementation and update the factory to use this new strategy
    3. Add comments as necessary to the new strategy implementation
The factory gives us much more flexibility. It allows us to restore the original strategy if we later find that we really don't gain enough overall performance to warrant the new version. It also allows us to experiment with different strategies for improving the performance before deciding on one.

I am of the school of thought that a lot of comments in code is a design smell that the code wasn't as well thought out and decomposed as it should be. I think that most code should be written to be self-documenting with appropriately named methods with small scope. There are certain exceptions to this. Writing for performance is a common way of adding unintentional complexity. Often this added complexity is unavoidable. We should add sufficient comments to explain the code and the reasoning behind the extra complexity so that someone further down the road does not reverse our decisions (perhaps for readability) without understanding the implications of that reversal.

Next week I will push into a use-case where I opted for readability over performance in conflict with published performance recommendations from the platform vendor.