We will use decision-records to document OTP development relevant decision. Use the template to describe new decision records.
Leave things BETTER than you found them, clean up code you visit or/and add unit tests. Expect to include some code cleanup as part of all PRs.
Use established terminology from GTFS, NeTEx or the existing OTP code. Make sure the code is easy to read and understand. Follow naming conventions .
Be prepared to provide analyses and/or design documentation if a task is complex, changes the core model and/or the main APIs.
Document the business intention and decisions in the relevant code. Do not repeat the logic expressed in the code. Use JavaDoc, you may have to refactor part of your code to encapsulate the business logic into a method or class to do this.
Document all public
types, methods and fields with JavaDoc. It is ok to document implementation
notes on private
members and as inline comments.
If you decide to NOT follow these decision records, then you must document why.
See also
- Developers-Guide > Code comments.
- Codestyle > Javadoc Guidelines - JavaDoc checklist
Document API and configuration parameters.
OTP uses prettier to format code. For more information on code style see the Codestyle document.
Respect Object-Oriented principals
- Honor encapsulation & Single-responsibility principle
- Abstraction - Use interfaces when a module needs "someone" to play a role
- Inheritance - Inheritances expresses “is-a” and/or “has-a” relationship, do not use it "just" to share data/functionality.
- Use polymorphism and not
instanceof
.
Use dependency injection to wire components. You can use manual DI or Dagger. Put the
wiring code in <module-name>/configure/<Module-name>Module.java
.
OTP will use a dependency injection library or framework to handle object lifecycles (particularly request-scoped vs. singleton scoped) and ensure selective availability of components, services, context, and configuration at their site of use. Systems that operate via imperative Java code (whether hand-written or generated) will be preferred over those operating through reflection or external markup files. See additional background.
Keep modules clean. Consider adding an api
, spi
and mapping code to
isolate the module from the rest of the code. Avoid circular dependencies between modules.
Keep the code DRY - Do not repeat yourself. Avoid implementing the same business rule in two places -> refactor.
All business logic should have unit tests. Keep integration/system tests to a minimum. Add test at the lowest level practical to test the business feature. Prefer unit tests on a method over a class, over a module, over the system. On all non-trivial code, full branch test coverage is preferable. Tests should be designed to genuinely demonstrate correctness or adherence to specifications, not simply inflate line coverage numbers.
Prefer immutable types over mutable. Use builders where appropriate. See Records, POJOs and Builders