Pros and Cons of Modularization, Plugin Architectures and Other Techniques 📎
Plugins, modules, bundles and decoupling seems to be sexy nowadays. I remember the disappointment of an architect in one of my past projects, as we went into production with only five plugins. He expected more, but the customer was absolutely happy with the result, as well as the provided flexibility. I asked him, why we need more plugins - his answer was: "because of modularization". But: It is hard to find a customer, which just pays for modularization :-).
Modularization helps to structure the application, but as every other architectural paradigm, it has it's challenges as well:
- Every plugin / module / bundle comes with metadata which defines provided and required dependencies. This data has to be provided somehow, it isn't DRY (don't repeat yourself) in general. At least the names of classes, interfaces etc. will be listed in the configuration. You will need specific tools (Eclipse, Netbeans) to maintain that metadata, otherwise refactoring could become a nightmare.
- At least "provided" dependencies are often realized as Java interfaces. The plugins are decoupled from each other via interfaces. Not every technology is compatible with this approach E.g. relationships between JPA objects can be hardly expressed with interfaces. The result: the whole domain model is packaged in one plugin...
- The governance can become hard. The dependencies between plugins (and their versions), has to be configured somehow. But: how many version do you would like to maintain in parallel? This problem is similar to the SOA-challenges. See: "How To Kill A SOA Project" as well.
- Funny story: after the deployment many customers do not want to be able to load and replace parts of the application at runtime. This could become too hard for the end users (sometimes even for developers) to maintain. In most of my projects, we had to disable the update site / plugin management capabilities in "production".
- In most companies the release cycle for desktops apps is predefined. The applications are just shipped as a "blob". From the deployment point of view it is easier to deploy one single file, instead of many interconnected chunks of functionality.
- Most of the frameworks like JPA (Hibernate, TopLink), Log4J etc. have problems with specific classloading in Eclipse / Netbeans RCP (there are issues in both cases). In Eclipse land the projects often go to production with "Eclipse-BuddyPolicy". Then the plugins are able to export / import the classes directly - actually a hack...
- Sometimes bidirectional relations between plugins are required, because of business requirements. Most of the plugin "containers" have their problems with bidirectional dependencies. Bidirectional dependendencies are not "beautiful" but sometimes required in real world. You can of course obfuscate them with reflection or other hacks, or deploy the dependent parts in one bigger plugin. The problem here: the plugins are not designed in respect to business, but deployment point of view.
- Performance is not an issue in general. Nonetheless plugins can influence heavily the startup performance. Just try to start Eclipse SDK, then one of the commercial offering built on top of Eclipse (Rational, SAP, BEA etc). You will see the difference :-).
- It is hard to find good extension points in advance. They are often too generic or too specific.
- In contrary to technical stuff and IDEs, business software is not always that extensible. The customers do not think in replacable algorithms. It is often hard to say which parts are instable (or are changed often), and which are rock solid. This is rather simple for IDEs, but much harder for business applications. Often the algorithms in real world are not going to be replaced very often.
- Usability can suffer. Best example: Glassfish. Glassfish v2 can be installed with few clicks. Glassfish v3 either. BUT: you have to have an internet connection to download e.g. the admin console after the installation. The modules can be dynamically downloaded and installed, but it can go wrong and is not as convenient as in the rather monolithic Glassfish v2. Although Glassfish v3 is modular, it will be surely (hopefully :-)) distributed in predefined profiles, rather then with a micro kernel and tons of dynamic modules.
Nonetheless, modularization is much better then monolithic applications. Building cohesive and independent units is always a good thing. But they do not have always to be dynamic reloadable, installable and replacable.The modules should be designed according to the functional requirements, and not driven by the capabilities of the "plugin-containers". Just: Keep It Simple...