I have a bunch of modules. I can break these modules into different categories that are complete and do not overlap. For example, three categories, with ids that can be expressed as
Mineral. I further break these categories down into subcategories, which again are distinct, complete and do not overlap. For example, ids that can be expressed as
Gem. Finally, underneath these categories, there are the modules themselves, e.g.
Here are my common use cases:
- I need to call various methods on all modules.
- I need to get flat snapshot of the current state of all data across all modules.
- I need to call various methods on all modules in a particular category (but not subcategory).
- I need to call various methods on a particular specific module based on it's known ID.
- This could be a "do something" or a "tell me some data about yourself"
- I need to store aggregate data about all modules in a particular category (but not subcategory).
How should I store this data?
Some other relevant facts:
- The categories are established in runtime
- As such, the bottom level modules do share a common interface.
- Once they're set up, they don't change in that particular run - they are based on data in configuration files.
Here's what I currently do:
- I have a class that contains a
Map<Category, CategoryDataStructure>. This class also maintains a separate
Collection<Module>view of the data for use with requirement #2.
CategoryDataStructurehas chained delegation methods that send the method call down the chain, via
CategoryDataStructurealso stores the aggregate data used in requirement #5.
It works, but it's honestly quite unwieldy. The whole thing is stateful / mutable and hard to change. If I want to add new behavior I have to add it in many places. Currently the data structures themselves have a lot of business logic as well; the delegation methods. Also the parent data structure has to do a lot of business logic to create a particular module and it's parent data structure if need and that parent's data structure if needed.
I'm looking to somehow break apart data management logic away from the data structure itself, but because of the nesting it's complicated. Here are some other options I've been considering:
- Create a simple
Map<Category, Map<Subcategory, Module>>, and put all the code to keep its state in a different class. My concern with doing this is requirements #1 and #2, it will be difficult to keep the view consistent as now I'll have two different data structures that represent the same data.
- Do everything in a flat data structure, and loop through the entire structure when I'm looking for a particular category or sub category.