Geertjan is a DZone Zone Leader and has posted 468 posts at DZone. You can read more from them at their website. View Full User Profile

How to Split an Application into Modules?

12.01.2009
| 37515 views |
  • submit to reddit
When you're new to modular architectures, a question that is likely to arise (sooner, rather than later) is: "How should I determine the best way to split an application  into modules?"

I asked NetBeans Dream Team member Tom Wheeler this question, in relation to his contribution to advice given during a training session described here. Below follows his response, which could apply to any modular system (based on OSGi bundles, NetBeans modules, or anything comparable).

There's really no right answer for knowing how to split your application into multiple modules.  In general, it's better to have lots of small modules instead of a few big ones. In general, I definitely prefer to have lots of little modules than a few big ones. If you're designing a new app from scratch, it's easy to achieve "smallness" in your modules and you'll have a better design (less coupling) because of it.  If you're porting an existing application to the NetBeans platform, then you'll probably just have one or two big modules at first and you'll have to achieve smallness as you make things more modular over time.

One rule of thumb is that you can often split the application into modules based on package boundaries.  Thus, if you have the following packages:

    com.tomwheeler.app.gui
    com.tomwheeler.app.data
    com.tomwheeler.app.logic

You might refactor this into a GUI module, a data module and a logic module.  As you continue development, you might find that these could be split even further.  For example, your data module might have objects representing customer data and product data, so you could create a customer data module and a product data module.

Making your application modular actually makes refactoring easier because it's clear exactly what you've exposed as a public API.  For any given feature, I almost always strive to separate API, implementation and client code into separate modules. This allows me to develop iteratively -- I can first concentrate on the API, then write a very basic implementation of it.  I can then develop additional (or better) implementations of that API as time allows.

One example might be a reporting subsystem for an application. I could create an API that defines what's needed to generate a report, but the API won't focus on details like file format.  I can then create the simplest possible implementation of that API; it might create a plain text version of the report.  I can later create a new module which creates a better report, perhaps in Excel or PDF format.  While I could simply replace the first version, I could also easily add a little code to let the user select the desired report format.

In addition to reducing coupling in your application's design, having smaller modules gives you more flexibility.  When your application is modular, it's very easy to build different versions of the application with different sets of features, kind of like the "basic", "standard" and "enterprise" versions of software you sometimes see.  Doing that with a monolithic application is usually pretty difficult.

 

If you, reading this article, have experience in this area, i.e., modularization, please share your thoughts on this topic in the comments below, since doing so would be very useful to others starting on this path!

Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Marcel Offermans replied on Wed, 2009/12/02 - 4:18am

Good stuff! Modularizing any application is also always a trade-off, where you have to take many different aspects into account. Tom definitely mentions the important ones. Besides those, you should also consider:
  • The added complexity of having many modules. The more tiny modules you have, the more complexity you add to the deployment and management aspects of your application. Having hundreds of modules makes people loose an overview more quickly, so you definitely should not make every package, or maybe even worse, every class its own module. As Tom states, package boundaries are a good place to start.
  • Rate of change at which code evolves. Usually, not all the modules in your application evolve at the same rate. Do not put things together in one module that clearly have different rates of change. For example, user interfaces tend to change more often than business logic. Also in a user interface, things like file importers or exporters might be things you want to change or extend over time, and you don't want to redeploy the whole UI every time you do that.
  • Module ownership. Especially in larger projects, there are often multiple teams, where each time might be focussed on one technical expertise, or maybe your teams contain members with different disciplines. Consider aligning the way you design your modules with the way you design your teams, so you don't end up with modules that need to be developed and maintained by multiple teams.

Phil Zoio replied on Wed, 2009/12/02 - 4:53am

Great to have a discussion opened on this important area, and some good pointers so far!

My view is that the question you should always be asking yourself is this: does my module contain separate chunks of functionality which could conceivably "live" on its own, or at least separately from the rest of the module. If so, then it probably should. Often, there will be practical queues for splitting modules: for example:

  • if your application consists of a core plus custom extensions, then each custom extension should certainly go in its own module.
  • if some functionality uses technology that is not used elsewhere in the application (e.g an interface with an SMS gateway), it should be separated
  • in general, I'd probably go for not mixing modules across tiers (ie data, service and web) but there are times for relaxing this

When designing modularity, you need to use a bit of gut feel. If a module is getting big, it starts feeling like it is taking too much responsibility, and that is usually the point to consider creating a new module and dividing up responsibility. Bear in mind that modules will grow over time, and it is probably slightly easier to coalesce than divide modules.

Phil Zoio
Impala - simple dynamic modules for Spring
http://www.impalaframework.org/
http://impalablog.blogspot.com/

 

Shambhavi 123 replied on Wed, 2009/12/02 - 5:15am

If we use modularity in application, we will have advantage of using different languages in different modules.So we can best make use of the language advantages.

Geertjan Wielenga replied on Wed, 2009/12/02 - 3:01pm

Great feedback. Maybe a refcard on modulerization should be created. The basic principles listed above are great starting points. It's also cool to see that various module systems have the same basic rationales underpinning them.

Also, based on the above various comments, could one perhaps say: "when in doubt about whether or not to create another module, go ahead and do so"? I.e., the fact that you're thinking about it is probably a reason to go ahead and follow that impulse, since it is probably appropriate in your context.

 

Milos Silhanek replied on Wed, 2009/12/02 - 5:15pm

It is better to have many of small modules with strict responsibility. It is less complex problem to make it but a question is what abou understanding of not own module bundle. You can declare dependency on other modules and some modules you do not need refer at all. But dependency structure will get difficult to understand.

I have a such experience with NetBeans modules dependencies. If I choose some dependency to use some module functionality then I need to add many of other modules. E.g. if you would use editor you must add to suite/app a lot of modules you will get wonder - http server module in my case if I remember. 

 Interesting note: It is more flexible and you can loose dependencies if you expose functionality as a service.
So you can even add several implementations and you can offer them to user to choose.

The other thoughts I have forgoten...

Muammer Yucel replied on Thu, 2009/12/03 - 3:34am in response to: Milos Silhanek

I agree with silhanek. "Strict responsibility" is the key point. Loose coupling and high cohesion are the most valuable major abilities that we intend to gain when coding, aren't they? So, if a developer can describe  responsibilities of the part of code, he should encapsulate it in a module. Not big modules neither small modules. These are not important. Describing the responsibility of modules has the biggest importance, I think.

Milos Silhanek replied on Fri, 2009/12/04 - 4:10pm

About modularity Part One:

http://techdistrict.kirkk.com/2009/11/16/applied-modularity-part-1/ 

 

Clossing article:

http://java.dzone.com/articles/applied-modularity?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+javalobby%2Ffrontpage+%28Javalobby+%2F+Java+Zone%29  

bye

Abdel Zoo replied on Fri, 2014/10/31 - 12:04pm

 greaaaaaaaaat    العاب صبايا فلاش 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.