views:

589

answers:

10

I have some Java programs, now I want to find out whether it is modular or not, if it is modular then up to what extent, because modularity can never be binary term i.e. 0 or 1. How do I decide that particular code is modular upto this much extent. I want to know how to make code much more modular?

A: 

Assuming I understand your question, that you want to know what it is that makes code modular, since code modules will obviously need some dependency between each other to work at all. This is my answer:

If you can break your system down into modules, and you can test those modules in isolation, that is a good indication that a system is modular.

Christian
A: 

As you say modularity is not a binary thing so it depends on your relative definition.

I would say: Can you use a given method in any program where you need to perform that function? Is it the "black box" where you wouldn't need to know what it were doing under the hood? If the answer is no, i.e. the method would only work properly in that program then it is not truely modular.

Smalltown2000
A: 

Modularity is relative to who ever is developing the code. But I think the general consensus is that modular code is code that has portions that can easily be swapped out without changing most of the original code.

IMHO, If you have 3 modules A B and C and you want to change or replace module C completely, if it is a SIMPLE task to do so then you have modular code.

Peter D
A: 

You can use a code analysis tool such as CAP to analyse the dependencies between types and packages. They'll help you find and remove any cyclic dependencies, which are often a problem when trying to develop modular code. If there are no cyclic dependencies, you can start separating your code into discrete jars.

In general it is good practice to code to interfaces if you can, this generally means your code can more easily be refactored and/or used in different contexts.

Dependency injection frameworks such as Spring can also help with the modularity of your design. As types are injected with their dependencies by some external configuration process they don't need a direct dependency on an implementation.

Rich Seller
+6  A: 

Some Benchmarks for modularity:

  1. How many times are you rewriting similar code for doing a particular task?
  2. How much code do you have to refactor your code in case you change something somewhere in a part of your program?
  3. Are the files smaller and easier to navigate through?
  4. Are the application modules performing adequately and independently as and when required?
  5. How less disastrous is your code? Does all hell break lose when you delete just one function or variable? Do you get 20-odd errors upon re-naming a class? (For Instance you can implement a stacking mechanism to keep trace of all the hops in your application)
  6. How near is the code to natural language usage (i.e. modules and their subcomponents represent more real world objects without giving much concern to net source file size).

For more ideas check this out and this one on software quality

As for your concern on making your code more modular first you should ask yourself the above questions, obtain specific answers for them and then have a look at this

The basic philosophy is to break down your application into as small a code fragments as possible arranged neatly across a multitude of easily understandable and accessible directory layout.

Each method in your application must do no more than the minimum quanta of processing needed. Combining these methods into more and more macro level methods should lead you back to your application

OrangeRind
Another benchmark might be the "deletion criterion": If you delete X (package, class, method, field) from your program, what breaks? If there are breaks, how "far away" are they from the deleted item? If the broken items are distant, then that means X was less modular.
John O
(Add to previous comment) - When you delete something, you immediately expose its connections with the rest of the program - all of the places where it is wired to calling code. More modularity *usually* means fewer connection points, and usually means the connection points are more "local" in scope (for instance, within a single package).
John O
+1! absolutely correct!
OrangeRind
altough it does get taken care of partly in refactoring and partly in independent testing of modules, still no harm in mentioning it separately!
OrangeRind
+6  A: 
eed3si9n
+1  A: 

To answer your specific question of how to make the code more modular, a couple of approaches are:

  • One of best tool for modularization is spotting code re-use. If you find that your code does the same exact (or very similar) thing in more than once place, it's a good candidate for modularizing away.

  • Determine which pieces of logic can be made independent, in a sense that other logic would use them without needing to know how they are built. This is somewhat similar to what you to in OO design, although module/component does not necessarily need to correspond to a modeled object as in OO.

DVK
A: 

The package-by-feature idea helps to make code more modular.

Many examples seen on the web divide applications first into layers, not features

  • models
  • data access
  • user interface

It seems better, however, to divide applications up using top-level packages that align with features, not layers.

Here is an example of a web app that uses package-by-feature. Note the names of the top-level packages, which read as a list of actual features in the application. Note as well how each package contains all items related to a feature - the items aren't spread out all over the place; most of the time, they are all in a single package/directory.

Usually, deletion of a feature in such an app can be implemented in a single operation - deletion of a single directory.

John O
A: 

Since this has been tagged with 'osgi', I can throw in an OSGi-related perspective.

The short answer is that it is possible to go from completely spaghetti code to modular in small steps; it doesn't have to be a big bang. For example, even spaghetti code depends on some kind of bolognaise logging library, so in some sense, it's already modular, just with One Very Big Metball (sorry, module) in it.

The trick is to break the big meatball into one smaller chunk and then a slightly less big meatball and then recurse. It doesn't all have to be done in one go either; simply chip off a bit more each time until there is nothing left to remove.

As for OSGi, it's still possible to put an uber-jar into a bundle. In fact, you can do this without changing the bits; either by modifying the Manifest.MF in place, or by wrapping that in another JAR and specify Bundle-ClassPath: metaball.jar in the manifest.

Failing that, tools like BND can help generate the right data you'd need, and then it can be dropped in an OSGi runtime easily enough. But beware of overly coupled code, and stuff that mucks around with classloaders - those will trip you up.

AlBlue
A: 

Hej,

See, "How to encapsulate software (Part 1)," here:

http://www.edmundkirwan.com/encap/overview/paper7.html

Regards,

Ed.