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 Widget
.
The layout is structured as a tree. Each widget can have only 1 parent and zero or more children, which are also of type Widget
.
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 Button
and 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 Widget
.
Is there an option 3 that is better? Any thoughts about the 2 options above? What's the right approach here?
Theme
s active at the same time, with someWidget
s referencing oneTheme
and otherWidget
s referencing a different one?Theme
. The widgets that care about themes all share a reference to that same, singular instance. Think of this in ashared_ptr
concept: Shared ownership, but single instance.