The solution to pollution

In essence, we're striving to make sure that a newcomer to a project is never surprised by what they see. Everything should be clearly labeled, decisions should have logic behind them, and code should be in a place that makes sense for its functionality. We've briefly touched on how a namespace (such as utils) can become a "bucket" for code that doesn't immediately fit. There are a couple of other situations in which we find ourselves creating a dumping ground for functions that nobody knows what to do with.

A global solution to a local problem

Our hero, the plucky programmer with a lot of heart and a burgeoning talent, is writing their latest application when they realize something.

I'm going to need this function a lot; potentially, in most of my UI components.

Worried, they consider the best way to implement it, then the best place for it to fit in the existing code base.

I need to call it from anywhere in the application. Also, my application class is already available from everywhere in the app; I'll hang it off there. MyApp.myFunc(), here we come!

And so our hero starts down the road to madness. MyApp.isUserLoggedIn(), they ask? MyApp.isProduction() or MyApp.isStaging(), they wonder? Also, for convenient access to configuration, we have the MyApp.validNames and MyApp.apiUrl arrays.

Look on my global state ye mighty, and despair!

A little melodrama to get the point across. It's very easy to use your application singleton as an easy catch-all as shown here:

Ext.define('CultivateCode.Application', {
    extend: 'Ext.app.Application',
    
    name: 'CultivateCode',

    searchCfg: {
        mode: 'beginsWith',
        dir: 'asc'
    },

    isLoggedIn: false,
    isSecure: false,

    launch: function () {
        this.setupAjaxOverrides();
        this.performCookieCheck();

        Ext.apply(Ext.util.Format, {
            defaultDateFormat: 'd F Y'
        });
    },

    setMasked: function(mask) {
        // Implementation
    },

    setupAjaxOverrides: function() {
        // Implementation
    },

    onAjaxError: function(connection, resp, opt) {
        // Implementation
    }

    performCookieCheck: function() {
        // Implementation
    }
});

What would be the right thing to do here? Well, searchCfg needs to be moved to the place it's used, perhaps a search model or view model, maybe on the UI component responsible for search.

The Ajax overrides and error handling could be moved to the /overrides folder and positioned within their correct namespaces, making them much more discoverable.

The cookie check, which makes sure users have cookies enabled on their browser, could probably be retained in the application class, simply because in this app, cookies could be a requirement.

Things such as isLoggedIn would be best taken care of by a SessionManager, as we previously discussed. Still in a singleton, but a singleton that is in a more discoverable and logical place for this functionality.

In another place, we can take our cue from the Ext JS framework: setMasked. Rather than having this as a method on the application, Ext JS provides it as a method on each Ext.Container, meaning you can call it directly on panels and grids. This means that the code that masks components will no longer jump up to the global application scope and hope that it's targeting the correct container. Instead, you can be certain that you're affecting the component you're interested in and nothing more, and all without polluting your global application class.

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

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