Designing the FragmentedBase Class

This page describes the design of the FragmentedBase<T> class template.

Why Do We Need a FragmentedBase Class?

As motivated in Designing the Fragmenting Component, the FragmentedBase<T> class template is introduced to factor shared functionality from FragmentedNuclei, FragmentedMolecule, and FragmentedChemicalSystem.

FragmentedBase Considerations

container

All FragmentedBase<T> objects should satisfy the concept of

supersystem

FragmentedNuclei, FragmentedMolecule, etc. have in common that they contain subsets of a superset. The FragmentedBase<T> factors out the infrastructure for holding the superset and interacting with it.

  • Addendum 5/9/2024. Factoring out the supersystem leads to extra copies when FragmentedMolecule is implemented in terms of FragmentedNuclei. This is because the bases of both FragmentedNuclei and FragmentedMolecule assume they own the supersystem. Accessing the supersystem is still done through the base, but we instead opted for a virtual function to retrieve it from the derived class (this allows FragmentedNuclei to own the Nuclei piece and FragmentedMolecule to own the charge/multiplicity piece).

immutable superset

For the purposes of the super-/sub-set relation we assume that the superset has been fully initialized and will not change.

  • If the superset changes it will invalidate the elements of the entire class hierarchy, which is difficult to recover from.

  • 5/6/2024 addendum. This consideration has been relaxed. Since the FragmentedBase<T> object will own the supersystem it is fragmenting it is conceivable that the user may want to update that supersystem directly rather than needing to copy it out, modify it, and then create a new FragmentedBase<T> (actually a T) object with the new supersystem. This still has the potential to invalidate the class hierarchy, but if the user knows what they’re doing it can still be okay…

null and empty states

The state of FragmentedBase<T> is defined in reference to a supersystem. This raises a conundrum, how can we tell a FragmentedBase<T> with no supersystem (and also no fragments) from one with a supersystem, but no fragments? We opt for distinguishing between null and empty. Null meaning there is no supersystem and empty meaning there is a supersystem, but no fragments.

  • Addendum 5/9/2024. The empty set is a universal constant and have opted for null objects to instead fragment the empty set. An object with a non- empty superset, but no fragments can be distinguished by comparing the supersets.

FragmentedBase Design

../../../_images/fragmented_base.png

Fig. 9 Classes related to the implementation of the FragmentedBase<T> class.

Fig. 9 shows the classes involved in implementing FragmentedBase<T>. To satisfy container, FragmentedBase<T> inherits from utilities::IndexableContainer<T> class. In accordance with supersystem, FragmentedBase<T> contains an object of type U such that U is the class from the chemical system component T fragments.

Summary

container

FragmentedBase<T> inherits from utilities::IndexableContainer<T> to satisfy this consideration.

supersystem

FragmentedBase<T> manages a supersystem object.

immutable superset

Addressed by storing the superset as a read-only object.

null and empty states

The default constructor will fragment an empty set object, whereas the constructor which takes a superset creates an empty object.