The Mediator class

The Mediator class is responsible for coordinating the overall application state, and the interactions between our various UI classes. As such, it really needs to have three key ingredients. Firstly, it needs to have the concrete implementation of the IMediatorImpl interface, so that it can call the various functions it needs to when the UI needs updating. We have just implemented the IMediatorImpl interface in our AppComponent class, so we will need to pass a reference to the AppComponent instance to the Mediator class.

Secondly, the Mediator class needs a concrete instance of each of our State classes, so that it can recreate both the current state of the application, as well as the desired next state. It can then compare the current state and the desired next state to figure out what changes will need to occur to move from state to state.

Thirdly, the Mediator class needs to store the current state of the application. As it is responsible for moving from state to state, it makes sense for the Mediator to be the single source of truth for anything state-related. Also, where UI functionality is dependent on the current state of the application, we can forward any queries about what to do through to the Mediator class to make a decision for us.

Bearing these elements in mind, let's take a look at the properties and constructor of our Mediator class, as follows:

export class Mediator { 
    private _mainPanelState = new MainPanelOnly(); 
    private _detailPanelState = new DetailPanel(); 
    private _sideNavState = new MainPanelWithSideNav(); 
 
    private _currentState: IState; 
    private _currentMainPanelState: IState; 
    private _mediatorImpl: IMediatorImpl; 
 
    constructor(mediatorImpl: IMediatorImpl) { 
        this._mediatorImpl = mediatorImpl; 
        this._currentState = this._currentMainPanelState = 
this._sideNavState; }

We start with the three concrete instances of our three State classes, named _mainPanelState, _detailPanelState, and _sideNavState. Following this, we have two properties, named _currentState and _currentMainPanelState, which are both of type IState. These properties will be used to store the current state of the application itself, and the main panel. Remember that if we switch from the main panel to the detail panel and then back again, the side navigation panel should reappear in the same state as we left it. This is what the _currentMainPanel state variable will be used for.

The next function we will implement within the Mediator class is a simple factory function to retrieve the concrete instance of a State object given the StateType enum value as an input, as follows:

getStateImpl(stateType: StateType) : IState { 
    var stateImpl : IState; 
    switch(stateType) { 
        case StateType.DetailPanel: 
            stateImpl = this._detailPanelState; 
            break; 
        case StateType.MainPanelOnly: 
            stateImpl = this._mainPanelState; 
            break; 
        case StateType.MainPanelWithSideNav: 
            stateImpl = this._sideNavState; 
            break; 
    } 
    return stateImpl; 
} 

This is a simple helper function that returns the correct implementation of a State object given a StateType enum value.

We can now focus on the heart of the Mediator class – managing the changes to the UI when we move from state to state, as follows:

moveToState(stateType: StateType) { 
    var previousState = this._currentState; 
    var nextState = this.getStateImpl(stateType); 
 
    if (previousState.getPanelType() == PanelType.Primary && 
        nextState.getPanelType() == PanelType.Detail ) { 
            this._mediatorImpl.showDetailPanel(); 
        } 
    if (previousState.getPanelType() == PanelType.Detail && 
        nextState.getPanelType() == PanelType.Primary) { 
            this._mediatorImpl.hideDetailPanel(); 
        } 
 
    if (nextState.isSideNavVisible()) 
        this._mediatorImpl.showNavPanel(); 
    else 
        this._mediatorImpl.hideNavPanel(); 
 
    this._mediatorImpl.changeShowHideSideButton(  
        previousState.getPanelButtonClass(), 
        nextState.getPanelButtonClass() ); 
 
    this._currentState = nextState; 
    if (this._currentState.getPanelType() == PanelType.Primary ) { 
            this._currentMainPanelState = this._currentState; 
    } 
} 

This function, named moveToState, contains all of the UI logic to handle our three application states. We start by declaring two variables, named previousState and nextState. The previousState variable is where we are now, and the nextState variable is where we want to be, as passed in through the stateType argument. Once we have these two State objects, we can start to compare their properties, and then call the IMediatorImpl interface functions accordingly.

Consider the first if statement. The logic here simply states the following:

  • If we were on the primary panel, and we wish to move to the detail panel, then tell the UI to show the detail panel.

The second if statement states the following:

  • If we are on the detail panel, and wish to move to the primary panel, then tell the UI to hide the detail panel.

Our third if statement states the following:

  • If our State tells us that the side navigation panel should be visible, then show it, otherwise hide it.

We then make a call to the UI to switch the show/hide button from our current state icon to our future state icon. This will have the effect of switching the button from < to > , or vice versa, based on the properties of our two states.

Once we have finished updating the UI, we need to store our current state.

Finally, our last if statement states that if we are on the main panel, update the internal value of the _currentMainPanelState property. We need to store this value so that when we switch to the detail panel and back again, we restore our side navigation bar correctly.

This function contains, in simple, human-readable statements, how to move from state to state. Our logic has boiled down into asking a few simple questions, and responding accordingly.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.211.66