Problems when developing large projects

Separating data
cutlets from presentation, design, bicycles ... most important without fanaticism. What problem is often encountered when developing RIA applications. A team of strong programmers “falls in love” with a new project, and with thoughts “now we will do something - the main thing is to do everything ourselves so that no other bug will crept in” they begin to refuse ready-made frameworks, libraries, solutions.
However, there is one logical explanation for this tendency, the fear of being tied to someone else's product, it happens that during the development it turns out that such an interface will be very difficult to develop on an accessible toolkit, and crutches, edits of other people's frameworks, etc. are born. I would like to offer a solution to this problem. Creating an interface manager (modules). One module can use ExtJS, another dhtmlx, and maybe even pure Javascript
Not someone else's - but open
What are the advantages of using ready-made solutions? It's easier to find a new person for a project when you use a well-known third-party product. In a situation where you are the only one of the creators of the framework and you decide to leave, then most likely the new team will rewrite everything from scratch. Plus, edit bugs and add new features while you are working on business logic. Do you want a powerful weapon in the separation of data from the presentation - use ExtJS for example, why write your own framework? You need to dynamically load the dependencies - look towards YepNope. Provide a dom with jQuery or any other known framework. Concentrate on the result. I understand that most programmers like to write everything from scratch - but this is not from what he wants to learn, to develop ... it is from laziness ... yes, it is from laziness. Studying someone else's code, reading the documentation is much more difficult than developing everything from scratch. When you write everything from scratch you will not learn a lot, people learn mostly from others, exploring someone else’s work, learn from experience (
this is how to eat your opponent’s liver ), and together with your experience you come up with something new ... more perfect. Creating stable applications in a short time you will get more recognition than by digging into the edits of the next mega-framework after the release of the new browser
IE6 ,
IE7 ,
IE8 , IE9.
If you have a goal to write your own framework, instead of developing ERP for which you were given a period of 2 months, then start with the OS ... or with the processor architecture ... and why not!?
Modularity as a cure for many diseases
Modularity is the principle of dividing a complex system into separate parts - modules. What benefits we get - we simplify the development, testing and maintenance of the system, we reduce the number of connections between different parts of the system to a minimum.
Development of the kernel and modules can engage different people in a team, and not interfering with each other at all. Refactoring of a kernel, or modules does not affect each other in any way and can be carried out in parallel and independently.
The core is the head of everything
The application kernel is the system parts manager. Top manager of the company who performs the functions of a supervisor. It controls access to resources and communication between company sites. But not control the loading of goods in the warehouse, the issuance of food and so on. Let utilities and libraries to which tasks will be delegated are engaged in this.
Kernel duties include:
- Delegation of loading modules and necessary dependencies
to the library department (in our case, I chose YepNope). - Delegation of creating the canvas for the module interface.
- Information transfer between modules.
- Notification of any system events (closing of the application, activation of a new module, resizing of the window, loss of connection with the server, etc.).
- Execution of module requests (for example, loading of another module)
See the complete project code on
GitHub.')
Simplified version of the kernel:
!function () { var listOfLibraries = {}; $(window).resize(function() { $.each(listOfLibraries, function(){ this.body.onResize($(window).width(), $(window).height()); }); }); $("script[id=core]").bind('request', function (data) { switch (data.header) { case "attach": var library = { name: data.body.name, body: new data.body.module() }; listOfLibraries[library.name] = library; $('<div id="'+library.name+'"></div>').appendTo('body'); var moduleContext = $('#'+library.name); library.body.main(moduleContext); break; } }); }();
After its load, the kernel listens to the
request message channel, when a new module is connected, it adds it to the
listOfLibraries collection. All loaded modules are stored in this collection.
Give independence to the modules!
Module example:
!function () { var Lib = function () { var context; this.main = function (moduleContext) { context = moduleContext; context.html('Hello World'); } this.onResize = function(width, height){ context.width(width); context.height(height); } } $("script[id=core]").trigger({ type: "request", header: "attach", body: { module: Lib, name: "HelloWorld" } }); } ();
As can be seen from the example, the kernel communicates with external components by means of events, or rather one “request” event, the message pool.
The message body consists of a
header and a body. In this case, the module informs the kernel that it wants to register with the system under the name “HelloWorld” and reports a link to the body of the module.
Each module receives a context from the kernel with which it needs to work. Communication with the kernel, other modules or page elements should be done through messages.
Why then do we need a kernel if we could easily create a context in the module and work with it !?
I answer: to implement a multi-window interface, to load modules on demand, to be able to load module dependencies, to create a unified system of communication between modules, to simply maintain the code ... and so on.
As a result, we got a lightweight modular solution, in which, even with a complete change in the logic of the kernel, the code of the modules does not change.
All changes concern only adding of new events. To unify the interface for communicating the kernel with modules, it is better to select an abstract class with the basic implementation of the routine and all Lib classes of modules to inherit from it.
window.Module = function () { this.context; } window.Module.prototype = { main: function (context) { this.context = context; }, onResize: function (width, height) { } }
When you connect a module to the kernel, you only need to make sure that the plug-in inherits the functionality of the abstract class Module, and if it is successful, connect it to the system.
See the complete project code on
GitHub.