SportsForge
Added by Ted Husted, last edited by Ted Husted on Oct 16, 2006  (view change)
Labels: 
(None)


The SportsForge application follows a number of stylistic conventions designed to make the system easier to create and maintain.

Since the SportsForge development group is responsible for both the database system and the application source code, the conventions are designed to apply equally to both subsystems.

Mechanical Coding Conventions

Souce code mechanics, such as where to place the brackets, are left to the current defaults of the IDEA by JetBrains.

Naming Conventions

Conventions are chosen on the basis of simplicity and pragmatism, moderated by compatibility with external systems. In the event of a tie, simplicity and pragmatism trump external systems. The Sun and RogueWave conventions are used as a starting point and exceptions noted.

Database

The database is considered the one-true model of the application's problem domain.

Database Table Names

  • All lower case, singular voice. The set of "person" entities is stored in the "person" table.
    • Some workers use plural table names, but creating a plural table name does not add semantic value and clouds the relationship between the table and the primary entity represented by a table.
    • If the database is represented in a transfer format, like XML, it is suggested that person elements be encapsulated in a person-set element.

Database Field Names

  • All lower case. If multiple words are needed, words are separated by an underscore. With the exception of the primary key ID and NAME columns (infra), all field names should be unique between all tables.
    • Unique column names simplify query writing and table refactoring.
    • Common field types, like "memo", can be prefixed with the table name to create a unique column identifier.

Primary Key Column

  • Each table includes a primary key as the first column under the common name "id".
    • The term "key" would have been preferred, but it may be a reserved word in some database systems.

Foreign Key Column

  • A column that references a primary key column is named by the table name suffixed with "_id".
    (* The column "user_id" equates to "user.key", e.g. the "id" field in the user table.
  • To avoid confusion, the "_id" suffix should not otherwise be used in a field name.
    • A likely alternative for some type of ID in a problem domain is "code".

Primary Key Name

  • A table will often include a "name" column with a human-friendly business name for the row, or the entity represented by the row. Since a "name" column is such a common use case, and since it is often used in user interface menu lists, a "name" column is an exception to the unique column identifier convention.

Application Source Code

The role of the application source code is to expose the database model and add value through the user interface.

Symbolic Constants

  • Constants that represent String values should be in lower or initial case, especially if the constant refers to a property or a symbol used in an XML file.
    • String values are most often lower case, and retyping or editing the constant from lower to upper case wastes time and increases the potential for error.
    • If the constant represents "success", then it is simplest that the constant is rendered as success.
  • Constants representing numeric values should be in UPPER CASE.

Application Property Names

  • Application fields names which represent database field names should utilize the same style and conventions as the database, including the use of lower case and underscores.
    • If the database field is "first_name", then the application should expose getFirst_name() and setFirst_name(value) as the property methods.
    • The underscore does not violate JavaBean conventions.

Generic Package Names

  • Since the members in our "actions" and "services" packages won't be shared, we use short, generic package names, rather than something verbose like org.sf.net.sportsforge.
    • Verbosity != value.

Data Transfer Objects

  • Data Transfer Objects are a normalized view of the fields used by a page or set of related pages.
    • (Note that DTOs contain only data and are not Data Access Objects.)
  • To avoid redundant coding, a minimum number of DTOs are used by the application, preferably one.
  • The DTO exposes values via property methods as well as a Map. By storing data transfer properties in a Map, we are able to access each by name as well as by property, without reflection.
  • For services, a field map is useful since we can return the service in the Data class,storing the result by query id.
  • For persistance, a field map permits a bulk transfer of properties from another source.
  • For testing, a field map simplifies assertions, since we can loop through the Map to test the fields.

Services

  • Business rule and data access utilities needed by the application are provided by finely-grained, strategic services.
  • Each service represents a discrete transaction or even a unit of work.
  • Each service accepts a data transfer object as input. Output is returned through the same data transfer object.
  • Unit of work services may be chained together to create a script or transaction.
  • Services are implemented as Spring objects. Most Services derive from a base object representing a common strategy.
  • All data access services share a common base object that exposes the SQL mapper.
  • The difference between many data access services may be which database statement is used. Statements are named with a prefix and suffix, like "story_save". Common strategies are applied by changing the prefix ("Story") and using the same set of suffixes ("Insert", "Update").

Service Names

  • Services are virtual or actual classes, and so Service Names follow the class naming conventions (camel case).
  • Other naming conventions lead to incompatibility with Spring or the Spring/Struts intetgration.

action URIs

  • All action URIs utlimately map to an Action class, and start by follow class naming conventions. Some action URIs map to methods. The obvious convention for invoking a method would be a ".", but that character is already overloaded. Instead the "_" (underscore) is used to separate an Action class name from the method to invoke on that class.

Action names

  • Most actions are implemented using a handful of wildcard mappings.
  • For actions that invoke the default service, the "*_" mapping applies. These actions share a a common ServiceAction. When this action is invoked, a Service matching the action name is passed the data transfer object.
    • Validation maps to "ServiceAction-{1}-validation.xml", and success maps to a {1} page. (StorySave.action -> StorySave.jsp).
  • For actions that invoke an alternate method, the "*_*" wildcard applies, and a nominal outcome maps to the "{1}_{2}" page. (StorySave_input.action -> StorySave_input.jsp).
  • For actions that do not utilize a service, the "*" wildcard applies. (Welcome -> Welcome.jsp).

Page Names

  • Pages follow the same conventions as action URIs, the exception being that the "*_" URI maps to the "{1}" page (without the trailing underscore).
  • Using the same default action with or without a service is discouraged. The URIs "Welcome" and "Welcome_" should not be used in the same application.

Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators