ProgramiCo
JavaScript Web Application Development
  • Home
  • SmartJs
    • Setting up the Environment
    • Running SmartJs
  • SmartJs Blog
  • About

S is for SOLID

9/26/2012

0 Comments

 
The year is 2012 and we have acronyms of acronyms of acronyms.  The word SmartJs is itself an acronym, the first letter of which is the first word of an acronym, which is itself composed of acronyms.  

This post aims to discuss SOLID principles and, in particular, demonstrate their usage in the SmartJs framework.

Background of SOLID

Please take a look here for some background on SOLID principles.  It is rather heavy reading so Wikipedia's article may be easier to digest.  We have been studying SOLID at our work and it has had a profound influence on my ability to formalize how I think about software development.

S = SRP; Single Responsibility Principle

SmartJs contains many examples of The Single Responsibility Principle.  Most obviously, AMD provides a language construct that encourages modular software design.  Each module of SmartJs is designed to do one thing only.  Indeed, during the organic construction of SmartJs, several modules were born when the code in a parent module began to do more than one thing.

But more than the modules themselves, the SRP was built right into the functionality at a fundamental level.  The most clear example of this is the interface to the Server module.  Although the interface exposes public methods that provide data persistence services, the function calls to Server are designed to begin the process only, and report back success or failure.  They never return a model representing the result of persistence, that is consumed by the caller.  In cases where a model is the result of a persistence operation, that model data always follows as a separately published application event.

The design and enforcement of rules like this took awhile to evolve.  By adhering to SRP, this design pattern doesn't seem difficult to work with, but rather a joyful reminder that SRP can be very helpful when correctly applied.  The application components must always remember that, for example in a list operation, the command to list will not be immediately followed by a list of results.  It is only a command to start the process, and a separate e.g. topic.list event will be present in the system a short time later with the contents of the requested data.  This allows an opportunity for all the components of the  application to respond equally and independently to the presence of new data and events in the ecosystem.

O = OCP; Open Closed Principle 

The Open Closed Principle can be hard to pull off, especially in a project that is evolving quickly.  It can be hard to have the foresight to know where OCP will eventually be needed.  Sometimes a switch statement is a good place to look for a place to implement OCP.

I think JavaScript makes OCP a lot easier than C# because there is never a type conversion that needs to be done.  Any object and any number of parameters can be passed to a function in any order, so Extensibility is rather built in.  It can be a fine line to walk.

The best example of OCP I can think of in SmartJs is the conduit from the client to the server.  It is boiled down to one function to call from client to server, and one function to call from server to client.  Everything goes through this narrow pipe, and the pipe itself does not require any maintenance when new functionality is added to the application.

Two modules use the Server functionality, dataContext and groupContext.  These wrap the Server in convenient methods, extending the Server's usability without requiring modification.  These two demonstrate OCP and ISP well, since new functionality could be added to the system without ever needing to change server.js.  The data conduit is truly open for extension, and closed for modification, making it a breeze to add interesting new realtime functionality.

L = LSP; Liskov Substitution Principle 

SmartJs demonstrates LSP when it passes around a Knockout observeableArray as if it was an array, to the Validation module.   Validation pushes errorMessages onto it as if was an array, never knowing or caring that the array is bound to the UI.

I = ISP; Interface Segregation Principle

Similar to SRP, modules in SmartJs are designed to do one thing.  They return only the minimum necessary interface that other modules will need.

When a model in the system needs to be used for two different purposes, SmartJs will use two different ViewModels, each with their own UI binding and public interface.  This prevents having a catch all interface that is cluttered and violates SRP.

DataContext and groupContext modules also provide segregation of the Server interface.  Their interfaces are specific to data and group kinds of functionality respectively.  New group functionality could be added to the groupContext without needing to change the server's interface.  This results in a system that is less brittle overall.

D = DIP; Dependency Inversion Principle

The best for last.  I really think this is my favorite.  It is the reason that AMD is so wonderful.  It is what separates MVVM from MVC.

AMD allows modules to have dependencies fed to them at run time.  There is no composition root.  There is no Controller to call for help.  There is only the View and the ViewModel, their binding, and events in the system which encourage things to happen.  When model properties are changed, the user interface automatically udpates through binding.

Modules never have to know or care how their dependencies are fulfilled.  They call an interface and have an expected result.  Therefore, DI makes it easy to perform Unit Testing, by allowing the building of stub objects that fulfill the dependency interfaces without doing any real work.

I have a good deal of background working in MVVM in XAML/WPF for Windows app development.  One thing that makes this pattern possible in that world, is Unity Controller.  MVVM without a DI container is a lost cause.  MVVM with a DI container is a pure pleasure to develop.

Therefore, implementing MVVM in JavaScript is correctly done using AMD and RequireJs provides this ability flawlessly.

Next post...M is for MVVM 
0 Comments

Your comment will be posted after it is approved.


Leave a Reply.

    About the Author

    Picture
    Hugh Anderson is a web frontend developer in Tennessee who loves JavaScript and C#. 

    View my profile on LinkedIn

    Archives

    August 2015
    January 2013
    December 2012
    November 2012
    October 2012
    September 2012

    RSS Feed

Powered by Create your own unique website with customizable templates.