OO Nav Drawer Design Exercise – Part 1

In this three part article we are going to work through an OO design exercise in some detail. We will be designing a mini-model that backs a drawer navigation system such as the one in figure 1.

mio-staging_mio-components_1568406561463_assets_1nsuL8VDpBW_LZYXgabK1H0uq6icmmKYt_nav-drawer-introFigure 1

In part 1 (this part) we will identify the main classes and their relations. In part 2, we will work out how to construct objects from this class structure in an immutable manner. In part 3, we work out an extension of the model.

Let us start with the simplest bit. The navigation system shows a list of links, each with a distinct ID and a human readable label as shown in figure 2.

controller-example-02-4

Figure 2

Note that in the real world there would be several classes for model, controller, view model, etc. For the purpose of this article, we will use the Nav class to stand in for this set of classes. So the Nav class shall be responsible for providing the NavLink list as well as handling the selection of a link.

Each link is associated with a controller that is supposed to take over the control of the main content area when the link is selected. This association is shown in figure 3.

controller-example-03-2

Figure 3

Now, what happens when a link gets selected? How does the Nav know that it needs to switch to the associated controller? One solution commonly implemented in some of the popular UI toolkits is that the view passes the ID of the selected link to the Nav. To make things more interesting, let us go a different route and add the selection behavior to NavLink instead of just using it as a POJO.

Let us add a select() method to the NavLink, which is to be called by the view when the link is selected. How should the select() method be implemented? The naive solution is to have it directly call on the Nav. This introduces an unnecessary dependency from the simple NavLink class on the whole set of navigation classes. Thus, we add an associated Listener interface to the NavLink in order to abstract out, from the NavLink point of view, who handles the selection. Our design now is depicted in figure 4.

controller-example-04

Figure 4

So far so good? There is one remaining issue, which is how to construct instances of these classes. As usual, we would like to create immutable objects whose fields are all final. However, there is an issue with the design in figure 4 that makes this non-trivial. The issue is that there is an implicit cycle in the design. Pause a minute and try to spot it.

To construct a NavLink you need to have an instance of the Listener interface, which in this case is implemented by a Nav instance, and to construct a Nav instance you need to pass it the NavLink list.

We address this issue in part 2.

Leave a comment