12 years ago, mid-August
Object Active ‘98
Posted by pbirnie under technology
Here is my summary of the Object Active '98 conference that I attended at the Capetown Waterfront yesterday. The two days were a life changing experience. I as yet have not read Martin's latest book and so do not know how much of this information appears in "UML Distilled’. The problem with this summary is that I simply present the axioms (fundamental assumptions) but to accept them you generally have to think about them and argue about it for a while. I would not like to misquote Martin Fowler or any of the other speakers so treat this as my interpretation. Here goes : Keeping Software Soft. (Keeping software adaptable )
The problem with software is that as the code grows in size and complexity, dependencies appear. These dependencies cause adding a feature to your software to ripple or cascade through the system.
Axiom : "Dependencies make software resistant to change"
Changing Requirements
The customer is always changing his mind. This is a common thread through all software projects and people often act surprised when the customer does this.
Axiom : "Stable software requirements do not exist"
How do we keep software adaptable:
If we can keep our software adaptable, we can adapt to changing requirements. Use object orientation to reduce dependencies and keep the software soft.
Forget about reuse with object orientation. "We must learn use before we can learn reuse".
How do we handle changing requirements ?
The ways of dealing with changing requirements are as follows:
Option 1:
Maximise changes before coding. Spend more time on defining requirements and then use the requirements as a contract which is fixed.
Anyone who believes that requirements can be fixed on a software project is in denial.
Option 2:
Accept the fact that requirements will change and use refactoring to handle these changes.
What is refactoring?
Refactoring is simply restructuring you code in small incremental steps whilst using regressive tests after each change so that bugs are not introduced. If a test fails, the bug can be easily found since it must be somewhere in the last increment's changes.
Axiom : "Tests are the key."
Refactoring eliminates dependencies and allows you software to adapt to changing requirements.
Using this technique, you can spend less time focusing on up front design and simply with small tested 'baby steps' nudge the structure of your code to meet the new requirements - Radical !! Sounds like hacker programming except there is a massive amount of testing with small changes.
Customer - Do I want this feature ?
A key part of a customers decision on whether he wants a feature is getting feedback about how much that feature will cost.
Estimating cost:
With software there are many problems with estimating the costs of a feature:
- New technologies add unknowns
- New technologies have a learning curve
- Efficiency of programmers may vary by a factor of 10
- Productivity decreases as the software increases and dependencies appear
- Testing and integration time is hard to estimate
Axiom: "Estimating the cost of a feature is impossible !"
There are too many unknowns to be able estimate accurately.
Result:
We cannot feedback the cost of a feature to a customer so how can the customer decide if he wants the feature?
UML
Check out Martin's home page at
Martin is not a purist. In fact he says not a day goes by without a impure thought. He started with a history of UML and about how the methodologists each attacked the problems based on their backgrounds. For example Jacobson worked for Erikson and then General Electric. His approach was process focused based on his factory experience.Start of UML
Standardisation was initially seen as a bad thing because the feeling was that this new field of object orientation needed to be explored for some time. There were also a lot of different points of view between the methodologists.
"The difference between a terrorist and methodologist is that you can negotiate with a terrorist."
Booch and Rumbaugh both working for Rational was the starting point of UML. Two gurus together started standardisation. Once Jacobson's company was bought out by Rational, panic swept through the methodologist community as they feared ‘standardisation the Microsoft way'.
The three amigos (Booch, Rumbaugh and Jacobson) are sometimes called the three ‘egos’. The other joke is that : In UML, Grady gave up his clouds and Rumbaugh his balls. (Class clouds and aggregation circles).
The primary way methodologists make their money is from case tool vendors and UML was a opportunity to be able to move models from one tool to the other. This created interesting market opportunities.
Use-Cases
Jacobson wrote 200 pages about use-cases but he never explained how to use them. ( No use-cases of use-cases). As a result everyone uses them differently. The important thing I realised is that a use-case is something that happens in the system and in UML terminology a scenario is one path through this use-case for example all of the error handling paths and the normal path can be shown on a single sequence diagram.
Evolutionary development:
Waterfall project planning is dead.
A statement like "We have just completed level 2 design" is easily fudgable because what does it mean actually? How do we know we have reached it. What happens is that the slips in projects then only appear when integration and testing occur as these are a lot less fudgable and a system must be delivered.
The primary driver of evolutionary development is reducing risk. Focus on being risk driven.
Step 1:
Define a broad business model and key abstractions.
Step 2:
Eliminate new technologies as risks by prototyping. Focus is on "gaining knowledge and not code". The use of prototype GUI interfaces that are shown to the customer is a very bad idea because you will never convince the user that there is still a lot of backend work to be done. Users often have programmed excel macros and do not understand the complexities and dependencies of large software systems. Perception is everything and so even if you are doing a great job on the project, if the user perceives that you are not, that is all that matters.
Only show a GUI 'prototype' when the code behind it is working. Keep GUIies Spartan, complexity adds dependencies.
Step 3:
Define a set of use-cases or features. Each feature should be goal driven. Spell checking is a good example of a feature in a word processor. ( What is the goal here ? ). [There are a lot of fuzzy issues related to what is a use-case, not a use-case or several use-cases. Martin said that he is never sure how to set them up]. A features list is a good starting point and for evolutionary development you need a fair degree of granularity of these features (see why below).
Avoid functional decomposition - OO and functional decomposition are oil and water. Also organising use-cases into a hierarchy is a waste of time. Avoid abstract use-cases - They must be simple so that the user can 'own' them. This way you can ask the user which use-cases he wants in iteration 1 and when you say "we have completed use-case x", he knows what you are talking about.
Step 4:
Break you project plan into say 5 increments (iterations) and allocate use-cases for the first iteration. In order to do this ask yourself and the user what is the simplest possible thing I can deliver? Since we are reducing risk the "worst things first principle must be applied" so if a use-case looks scary, put it in the first iteration. These are the things that are hard to design in later. Also choose use-cases that force the infrastructure out. Evolutionary development is excellent at avoiding the infrastructure trap - (where months are spent developing a infrastructure that is never used).
The duration of the increments should be about 2 weeks to 2 months. The shorter the better because you only remove the risks at the point of closure. The point of closure (End of one of the iterations) is where you can find out if other milestones have been fudged. Each iteration has the standard design and code cycle but testing is done though out the process.
It is very important to keep the milestones for the iterations fixed. Use the principle-"Its not that we don’t have enough time, its just that we have too much to do". Simply move some of the functionality (use-cases) to the next iteration if you start to run out of time.
Testing
I hesitate to use the word testing because the testing he talks about is extremely heavy and is automated. Assertions and design by contact are used as the person codes. Unit tests are developed in parallel with the code and you could have one test class per class.
The question I asked is :
How do you test since there are so many permutations and paths though your code ?
The answer he said is to be risk driven - If you feel there is a risk - test it! Also don’t be shy with you tests, there should a lot of them. Sew lots of seeds( tests) to reap the benefits.
The key factors are that :
- The tests are automated with either a pass or fail result.
- The tests are developed in parallel with or before the code.
- The process of writing the software is one of making small changes to the code, compiling and running the automated test. This doubles development speed because no time is wasted hunting for bugs. The bug is obviously in the last set of changes that were made!
Axiom: "Code is not code unless it comes with test code"
Code without associated unit tests should be rejected.
Design
Use CRC cards. Each class is represented by a card. Walk though the use-cases using cards and picking up the 2 cards from the desk as the 2 classes interact. Discuss alternatives.
Delegate and store responsibilities by writing them on the card. (To me responsibilities are very important when doing a OO design - Once you have allocated responsibilities for a class then everything falls into place. You know if you are polluting a class with the wrong functionality when it is not one of its responsibilities). Its important to capture the interaction of the classes after the meeting, perhaps using interaction diagrams.
Axiom: "Capture alternative solutions and why they were not used."
It always happens that you remember deciding not to do something a certain way but you cant remember why. I think note books with a pros and cons table for each decision are a great way to do this.
Axiom: "Intelligent laziness is a good quality in programmers."
If you design and write for too much future functionality, you end up wasting a lot of time because a lot of it is never used. Rather refactor later.
Documentation
Bear in mind Mark Twains statement - "I am writing you a long letter because I do not have time to write a short one". Summarising data can take a bit longer but massive documents never get read and is impossible to update.
Axiom : Summarise and highlight using UML
Use normal language, keep documentation short enough to be read on sofa in 5 minutes. Always use diagrams. Use technical memos.
Other
Axiom : "Training is not enough - Good training and metoring is essential."
Using a method will not make or break a project.
"You don’t have to have a case tool to use UML. My favorite case tool is a printing white board." - Martin Fowler.
