I have an architecture based on a domain with multiple object types. These objects (many and of disparate types) must reside together with each other because they make up a use-case. The types are not more than 20-30, but might be added along the way, and I do not know if type-safety is worth the maintenance. Let me make this more clear.
My architecture has to support various, (well...more or less) well-defined use cases for those objects, for example visualization, custom hierarchical relationships etc, which are, however, either strictly domain-knowledge (e.g. hierarchy) or strictly foreign to the domain (e.g. visualization styling). I am considering using a general repository (weakly-typed, with "objects") and provide the additional infrastructure-based behavior for each object through suitable decorators (e.g. VisualizationDecorator
, HierarchyDecorator
) that wrap the domain relationships (e.g. hierarchy)
or, generally, the expected behavior for the various use-cases (e.g. visualization). However, the decorators will have to be created from objects, so multiple dispatch will be necessary.
Right now I am thinking of creating Decorator classes for every use-case (e.g. KnifeVisualizationDecorator
would wrap the image of a knife, potentially with some color, dimensions etc., based on the properties of an actual Knife object, a DrawerHierarchyDecorator
wraps a Drawer object and provides the Children
property as a list of objects, known to the Decorator to be the Knives, Spoons and Forks of the strongly-typed Drawer object, etc.). Then, general Decorator-provider classes will perform the dispatch and create and dispatch suitable decorators for each use case. For example a VisualizationDecoratorProvider
checks the type of an object and returns a KnifeVisualizationDecorator
, or a SpoonVisualizationDecorator
etc. The consumer class will have no idea about the specific type of the decorator, all it cares about is how to visualize the spoon, knife, or fork, so the visualization decorator interface only contains a suitable visual (or appropriate properties to construct one thereof, based on the requirements of the underlying infrastructure).
As a consequence of this approach, any infrastructure "service" class will require a means to retrieve decorators for various objects passed to it. With that in mind, I will have to create decorator abstract factories, perhaps, which will, of course, be the materialization of the corresponding decorator providers. The problem is that it is necessary to "register" the various specifics for each separate object type the entire architecture will have to be able to serve. This way, I am dangerously approaching a Service Locator lookalike which will be the overall provider that checks the type of an object, invokes a suitable decorator-provider to wrap it into a decorator and hands it out to the requester.
This may not look like the exact Service Locator pattern at first, but if I supply the general "decorator-provider-provider" (decorator-provider resolver, actually) to many classes, this will be it. I can avoid this if I only supply specific decorator providers based on the needs of each infrastructure class and avoid the overall resolver.
So, my question is, is it a good architecture to unify a set of behaviors by extending weakly-typed objects based on their run-time type through corresponding decorators, which will be resolved based on run-time type-based dispatch by corresponding resolver classes injected to the various infrastructure classes that need them?
EDIT: To clarify my question a bit, to put this architecture in place, I have to create Decorator Services that supply suitable decorators based on the object type. So, a class requiring a VisualizationDecorator
from an object will have to be handed a VisualizationDecoratorService
upon construction (or VisualizationDecoratorProvider
, if you like) and request the VisualizationDecorator from that as in:
VisualizationDecorator visual = visualizationDecoratorProvider.Decorate(obj);
These Decorator-providers will have to be handed to each infrastructure class (e.g. a visualization service). Is this going to pose a significant problem in the long-run, which I might be missing at the moment?