Design Concepts for PCGen

From PCGen Wiki
Revision as of 00:56, 5 April 2009 by Tom Parker (talk | contribs) (New page: {| align="right" | __TOC__ |} ==Functional Requirements== The following functional requirements are provided for use in understanding the basis for the PCGen architecture. Functional...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Functional Requirements

The following functional requirements are provided for use in understanding the basis for the PCGen architecture. Functional requirements are constraints on features as they appear to a user of PCGen.

Compatibility with Previous Versions

A version of PCGen must be fully capable of loading LST data files that were compatible with the previous release. Any tokens that were deprecated in the previous revision may be removed. For example: PCGen 5.16 must be capable of fully loading PCGen 5.14 LST data files. Data from older 5.x releases (in particular PCGen 5.12 and 5.10) may be compatible with PCGen 5.16; however, there are known ambiguities that prevent 100% compatibility with older releases.

With few exceptions, this requirement must be met. Other features of the system (requirements and other good design guidelines) will be sacrificed to meet this requirement. Exceptions to this requirement require unique conversion scripts (which may prompt the user to resolve ambiguity) to be available in the LST Converter.

All tokens deprecated in a given release of PCGen should have automatic conversion using the LST Converter if there is equivalent function in the new version. To remove function from PCGen requires explicit approval from the Content team

Basis: There is a tremendous investment in the PCGen code, data and documentation. This compatibility requirement ensures the ability to leverage that time investment, especially in data and documentation.

Increased Flexibility

Eliminating hard coded values and special cases that currently exist in the PCGen code base will allow PCGen to more easily support non-d20 systems. In addition, increased flexibility will provide for faster feature enhancement, providing additional benefit to users.

Basis: Desire for faster turnover of feature requests, and long-term strategy to expand the PCGen universe to include non-d20 based game systems to increase function for existing users and to attract new users to PCGen.

Structural Requirements

The following structural requirements are provided for use in understanding the basis for the PCGen architecture. Structural requirements are constraints on features as they appear to a developer of PCGen.

Note: It is recognized that some of these items would qualify more as "design" than "architecture", as they are general features or characteristics of well-written software systems. Without any disrespect for software architecture purists, we include a number of those design characteristics, as they help to contrast the current PCGen architecture from architecture of earlier versions of PCGen.

Minimize Process/Structural Models

PCGen should have a minimal set of design structures used to specify the functions required to build a Player Character.

Basis: This minimizes the number of mental models a developer must understand. Reduced quantity of design patterns and structures improves the ability of new (and existing!) developers to understand the code. This also allows greater code reuse and reduces code duplication (which is subject to copy/paste error). Selection of appropriate models will also reduce the number of exceptions in the code, eliminating further risk of bugs and confusion for developers.

Information Hiding

The format of data files on disk should be independent of the processing of a game system or Player Character.

Basis: This insulates the code (modifying a player character or the game system data) from changes in the data file format. This increases the flexibility to add features to PCGen without core changes. This facilitates unit testing by improving component isolation.

Data Encapsulation

There should be defined and limited interfaces between modules of PCGen.

Basis: This improves code maintainability. This truly insulates modules of PCGen from changes elsewhere in the system. This therefore facilitates parallel development. This also improves the ability to unit test the code, as "mock" objects that implement the framework can be used for testing.

Catch Errors Early

Errors in the data files should be caught during data persistence file load, and should not trigger runtime errors.

Basis: Given the Rules Persistence System being independent of the internal data structure, all items will be resolved at Data Load. This will ensure that all objects in a given namespace possess a unique KEY, regardless of the source file. In addition, all object references can be validated to ensure an object that was actually constructed and loaded.

Stable Code Structure

Dependency between packages and classes will result in a Directed Acyclic Graph.

Basis: The PCGen code base is over 2,000 classes. This is a significant code base and requires isoloating subsystems and defining dependencies in order to minimize the impact of code changes. Improved code structure also facilitates testing. Eliminating tangles in Class dependency will improve the ability to write true unit tests (tests that work on a single Class). This means it will be possible to catch smaller errors due to incorrect modifications of the PCGen code base. Improved structure also facilitates understanding of the code by developers. The overall impact of good code structure is seen to both developers and end users as improved speed and ability to modify the PCGen code.

For further information on why this is important, you can read more about granularity at ObjectMentor

Avoid Contracts

Two forms of contracts should be avoided: (1) When a developer makes a code modification, the developer should not be forced to make a matching modification in another location in the code. (2) When a change is made to the internal data structure, a significant amount of "reorganization" to ensure a valid data structure should not be necessary.

Basis: Contracts cause problems because they introduce bugs into software when matching changes are not made. They also make it more difficult for developers to understand the architecture of a system, because they are forced to focus on adhering to the contracts. Data structure contracts can result in invalid data structures, and often lead to performance issues as the data structure is validated and corrected.

Minimize Order Dependency

The number of order dependent operations should be minimized.

Basis: Order dependency can cause significant issues, especially as it is hard to maintain accurate documentation of such restrictions. Operations that are not order dependent can also be parallelized (e.g. on multi-processor systems) to improve performance.