Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Refactoring IGB into self-contained "modules" of independent functionality reduces IGB's complexity and makes it easier to maintain and modify when new needs arise. Why does reduced complexity help? It helps in many ways, but one of the most obvious and important is that it reduces the amount of information a developer must keep in mind when reading or modify modifying a section of the code. Instead of working on the entire application all at once, a developer can focus on a single module, confident that any changes he or she makes will affect only that one module, provided the module interface stays the same. By enforcing a modular design - and restricting the points of contact between modules - we can build a more complex, powerful application for users while also gaining flexibility to adapt to change. This view of IGB as a system of cooperating modules with clear boundaries builds on the familiar concept of separation of concerns in object oriented programming. Rather than apply this principle at the class or package level, we apply it at the module-level, where modules are "bundles" of code responsible for clear tasks within the IGB application. By working with modules, we can more effectively manage our code base.

...

IGB runs within an OSGi framework, a system and protocol for assembling and running applications composed of independent modules. When users launch IGB, they are really launching an OSGi "run-time," which then loads individual IGB modules - called "bundles" - into the run-time environment and instantiates objects as needed to satisfy module's dependencies on each other. To make methods available to other modules, a module developer inserts annotations that signal to the run-time that the method should be provided as an optional service to other modules in the IGB system. Only methods that are explicitly annotated as exportable are exposed to external modules. Moreover, developers rarely have to explictly explicitly create or destroy many of the key objects in the IGB application. The OSGi run-time handles all of that.

...

The efforts we have made and continue to make to modularize the IGB code base have the incredibly beneficial side effect of leading to a software system which is already pluggable/extensible in a huge variety of ways.  The reason why a plugin API is the natural organic output of this refactoring effort is obvious. Each time we find existing functionality in code which is being isolated into a module we must evolve our APIs to allow for extensibility to accomodateaccommodate. If for example, we find some code which is adding a menu option into the main IGB toolbar, then we must then create mechanisms in the plugin API to allow for the addition of menus to this toolbar (e.g. the addtion addition of an interface to implement).  These mechanisms are then available to all future module developers to leverage when writing their own extensions to IGB.  

...

  1. Library Modules - modules that contribute "utility" classes for consumption by other modules (e.g. guava, apache commons)
  2. API Modules - modules that only contain service interfaces, abstract classes, data model, or similar content.  (e.g. the igb-services-api module)
  3. Implementation Modules - modules that implement instances of the interfaces/abstract classes contained in API modules.  There  Their implementations typically will take the form of a registered OSGi service, requiring none of the internal content of bundle a qbundle to be exposed.
  4. Blended Modules - Small modules which may both define API content and publish implementation content within the same module.  We do not consider this improper in most cases as long as the package exports are ensuring a proper separation of concerns and not exposing internals.  As a rule, only expose API, utility classes, and data model. 

...