582334 TDD-ohjelmointimenetelmä ja koodin suunnittelu (5 op), syksy 2009
582334 TDD programming technique and designing code (5 cr), autumn 2009
Separate Exams
This course's separate exams are different from other courses, because it will not be possible to measure the skills learned on this course with just regular exam papers. The separate exams will consist of two parts: a project work and an oral exam.
Project Work: You will need to refactor the source code of a small Java project (about 1000-2000 SLOC) and return the resulting code by email to the teacher. The project work will be rated based on the quality of the resulting code.
Oral Exam: You will need to attend an oral exam (about 45 min) where you will program using TDD. You will implement a small assignment from scratch, while pairing with the teacher. The oral exam will be rated based on how well the TDD process is followed.
You can attend the separate exam by contacting the teacher by email before the date of the separate exam. The dates for the separate exams during the year 2010 are 19.1.2010, 26.3.2010, 15.6.2010 and 26.11.2010. The oral exam will be on the exam date (or soon after it). You can start doing the project work right away (see the assignment below) and it must be returned by email 2 weeks after the exam date. The effort needed to do the project work is comparable to doing all the exercises of this course, so it's best to reserve enough time for it.
Course Material: The material for the separate exam is the same as for the course. This includes the book Clean Code: A Handbook of Agile Software Craftsmanship (some copies are available in the library), the lecture slides, and the articles and videos which are linked on the Course Material pages at the end of each lectures' slides.
To prepare for the exam, it is recommendable to write lots of programs using TDD and refactoring the code to be as clean as possible. Doing the exercises of this course may be useful, in addition to which you should use TDD in your own little projects. Object Calisthenics (also explained here) can be a good exercise for learning OO design and refactoring. Also review and apply the course material on how to write clean code.
Project Work
The assignment is to refactor the source code of Corruption Corrector - a pile of moderately dirty Java code written by a 1st year CS student on the Programming Project course. To find out what the program is about, read its description and tutorial.
Get the source code from http://github.com/orfjackal/ccorr by cloning the Git repository. Always make a commit after completing a refactoring. Then when you return your project work, return the whole version history of your changes, so that it can be seen how the code evolved. With Git this can be done by putting the project's .git
directory into a ZIP file.
Also write down short descriptions of how you improved each of the code design problems which are mentioned below. For example when splitting a class with multiple responsibilities, mention that into which classes each of the responsibilities was moved. This is to make it faster for the reviewer to grade the assignment.
The Project Work Assignment
Note: The scope of the project work and its grading has been changed. Contact the teacher to agree on the scope.
Your assignment is to refactor the code in the net.orfjackal.ccorr
package. The net.orfjackal.ccorr.gui
package does not need to be improved, as long as it's not broken. The ccorr
package has quite good test coverage, so that refactoring can be done safely, but the gui
package has no test coverage. Here are some things that are in general wrong in the current codebase:
- The biggest class is 1100 lines long, and many others are hundreds of lines long. This is a symptom of the classes having too many responsibilities. Refactor the code so that the biggest class is less than 200 lines long, and most of the concrete classes are less than 100 lines long (compare Object Calisthenics).
- The classes have multiple responsibilities. Refactor the code so that each class is focused on doing only one thing, so that the classes will have high cohesion and low coupling (see Single Responsibility Principle and Clean Code chapter 10).
- There are lots of huge methods. Refactor the code so that it will follow the Composed Method pattern and each method will be at a single level of abstraction (see 10 Ways to Improve Your Code and Clean Code chapter 3).
- There are mandated comments and bad variable/method names. Refactor the code so that it will be clear what the code does, even without the comments, and whatever comments remain are the best possible comments (see Clean Code chapter 4).
- The program contains much mutable state. Refactor the code to use mostly immutable objects.
- The program contains dead code and unnecessary complexity. Simplify the program by removing code which is not being used from the GUI.
Here are some specific things that are wrong in individual classes:
ChecksumFile
- Multiple responsibilities: calculating and storing the checksum data, saving and loading it to a file, remembering to which file it was saved, updating the progress monitor
- It is possible to construct an invalid instance (checksums == null)
- It is not immutable
Comparison
- Multiple responsibilites: holding together all objects which are part of this comparison, comparing the ChecksumFiles, calculating the file similarity, saving and loading it to a file, remembering to which file it was saved
- It is possible to construct an invalid instance (by not running the doCompare() method after adding/removing a ChecksumFile)
- The copying of markers in doCompare() would not be needed, if ComparisonItem would be decoupled from ChecksumFile. If only the mark, part index and checksum are stored together, then the same data will work for all ChecksumFiles. Then the "mark mirroring" code could also be removed.
- If the user provides an invalid index to one of the methods, it would be better to fail early by throwing an exception, instead of returning a magic value (null, "", -1).
- Resizing arrays (in addFile() and elsewhere) would not be needed if an ArrayList was used.
- Dead code: comments, removeFile(ChecksumFile) (only removeFile(int) is used), getPossibleCombinations(), createPossibleCombinations()
ComparisonItem
- Multiple responsibilites: remembering the mark, saving and loading it to a file
- Should be decoupled from ChecksumFile - see the Comparison notes above.
- Dead code: caption
CRC
- Multiple responsibilites: knowing the algorithm, using the algorithm
- The constructor should not know about the available algorithms.
- Dead code: not all algorithms are used
FileCombination
- Multiple responsibilites: knowing which bytes to read from which file, writing the combined data to a file, updating the progress monitor
- This class is hard to test in isolation, because it requires files to be created. If the class would operate on streams instead of files, then it would be possible to test it using in-memory data structures.
- If the user provides an invalid index to one of the methods, it would be better to fail early by throwing an exception, instead of returning a magic value (null, "", -1).
- Dead code: counting the checksums
Log
- Would be better replaced with a stardard logging component, for example java.util.logging.Logger
Main
- Does not start the GUI in the event dispatching thread. Should use javax.swing.SwingUtilities.invokeAndWait()
Settings
- Multiple responsibilites: holding all the settings, saving and loading them to a file, an access point for the progress monitor
- Dead code: not all the settings are ever changed
Grading
The oral exam will be graded Pass/Fail. To pass the oral exam, the following points must be obeyed:
- The three rules of TDD are followed.
- The steps in TDD are small, so that the full TDD cycle goes through quickly every couple of minutes.
- The code is kept clean and refactored regularly, always after passing a new test.
- Refactoring is done in small, safe steps, so that the code passes its tests every minute or so.
After passing the oral exam, the project work will determine the final grade for the separate exam, on scale 1-5. You can get a maximum of 25 points from the project work, grade 1 requires 13 points, and grade 5 requires 21 points. The following criteria are used to give points:
- +5 points if over 50% of the concrete classes are less than 100 lines long; and -1 point for every 100 lines or part of 100 lines, that a file which is longer than 200 lines (i.e.
penalty = Math.ceil((lines - 200) / 100.0)
).
- +5 points if every class has a single responsibility; otherwise -1 point for every additional responsibility (see the above list of known multiple responsibilities).
- +5 points if all methods follow the Composed Method pattern; or +2 points if over 50% of the methods are like that.
- +5 points if all names are meaningful (Clean Code chapter 2), the code follows the Stepdown Rule/Newspaper Metaphor (Clean Code pages 37, 77-78), and every remaining comment (if any) adds value which is not achievable with better naming; or +2 points if over 50% of the code is like that.
- +5 points if the code does not have serious code smells or other problems; otherwise -1 point for every remaining problem (see the above list of known problems), including any newly introduced problems (for example unnecessary complexity)
Viimeksi muokattu 01.12.2010 21:05
Copyright © 2009 Esko Luontola