Difference between revisions of "Implementing the class"
Line 1: | Line 1: | ||
− | == Start small == | + | === Start small === |
The most important thing to keep in mind when implementing new functionality is to do it in small sections ... break the task up. You should release little and often so that others can review changes and offer helpful advice early. | The most important thing to keep in mind when implementing new functionality is to do it in small sections ... break the task up. You should release little and often so that others can review changes and offer helpful advice early. | ||
− | === | + | === Pick small groups of methods === |
When implementing a class, you need to start by implementing an initial version of the designated initialiser and the -dealloc method so that you can create and destroy instances of the class. You may want to revise those methods as you implement more of the class, but you can start by implementing very simple versions. | When implementing a class, you need to start by implementing an initial version of the designated initialiser and the -dealloc method so that you can create and destroy instances of the class. You may want to revise those methods as you implement more of the class, but you can start by implementing very simple versions. | ||
Line 17: | Line 17: | ||
Ideally, you should do this '''before''' implementing: | Ideally, you should do this '''before''' implementing: | ||
− | You can write one or more test cases for each method, and if you have access to an OSX system, you can run those test cases there to check that the OSX behaviour | + | You can write one or more test cases for each method, and if you have access to an OSX system, you can run those test cases there to check that the OSX behaviour of the method actually is what you expect. |
If you don't have an OSX system, you can still ask other people to run your testcases for you, and email the results back to you. | If you don't have an OSX system, you can still ask other people to run your testcases for you, and email the results back to you. | ||
+ | It is extremely useful to run test cases before designing how your code will work ... since that can inform your design and avoid wasting time writing code which doesn't match the OSX implementation. | ||
You can add a comment to the header file, before each method you are about to implement. The comment would describe what you think the method should be doing. If you've implemented test cases and tried them on OSX, you will by now '''know''' what the method is supposed to do. | You can add a comment to the header file, before each method you are about to implement. The comment would describe what you think the method should be doing. If you've implemented test cases and tried them on OSX, you will by now '''know''' what the method is supposed to do. |
Latest revision as of 08:22, 13 February 2012
Start small
The most important thing to keep in mind when implementing new functionality is to do it in small sections ... break the task up. You should release little and often so that others can review changes and offer helpful advice early.
Pick small groups of methods
When implementing a class, you need to start by implementing an initial version of the designated initialiser and the -dealloc method so that you can create and destroy instances of the class. You may want to revise those methods as you implement more of the class, but you can start by implementing very simple versions.
Once you can create and destroy instances, it makes sense to implement core methods like -hash, -isEqual:, and -description.
Next you can implement things like -copyWithZone: and -mutableCopyWithZone: (if the class supports copying and perhaps mutable copying), and the -initWithCoder: and -encodeWithCoder: methods if the class supports coding.
Then pick small groups of methods with related functionality to implement, so that you can document and test those methods together.
Document and write test cases as you go
Ideally, you should do this before implementing:
You can write one or more test cases for each method, and if you have access to an OSX system, you can run those test cases there to check that the OSX behaviour of the method actually is what you expect. If you don't have an OSX system, you can still ask other people to run your testcases for you, and email the results back to you. It is extremely useful to run test cases before designing how your code will work ... since that can inform your design and avoid wasting time writing code which doesn't match the OSX implementation.
You can add a comment to the header file, before each method you are about to implement. The comment would describe what you think the method should be doing. If you've implemented test cases and tried them on OSX, you will by now know what the method is supposed to do.
Then, when you actually implement the method for GNUstep, you can run the test case you wrote, and be sure that your code does just what it should.
Let other people know what you've done
If you make each batch of changes available immediately, other people might try them out on other operating systems or different processor architectures. If you have provided test cases in the test suite, people will be able to see if the code behaves the same way on their systems as on yours. Portability issues can be addressed quickly, and problems can be spotted and fixed quickly.
Avoid using new language features
We use #if...#else...#endif to deal with Objective-C language variations ... most people don't use the more recent additions Apple have made to the Objective-C language, and you must assume that the source code will be built by a compiler which doesn't support those features, so you need to have alternatives which will work with other compiler versions.
Avoid system specific code
We always write for portability ... GNUstep has to run on many operating systems and different types of CPU. In particular you need to ensure that any code which uses UNIX system/library functions also has a variant which works under ms-windows.