|
Although the philosophy may appear obvious to many, it is worth stating in order to make development priorities clear.
Getting code working involves writing it in the first way of providing a solution which seems intuitive. This approach is necessary because of the large amount of code that needs to be written to support complex requirements of working with environmental health studies. At this point, a solution that is intuitive to one developer may not be intuitive to another. Furthermore, the intuitive solution may prove to be inefficient in some way. With so many coding features recurring within the same project or across many projects, common patterns emerge which become well scrutinised by the broader developer community.
Ideally we would use design patterns wherever possible so that other developers who recognise the design motifs can quickly learn what a piece of code does. By making references to design patterns, the development team can refer other developers to other literature which explains how and why a design pattern performs well for a particular context. However, matching a common code need with a standard pattern implementation and then fitting it into the existing code base can be time consuming. The potential benefit of readability here may not justify the work needed to standardise a code fragment. As well, overuse of design patterns can create a case of a tool that is looking for an application.
Although this project has been better funded than many other scientific software projects, we recognise that its character of future development will likely follow the way most tools are developed in an academic setting. Its long term maintenance will likely be characterised by a series of lone developers who code on projects that fund research, not development.
The amount of money available to fund developers will likely remain below market value of seasoned commercial developers and it is likely the future development team will comprise mainly graduate students who may end up doing some other projects. It is also possible that future developers may not have years of experience developing large code bases in general.
It takes skill to design software so that its future maintenance can be de-skilled. De-skilling future development can be done in many ways, but one good way is to use an easily understandable architecture which provides the scaffolding needed to add future enhancements. De-skilling future development involves:
One example of coding to convention is to mark all method parameters in all classes as "final". Some developers advocate adopting this practice to support compiler optimisations, although the benefits seem negligible. Other developers feel the practice adds little value and makes code more cluttered for the effort it takes to write "final" in front of every method parameter.
My reason for using final method parameters is that it allows me to leverage the power of the compiler to spot careless errors I might otherwise overlook when I'm tired. When a piece of calling code calls a method, the actual parameter values the caller passes are copied by reference to the corresponding formal parameters. Once this is done, the formal parameters should not be assigned new values.
Assigning new references to the formal parameters within the body of the method is considered poor practice. But marking method parameters as final increases the chance that this kind of coding mistake can be easily detected.
The likelihood that I would intentionally assign new values to formal parameters is zero. But the likelihood I would make mistakes after a long session of coding may be significant. As well, future developers who do not keep the consequences of making this mistake in mind may encounter problems and not understand the cause of the error.