Search code examples
algorithmcomputer-sciencedesign-principles

What is an elegant way to track the size of a set of objects without a single authoritative collection to reference?


Update: Please read this question in the context of design principles, elegance, expression of intent, and especially the "signals" sent to other programmers by design choices.

I have two "views" of a set of objects. One is a dictionary/map indexing the objects by a string value. The other is a dictionary/map indexing the objects by an ordinal (ordering integer). There is no "master" collection of the objects by themselves that can serve as the authoritative source for the number of objects, but the two dictionaries should always both contain references to all the objects.

When a new item is added to the set a reference is added to both dictionaries, and then some processing needs to be done which is affected by the new total number of objects.

What should I use as the authoritative source to reference for the current size of the set of objects? It seems that all my options are flawed in one dimension or another. I can just consistently reference one of the dictionaries, but that would codify an implication of that dictionary's superiority over the other. I could add a 3rd collection, a simple list of the objects to serve as the authoritative list, but that increases redundancy. Storing a running count seems simplest, but also increases redundancy and is more brittle than referencing a collection's self-tracked count on the fly.

Is there another option that will allow me to avoid choosing the lesser evil, or will I have to accept a compromise on elegance?


Solution

  • I would create a class that has (at least) two collections.

    • A version of the collection that is sorted by string
    • A version of the collection that is sorted by ordinal
    • (Optional) A master collection

    The class would handle the nitty gritty management:

    • The syncing of the contents for the collections
    • Standard collection actions (e.g. Allow users get the size, Add or retrieve items)
    • Let users get by string or ordinal

    That way you can use the same collection wherever you need either behavior, but still abstract away the "indexing" behavior you are going for.

    The separate class gives you a single interface with which to explain your intent regarding how this class is to be used.