Difference between revisions of "Design Concepts for PCGen"
Tom Parker (talk | contribs) (→Structural Requirements) |
Tom Parker (talk | contribs) |
||
Line 66: | Line 66: | ||
<b>Basis:</b> 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. | <b>Basis:</b> 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. | ||
+ | |||
+ | |||
+ | ==Key Design Decisions== | ||
+ | |||
+ | ===Data Persistence Interface=== | ||
+ | |||
+ | The Data Persistence format must be independent of internal data structure. (The internal data structure must not have | ||
+ | knowledge of the data persistence file format) | ||
+ | |||
+ | <b>Underlying Requirement(s):</b> [[Design_Concepts_for_PCGen#Information Hiding|Information Hiding]] | ||
+ | |||
+ | <b>Basis:</b> This abstracts data persistence from the internal data structure. It forces the entire persistence contents to | ||
+ | be parsed on data load. This ensures any errors in data files are caught at data load, rather than at runtime. | ||
+ | |||
+ | ===The Persistence System IO=== | ||
+ | |||
+ | The input and output of data persistence information should be an integral part of the data persistence system. | ||
+ | |||
+ | <b>Underlying Requirement(s):</b> [[Design_Concepts_for_PCGen#Data Encapsulation|Data Encapsulation]], [[Design_Concepts_for_PCGen#Information Hiding|Information Hiding]] | ||
+ | |||
+ | <b>Basis:</b> Adding output to the persistence system provides the ability to reuse the data persistence system in a data | ||
+ | file editor, as well as the runtime system. This sharing of code helps to guarantee the integrity of the data file | ||
+ | editor. Such a structure also facilitates unit testing, as the persistence system can be tested independently of | ||
+ | the core code. | ||
+ | |||
+ | ===Character Persistence Interface=== | ||
+ | |||
+ | The Character Persistence format must be independent of the core code and data structure. (The internal PC data | ||
+ | structure must not have knowledge of the PC persistence file format) | ||
+ | |||
+ | <b>Underlying Requirement(s):</b> [[Design_Concepts_for_PCGen#Information Hiding|Information Hiding]] | ||
+ | |||
+ | <b>Basis:</b> This abstracts character persistence from the internal data structure. This also implies and ensures that | ||
+ | when a character is saved, it can be restored, even independent of the original persistent data being available. | ||
+ | |||
+ | ===Catch Errors Early=== | ||
+ | |||
+ | Errors in the data files should be caught during data file load, and should not trigger runtime errors. | ||
+ | |||
+ | <b>Underlying Requirement(s):</b> [[Design_Concepts_for_PCGen#Information Hiding|Information Hiding]] | ||
+ | |||
+ | <b>Basis:</b> Given data persistence being independent of the internal data structure, all references will be resolved at | ||
+ | load time. This will ensure that all objects in a given namespace possess a unique KEY, regardless of the source file. | ||
+ | Also, all object references can be validated to ensure an object that was actually constructed and loaded. | ||
+ | |||
+ | ===Shared Persistence System with Editor=== | ||
+ | |||
+ | The data persistence system should be usable for both a data file editor and the runtime character generation program. | ||
+ | |||
+ | <b>Underlying Requirement(s):</b> Code Reuse (general design characteristic) | ||
+ | |||
+ | <b>Basis:</b> A significant investment made in ensuring that persistent data is read without errors should be reused across | ||
+ | both a data file editor and the runtime system. This reduces the risk of error, ensures that the editor will always | ||
+ | be up to date (a problem in PCGen 5.x) and provides additional editing capabilities (e.g. edit data in place) that are | ||
+ | not available in PCGen 5.x. |
Revision as of 01:50, 5 April 2009
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.
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.
Key Design Decisions
Data Persistence Interface
The Data Persistence format must be independent of internal data structure. (The internal data structure must not have knowledge of the data persistence file format)
Underlying Requirement(s): Information Hiding
Basis: This abstracts data persistence from the internal data structure. It forces the entire persistence contents to be parsed on data load. This ensures any errors in data files are caught at data load, rather than at runtime.
The Persistence System IO
The input and output of data persistence information should be an integral part of the data persistence system.
Underlying Requirement(s): Data Encapsulation, Information Hiding
Basis: Adding output to the persistence system provides the ability to reuse the data persistence system in a data file editor, as well as the runtime system. This sharing of code helps to guarantee the integrity of the data file editor. Such a structure also facilitates unit testing, as the persistence system can be tested independently of the core code.
Character Persistence Interface
The Character Persistence format must be independent of the core code and data structure. (The internal PC data structure must not have knowledge of the PC persistence file format)
Underlying Requirement(s): Information Hiding
Basis: This abstracts character persistence from the internal data structure. This also implies and ensures that when a character is saved, it can be restored, even independent of the original persistent data being available.
Catch Errors Early
Errors in the data files should be caught during data file load, and should not trigger runtime errors.
Underlying Requirement(s): Information Hiding
Basis: Given data persistence being independent of the internal data structure, all references will be resolved at load time. This will ensure that all objects in a given namespace possess a unique KEY, regardless of the source file. Also, all object references can be validated to ensure an object that was actually constructed and loaded.
The data persistence system should be usable for both a data file editor and the runtime character generation program.
Underlying Requirement(s): Code Reuse (general design characteristic)
Basis: A significant investment made in ensuring that persistent data is read without errors should be reused across both a data file editor and the runtime system. This reduces the risk of error, ensures that the editor will always be up to date (a problem in PCGen 5.x) and provides additional editing capabilities (e.g. edit data in place) that are not available in PCGen 5.x.