5

I am designing a UI framework in Java. Every UI component, represented by the class Component, in the framework is identified by a non null unchangeable String key. So I get the key in the constructor itself and provided no setter.

Now I have another class AggregateComponent which represents a component containing array of components. In the AggregateComponent class a Factory is used to create the child components. For some reasons the key of the child components should be parentComponent.key + index, where index is the array index of the child component. So I pass parentComponent.key + index to Factory.create().

The contract is the Factory implementer should construct the child Component using the passed key.

We may enforce this contract in AggregateComponent by checking the key of the created component against the passed key and throw an exception. But I am asking

Is there any solution (even a completely different design solution) without such contracts.


Actually the components are intended to display data from an Object (a POJO, JSON or XML). For primitives in the object a simple Component is enough. For arrays we need the AggregateComponent. The factory is used in AggregateComponent to separate the creation logic of child components.

As I mentioned earlier the key of child components should be in particular form. In future we may write a Component to display maps (similar to array). In that case the key might be of form parentComponent.key + cKey where cKey is a key in the map.

2
  • Is there any possibility in your framework that a child component are removed or replaced? If so, is it acceptable to have "holes" in the "key numbers"? Is it acceptable to have duplicate keys? Dec 3, 2017 at 16:59
  • @TimothyTruckle Child components can be removed, replaced, added. The key number is not a primary thing, we are using the index just to show the difference among children. We can use non repeating random numbers also. It is not acceptable to have duplicates. Dec 6, 2017 at 16:15

1 Answer 1

4

As there is an external requirement on how the key of a child component is constructed, there must be some kind of contract in the construction of child components that ensures the format of the key.

How to best implement this requirement depends on what percentage of all components in your system is a child component.
If you only have one non-child (aggregate-)component, then I would change the constructors of the component classes to accept the parent component and index. Then they can construct the correct key themselves. Only the one non-child component would need a constructor that creates the key in a different manner (or accepts it from outside).

If there is a large percentage of non-child components, then your current design with the factory is perfectly fine.

6
  • Actually any component (including the aggregate one) can act as child components and only one component (the aggregate one) can act as a non-child component. Therefore there are one hundred percent child components and only one non-child component. Dec 3, 2017 at 7:55
  • If we add constructor accepting parent in all component classes then we are introducing more details in many classes for one class. Which bothers me a bit. For that the current design introduces more details in only one Factory class. Dec 3, 2017 at 8:04
  • 2
    If all classes can be children and if all instances except one actually will be children, then there is no strong reason to keep that knowledge out of the (common base class of the) component classes. Dec 3, 2017 at 10:06
  • Are parents a different type of thing (class, i.e.) from a child, or can a child act as a parent and vice versa? If the latter, then totally agree with Bart that there's no reason not to pass the parents along to the children for construction. If parents are a different type, then it might be a bit goofy with circular dependencies between two types (parent type and child type, or child->parent abstraction and parent->child abtraction).
    – user204677
    Dec 3, 2017 at 12:18
  • BTW, how are these keys used? I've done various GUI kits in the past and never thought to associate keys this way. Usually with form designers I make it so the parent ensures that each child has a unique name/key, and the child basically tries to insert itself using its control name... like "ListBox". If there's one that already exists, then "ListBox2", and "ListBox3", and so on (not using such a brute force algorithm though -- uses a compact trie). It's detached from the index position of the child relative to the parent -- just a unique name generated upon insertion.
    – user204677
    Dec 3, 2017 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.