About the author
Rick Hightower is CTO of Mammatus and is an expert on Java and Cloud Computing
Friday, January 31, 2003
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
Wednesday, January 22, 2003
Good Enough
Good Enough vs. Best Technical Solution
I hate purity for the sake of purity. I dogmatically dislike development dogma. Life is full of compromises. OO developments seeks to model real world concepts in life. Development must be full of compromises. How do you convey to fellow developers the need to provide business value as the primary concern? This means that often we have to sacrifice best to good enough. Or rather what is best for the customer instead of what is best for us or the purity of the project. We can always improve a system if it basically meets the customer needs. You can not improve a system if you tried to make it perfect and then the project was cancelled due to lateness. This is not to encourage sloth and sloppiness but to balance good with good enough. The best technical solutions has to be tempered with the technical solutions that is good enough but provides more of the features the customer wants. Timely delivery must be a key factor that is balanced with all of the other factors while never skimping on quality.
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 dictionary.com 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
- When is it Paralysis Analysis?
- 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?
- Ad Hoc vs. RUP or SCRUM or FDD or XP
- 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
- Customer Centric, Stories (Use Cases, Feature Descriptions)
- Simplicity
- Choose simplest thing that will work
- Choose the simplest design, technology, algorithm, technique
- Choose simplest thing that will work
- Feedback
- Small iterations, frequent deliveries
- Pair programming/constant code review
- Continuous integration, automated unit tests
- Small iterations, frequent deliveries
- Courage
- Courage to refactor, estimate, throw away bad code
- Automated testing breeds courage to change code
- Courage to refactor, estimate, throw away bad 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
- Trust, Constructive confrontation, Don’t underestimate peers
Communication
: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
- Software is the primary Goal
- Enabling secondary effort is secondary goal; Use before Reuse
- Business value before elegance
- Enabling secondary effort is secondary goal; Use before Reuse
- Provide Rapid Feedback
- fast feedback = ability to respond;
- allow customers to steer process (if no customers then customer representative, I.e., marketing)
- fast feedback = ability to respond;
- 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
- every problem is simple until proven otherwise
- Make Incremental Changes
- Do a little at a time; biggest bang for the buck:
- Website: refactor most hit pages first
- Do a little at a time; biggest bang for the buck:
- Embrace Change
- Customer changes mind; Customers steer
- Customer changes mind; Customers steer
- Do Quality Work
- Developers Prefer Quality work; Customer steers
- Developers Prefer Quality work; Customer steers
- Travel Light
- Eliminate every process that does not aid in your primary goal
- Minimalist
- Eliminate every process that does not aid in your primary goal
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
- 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).
- Small Release: The smaller the release; the sooner you get the feedback. Feedback is through customer using what you have completed.
- 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.
- 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.
- Continuous Integration: Build, deploy and test in the integration environment often. The build does not work until all of the automated testing passes.
- 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.
- 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.
- 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)
- 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.
- 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.
- 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?
- 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.