2

I'm at the point where I'm getting into the freelance development of some complex web apps, and I would like to develop a light weight framework for my personal use, but I'd like to get some advice from more experienced programmers first about one aspect of my big-picture design for the framework.

It's heavily prototype / OOP based. The framework is set up to know how to handle each prototype, and to know that certain objects for example, a socketIO construct, can utilize other specific objects, the IP of a server for example, and also the socketPort of that server.

It facilitates this practice with the programmer's own functionality as well, helping to keep all code decoupled, object oriented, and "wireless".

The outcome of this is code that looks "wireless" -- What I mean by that, is instead of passing data as function parameters, the framework's objects know which objects to look for and read from. The developer can pass an object in as the parameter, but if he doesn't the framework will search for it and find it if it exists within the appropriate scope.

Is what I have described a good programming practice/design?

I like the code structure that it helps me to achieve more quickly, but it's important to me that I don't spend time on something that is broken (a bad model).

I want to know if this practice where the data isn't visually passed around / transferred is an acceptable approach to development.

My concern is that the communication between related objects "behind the scenes" may confuse programmers who aren't privy to the design of the framework.


Here's some "mock" client side engine code that would work after the completion of the this framework that I'm currently calling Air JS. It's commented to explain itself, because it's my blueprint, of sorts, so feel free to skim through it without bothering with every detail.

App.Engine = new engine({

    /* 

    Air JS's Engine Model 
    ---------------------

    When developing web apps, the engine 
    gets complex quickly, both on the 
    client and server side. Without a 
    framework promoting the use of good 
    JS OOP coding patterns, the code can 
    very quickly become a tangled mess!

    By utilizing object prototypes, Air
    JS accesses relevant objects and will 
    find things like IPs, Ports, 
    extensions, and other information
    relevant to a specific task, without
    the developer needing to manually 
    connect things. For example, when 
    creating a socket.IO connection, if
    a server object exists that owns a
    socketPort object, Air will find the
    port! No strings attached. 

    */

    Server : new server({

    /*

    The server constructor allows all 
    relevant server information to be 
    gathered into one place. Sky JS 
    objects such as:

        socketIO object
        AJAX object

    that utilize server information 
    will dynamically locate and utilize
    the information "wireless", without
    the need to be passed in.

    */

        location : new location({

            url     : new URL("www.website.com"),
            IP      : new IP("1.2.3.4.5"),
            ports   : new portList({

                default     : new defaultPort("8080"),
                socket      : new socketPort("4545")

            }),
            paths   : new pathList({

                app         : "App",
                login       : "Login",
                register    : "Register",
                getData     : "Get"

            });

        }),

        auth : new authentication({

            username    : new username(App.Client.Username),
            password    : new password(App.Client.Password)

        }),

    }),

    "Socket" : new socketIO({

        open : new socketListener("open", function(){

            // handle event

        }),

    }),

    /* 

    The socketIO object expects an object 
    containing socketListeners as its first 
    parameter.

    The SocketIO object accepts a server object,
    portList, socketPort, or port string / int 
    as its second parameter:

        App
        Server
        App.Engine
        App.Engine.Server
        App.Engine.Server.ports
        App.Engine.Server.ports.socket

        "4545"
         4545

    This is an example of how Air.JS works 
    "wireless" -- If the relevant object exists
    within the same engine, it will be found, 
    without the developer passing the object or
    information in as a parameter. This is called
    wireless association in Air JS.

    Wireless association will be discussed later
    on in this program, and is the primary proponent
    of the clean, de-coupled code that Air JS
    promotes.

    In this situation, the relevant object is a
    socketPort. If a server object exists that 
    owns a portList containing a socketPort, 
    it will grab the port.

    If there are multiple server objects, the 
    framework will choose the first one that owns 
    a portList and / or a socketPort.

    If no socketList object is found in a server 
    object, the framework will search the main 
    scope of the server object. If no socketPort 
    object is found in a server object, or no 
    server object is found in the engine object, 
    the framework will check for a socket object 
    in the engine object's main scope. 

    Ultimately, 
    if no socketObject exists, and the developer 
    does not provide the port via parameters, an
    error will be thrown, pointing to the missing 
    data. 

    */

});

App.init();

The functionality demonstrated here are object prototypes assigned within the framework, as shortcuts. For programmer models of new engine pieces/components, the framework would facilitate the use of objects that "know" certain prototypes. For example, the user creates the prototype Car and lists carDoor as one of its related objects, so a Car instance will look for any carDoors, without the developer feeding it a carDoor through parameters.

  • Can you program against it without having to look inside the source code? Does it provide a solid mental model? Can you understand your own code a year from now? Can you build something BIG? If it can do all that, I wouldn't worry about the 'wires'. – david.pfx Jul 8 '14 at 14:14
2

This is essentially a dependency injection framework. They are very commonly used in server-side development. Spring and Guice are two frameworks used in the Java world. Grails uses a similar convention as you have defined, specifically injecting ovjects

Dependency injection supports the Inversion of Control principle. This is important for modularity and testability. It promotes self-contained elements that declare the components they depend on, making them easy to mock or stub out for tests as well as making the structure easier to understand.

You've highlighted what, in my opinion, in the greatest weakness of framework driven dependency injection: Programmers unfamiliar with the patterns may have a hard time understanding what's going on, and may start directly instantiating components rather than injecting them. This isn't a problem at my shop since everyone is familiar with the concept. Older versions of Spring used XML to wire objects together rather than annotations to call for components to be injected; this was nice for being able to see the structure of the system but made it difficult to understand individual components.

I recommend you take a look at Angular and Ember, two Javascript frameworks that heavily use dependency injection. If they may meet your needs exactly, you should strongly consider using them to make it easier for other programmers since they have documentation and define their own conventions. This will keep you from having to train as many people on a custom framework.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.