I have a series of classes that represent widgets in a layout system. The base class for all of these concrete widget types is
Widget. If I have a Button and a Text Box, these both derive from
The layout is structured as a tree. Each widget can have only 1 parent and zero or more children, which are also of type
Some of these concrete widget types need to share state. As a contrived example, let's say that each widget determines its own background color from a list of predetermined colors, configured by the user called
Theme. The overall theme of the application allows you to define colors for broad categories of widgets. When a widget needs to know what its background color should be, it needs to actively have access to the same instance of
Theme to do the lookup. So what I end up with is some widgets in the system (those that can be colored, such as the button and text box) needing access to a
Theme instance but other widgets do not care about color.
Option 1 is to make
Widget's constructor take a reference to the
Theme, which subclasses can choose to use temporarily, store permanently (for continued use), or not use at all. The downside to this is that not every widget subclass cares about themes, so this is like having an "Ostrich" class derive from a "Bird" class with a function in it called "Fly()" (i.e. not all birds fly).
Option 2 is to use visitor pattern. After construction of all widgets, use visitor pattern with overrides for
TextBox to obtain state from the visitor object to do the thing it needs to do. Other widget types would be "defaulted" to no-op in the visitor class by having a 3rd overload that takes the base type
Is there an option 3 that is better? Any thoughts about the 2 options above? What's the right approach here?
Themes active at the same time, with some
Widgets referencing one
Widgets referencing a different one?
Theme. The widgets that care about themes all share a reference to that same, singular instance. Think of this in a
shared_ptrconcept: Shared ownership, but single instance.