As a ICT trainer I have used the following picture a lot of times:
This pictures, borrowed from IBM, is still actual. Today we don't speak about needs, features and use cases, but about big changes, features, requirements and user stories. But the concept is still the same. You have to break down a solution gradually and you have to keep track of your requirements. Sometimes a problem detected during the implementation can be traced back to a high level requirement that has to be adjusted.
The following picture shows how the requirements for the sudoku app have been refined during the development process. Note that most messages in the UML sequence diagrams have become operations in the UML Class diagram.
REQUIREMENTS
|
Additional requirements: F Functionality F001 Import/Load facilities, F002 Usage of colors, F003 Delete functionality U Useability U001 Undo/Redo possibility, U002 Reset possibility, U003 Hint/Autosolve possibility, U004 Desktop/Mobile devices R Reliablility R001 Autosave possibility, R002 24/7 availability P Performance P001 Response within 100ms S Supportability S001 Easy adaptable, S002 Easy extendable
|
|
UC Solve sudoku |
|||||
LoadSudoku |
ApplyLogic |
SetDigit |
SetColor |
CheckSolution |
||
AcceptSingles |
EvaluateRules |
|||||
UpdateSiblings |
EvaluateRule1 |
EvaluateRule2a |
EvaluateRule2b |
EvaluateRule3456 |
||
Hint |
Autosolve |
|||||
DESIGN
MVC |
Autosave |
Undo/Redo |
IMPLEMENTATION
Code example:
Board.prototype.autoSolve = function (loc, digit) {// empty Location allowed
var isSolved = false;
if (!loc.isEmpty()) { // assign a digit to a location if provided
var cell = this.getCell(loc);
if (!cell.hasCandidate(digit))
throw "Internal error.";
cell.setDigit(digit);
this.updateSiblings(loc, SibType.Row, digit);
this.updateSiblings(loc, SibType.Col, digit);
this.updateSiblings(loc, SibType.Box, digit);
}
while (true) {
this.evaluateRules();
if (!this.acceptSingles()) // keep doing deterministic answers
break;
}
if (this.isSolved())
isSolved = true;
else {
var locChoice = this.findCellWithFewestCandidates();
if (!locChoice.isEmpty()) {
var cell = this.getCell(locChoice);
var Candidates = cell.getCandidatesArray();
for (var i = 0; i < Candidates.length; i++) {
var val = Candidates[i];
var newBoard = this.clone();
if (newBoard.autoSolve(locChoice, val) == true) {
newBoard.copyTo(this);
isSolved = true;
break;
}
}
}
}
return isSolved
};
As you can see this code results from the UML sequence diagram "AutoSolve" .