Friday, January 31, 2003

Definition of a software developer with schedule problems....

Level 1 Schedule starts to slip.... what the hell I'll give up exercise (this is the easiest for me to give up).
Level 2 Schedule starts to slip... I'll give up some sleep... 8 hours a day is a waste of time anyway.
Level 3 Schedule starts to slip... I'll give up taking a full hour lunch... Cheetos and Root Beer is enough.
Level 4 Schedule starts to slip... I'll give up personal grooming... Who has got time for friends anyway.

Everyone knows when you unhealthy, sleep deprived, malnurished that you can develop so much faster. Ugh!

Is it too late to become a fire fighter?

Wednesday, January 29, 2003

David Fraser is one of the smartest developers I have ever worked with.
He can figure stuff out. He tries, tries and tries until he gets it.
He has not met an app server he could not configure. They all bend to his will.

Friday, January 10, 2003

Not so Extreme

What if Extreme Programming was not extreme?

Effective Development Principles and Practices for all Methodologies

What if you could take the key principles and ideas from Extreme Programming and package them so that they could be more applicable to any type of process. As a consultant, I cannot always pick the process that the team has chosen. And, quite often there is a lot of resistance to the idea of Extreme Programming but not the ideas of Extreme Programming (read that again). Often times companies have already picked their process and best practices. Can you impact what is in place without causing massive political disruption? Extreme Programming causes much more resistance then it should. Can you seperate the idea of Extreme Programming from the ideas of Extreme Programming? Can you soften the tone of Extreme Programming so that it is not so "in your face different" than the accepted school of thought?

I think you can. According to a principle is "a basic truth, law, or assumption". Since Extreme Programming is based on principles for effective development, then these basic truths must apply to other methodologies and processes. Let's start by renaming this to Principles and Practices of Effective Developers. Then let's soften it to make it more palatable to people who would otherwise have a natural aversion to Extreme Programming. Since this paper is based on XP principles and for that matter agile programming assume all ideas are really variations of ideas presented by Kent Beck, Scott Ambler, Martin Fowler and the rest.

To begin, let's make the following assumption: The Ultimate goal in any software project is to deliver working software in a timely manner. The software should meet the customer’s needs and expectations (at least their needs).

There are many other ancillary goals to achieve this ultimate goal. In addition to many goals, there are many ways to meet those goals. To meet these goals you need to make some key decisions as follows:

  • "Reckless" coding vs. very disciplined

  • No design vs. Paralysis Analysis
    • When is it Paralysis Analysis?
    • Should all projects be treated equal?
    • Pace Maker Embedded Software vs. Online Catalog

  • Use a Lightweight methodology or heavier weight?
    • Ad Hoc vs. RUP or SCRUM or FDD or XP
    • How do you identify what is heavy weight?

  • Code-centric process vs. Document Centric
  • How much design and documentation is enough?

For example: To what level you will design the project up front. The level of detail you put into the design has a relationship to how much feedback you can get back from your customer, and how catastrophic failure would be. For example, if you are writing embedded software for a pace maker, you cannot expect a trial and error approach. The specification, design and testing will all have to be very rigid. On the other hand, an online catalog is a lot less rigid. Often customers don’t know what they want until they can work with a working version, and you expect several iterations of changes (your process should reflect this).

Notice that the most of the choices above are degrees on a continuim. This is nice since they can be adjusted according the project, management style, corporate culture, etc. How do we adjust these? Are there principles to tell us?

The decisions above are not taken lightly. They are different depending on makeup of your team, corporate culture, and type of project you are working on. It is easy to advoacte a rigid process or methodology, but this will not work. Every methodology has its strengths and weaknesses, and no methodology (unchanged) fits every combination of project, corporate culture and team.

Purists and Evangelist be damned, there is no one size process and methodology that fits every organization, corporate culture and project. However, there are principles, values and practices applicable to all projects and are key to making decisions listed above. At times (as a consultant or even an employee), you do not always have the power to change the companies software process.

Now we agree on the goals. What are the things we value the most to reach those goals. Here are the 5 main values lifted mostly from Kent Beck with one stolen from Scott Ambler:

5 values of an Effective Developer

  • Communication

    • Customer Centric, Stories (Use Cases, Feature Descriptions)
    • Shared Knowledge (Pair Programming), Task Estimation
    • Iteration Planning, Design sessions

  • Simplicity

    • Choose simplest thing that will work
    • Choose the simplest design, technology, algorithm, technique

  • Feedback

    • Small iterations, frequent deliveries
    • Pair programming/constant code review
    • Continuous integration, automated unit tests

  • Courage

    • Courage to refactor, estimate, throw away bad code
    • Automated testing breeds courage to change code

  • Humility

    • Trust, Constructive confrontation, Don’t underestimate peers
    • Value others skills: manager, project manager, customer, marketing
    • Arrogance: “Pointy hair boss”, “Dumb customers”, “Unrealistic Project manager”.
    • Senior vs. Junior; Cowboys okay (white hats only); Respect Individuality and Strengths of team members

It should be no surprise that communication should be valued. Any team larger than one needs effective communication. (Even a team that has one developer is larger than one: the customer makes two.) Let's cover some common forms of communication for an effective developer. Stories (Use Cases, Feature Descriptions, User Stories etc.): Have the customer help with the Stories. User Story become major milestones for completion; they communicate to the team the progress of the project. Customer Centric: Let the customer drive through user stories, iteration planning, feature requirements, etc. Prioritize user stories by doing the ones that provide the most business value first (customer picks). Shared Knowledge (Pair Programming, Knowledge Management): Working together is faster than working alone. Code is not reusable unless others know how to reuse it. Task Estimation: Estimate based on past performance. Be honest and task estimation gets easier as the project progresses. Iteration Planning: Refine Stories and estimate tasks for this iteration: work with the customer to do this. Stories are excellent goals for an iteration. If the story is too big, split into two or more stories. Or if the story can not be split split the story parts into two iterations. Design sessions: Design can be done during implementation if it helps you understand problem domain or during Iteration Planning if it helps plan the iteration. Design helps the team communicate ideas quickly. Design until you can proceed with code. Feedback: Feedback is very important. It is hard to judge where a project is and how much progress you are making without feedback. No feedback is like not having a compass. Small iterations, frequent deliveries: This shows that certain features of the system work, complete with unit tests that pass. Also the sooner the user (or marketing) can provide feedback, the more likely the project will stay on track.

Let it go; Don't be dogmatic

I don't see castrophic differences between Use Case Scenarios as compared to User Stories. Use Case Scenarios are much more detailed and are a bit more organized but the goal is very similar to User Stories. Both are used to break the project into milestones and are used to divide a project up into iterations (one for the Unified Process the other for Extreme Programming). From now on, I will refer to this concept as a User Story. Don't be dogmatic about Extreme Programming, RUP or any methodology. You have a better chance of improving your process gradually then you do by taking a dogmatic stance. For Example saying: "Use Cases suck. It is too complex. Let's just do User Stories" will not do much good in a RUP shop. Nothing can stop progress faster than making such a statement. Prefer gradualism. Most of principles of an Effective Developer can be flown under the radar with full support from management. Focus on gradual improvement not arguing or taking dogmatic stances. I agree that it is not as fun, but it is sure more productive.

7 Principles of an Effective Developer

  1. Software is the primary Goal

    • Enabling secondary effort is secondary goal; Use before Reuse
    • Business value before elegance

  2. Provide Rapid Feedback

    • fast feedback = ability to respond;
    • allow customers to steer process (if no customers then customer representative, I.e., marketing)

  3. Assume Simplicity

    • every problem is simple until proven otherwise
    • != skipping design step; design should focus on current iteration only!
    • counter-intuitive to common thought on software design, reuse
    • Do not abuse technology, frameworks or design patterns

  4. Make Incremental Changes

    • Do a little at a time; biggest bang for the buck:
    • Website: refactor most hit pages first

  5. Embrace Change

    • Customer changes mind; Customers steer

  6. Do Quality Work

    • Developers Prefer Quality work; Customer steers

  7. Travel Light

    • Eliminate every process that does not aid in your primary goal
    • Minimalist

A working system that provides business value is the ultimate goal. The ability to provide more features, extend, and reuse is an important secondary goal: never cloud your primary goal! Don’t add code features until you need them. Don’t apply design patterns until you have to. In fact, the early application of Design Patterns is epedemic in many big design up front shops. This can slow development down to a crawl. (P.S. I believe in the utility of Design Patterns; just not how they get abused.)

Assume simplicity. Do not clutter the architecture with unneeded features. Try the simplest way first. Objects can be replaced. Concentrate on interfaces and collaboration not perfection or purity. The customer does not care if you used the latest buzzword technology or not. Their emphasis is on business value.

Make incremental changes. Avoid sweeping changes in architecture. If changes are needed, focus on providing the most business value. Test the water before diving in.

Complex systems are difficult to specify. Customers don’t know what they really want until they see what they don’t want. Embrace this. Don’t fight it. Let them drive what features are the most important and what gets done first. Projects that are 50% done but are useful to customers are better than projects that are “100% done” but nothing like the customer needs or wants.

Customers hate shoddy work. Developers hate delivering shoddy work. It feels good to deliver a solid system. Nothing breaks morale faster than delivering garbage.

Travel light by eliminating every process and task that does not aid the ultimate goal. Review your process often and improve on it. Evolve it.

12 Practices of an Effective Developer

  1. Planning game: Do iterative development. Finish a story per iteration. If the story is too long, split it up. Try to keep the iterations short. Base task estimation on past experience of similar tasks. Calculate each developers task factor in ideal days. Add a factor for each developers estimation bias. Train developers to get closer and closer to ideal days. Developers should never excluded from planning (otherwise no buy in and no valuable input).

  2. Small Release: The smaller the release; the sooner you get the feedback. Feedback is through customer using what you have completed.

  3. Simple Designs : As simple as the project will allow. Add complexity only when needed through refactoring. Don’t try to guess reusable areas too early. Design until you understand the domain enough to build an iteration. Refine your design each iteration.

  4. Automated Testing : A feature does not exist unless there is a test that proves it works. Try to catch most bugs before they hit QA. Then QA will allow less bugs to filter through to the customer. Every bug found gets a test case that can force it; then it is fixed.

  5. Continuous Integration: Build, deploy and test in the integration environment often. The build does not work until all of the automated testing passes.

  6. Refactoring : When you embrace change, you realize that it is harder to predict what the final set of features will be added or needed (Conversely, what you deliver will be what the customer needs). Thus many architecture decisions can and should be delayed. This delay allows you to write a working system sooner; and allows you to gain additional insight into the problem domain. Since the tests are setup before the code is written, refactoring is facilitated. Refactoring is usually triggered when adding a new feature to the system breaks the systems coherent design, I.e., when the code starts to stink.

  7. Shared Knowledge : It is hard to reuse a piece of code you do not know exists. Sometimes the least effective way to share knowledge is through meetings and documentation. It is often easier to understand how a piece of code works by looking at a unit test case, reading an ad hoc description in WIKI, or pair programming than by looking at API docs. Pair programming is when two developers work on a task together after each task you switch partners. At first glance to many managers, this seems ineffective. However, it saves in duplication of efforts: reinventing the wheel. Less code to invent equates to less code to maintain and a simplified code base. The typical experience with many projects is vast acceleration of efforts and the production of a quality code base. You cannot reuse code if you do not know it exists. You cannot reuse code if you don’t know how to use it. The spread of project knowledge (domain and technology) by pair programming is viral and it is exponetially more effective than meetings. This is the main point folks miss about pair programming. The viral spread of knowledge. The other points about pair programming are secondary in my opinion.

  8. Team Ownership: Team ownership is the teams collective ownership of the project. This allows project flexibility as any developer can be assigned to any piece of the system. This often requires that each developer be versant in many aspect of development, which generally improves morale but puts a heavy burden on the skill sets needed and training. This can be alleviated through shared knowledge: particularly through pair programming. Management should also be willing to train employees. (2 weeks of training per quarter; budgets allowing)

  9. 40-hour week: How effective are you if you work 80 hours in one week? How effective are you if you do this several weeks in a row? What happens with the quality of the project? Occasional sprints are okay. But software development is a marathon race. Go home. Come back refreshed.

  10. On-site customer representative: The customer representative, which can be the customer or marketing or someone else who advocates the customer interests effectively, needs to be active in the project. This is especially the case during the planning game.

  11. Common Vision: You need to cultivate a common vision of the project with your customer. What does the project need to do? What is the vernacular of the domain? Are you using the customer-speak when you design and code the system?

  12. Coding Standard: Variety is the spice of life; except for software development. Agree on a coding standard and enforce it. Be flexible; don’t get into the bracket wars (see humility value). This transcends naming conventions and digs into other metrics, e.g., average lines of code, how to handle exceptions, and the like.

    I am not done yet. But this is a good start an outline of where I want to go.

    Random Thought: If you think pair programming 100% of the time is a waste of resources. How about pair programming 25% or 10%?
    TODO: Discuss XP's design per iteration vs. UP's elaborate design per iteration?

Thursday, January 09, 2003

I find that consultants at times have a hard time mentoring. The goals are a lot different. The mentors goal is to make himself obsolete, i.e., the company he is working for eventually does not need him. The contractors goal is to get more contracts. Contractors have this nasty way of multiplying. This is not to say that contractors are bad. They are not.