How to make code modular?

42,491

Solution 1

Some Benchmarks for modularity:

  1. How many times are you rewriting similar code for doing a particular task?
  2. How much do you have to refactor your code when you change some part of your program?
  3. Are the files small and easy to navigate through?
  4. Are the application modules performing adequately and independently as and when required?
  5. Is your code minimally disastrous? Does all hell break lose when you delete just one function or variable? Do you get 20-odd errors upon re-naming a class? (To examine this, 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 out this blurb about modularity 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 of code fragments as possible, arranged neatly across a multitude of easily understandable and accessible directory layouts.

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.

Solution 2

Key points are

  • Separation of concerns
  • Cohesion
  • Encapsulation (communicates via interface)
  • Substitutability
  • Reusability

A good example of such module system is standard car parts like disk brakes and car stereo. You don't want to build car stereo from scratch when you are building cars. You'd rather buy it and plug it in. You also don't want the braking system affecting the car stereo — or worse car stereo affecting the brake system.

To answer your question, "How do I decide that particular code is modular up to this much extent," we can form questions to test the modularity. Can you easily substitute your modules with something else without affecting other parts of your application?

XML parsers could be another example. Once you obtain the DOM interface, you really don't care which implementation of XML parser is used underneath (e.g. Apache Xerces or JAXP).

In Java, another question may be: Are all functionality accessible via interfaces? Interface pretty much takes care of the low coupling.

Also, can you describe each module in your system with one sentence? For example, a car stereo plays music and radio. Disk brakes decelerate the vehicle safely.


(Here's what I wrote to What is component driven development?)

According to Wikipedia, Component-Based Development is an alias for Component-based software engineering (CBSE).

[It] is a branch of software engineering, the priority of which is the separation of concerns in respect of the wide-ranging functionality available throughout a given software system.

This is somewhat vague, so let's look at more details.

An individual component is a software package, or a module, that encapsulates a set of related functions (or data).

All system processes are placed into separate components so that all of the data and functions inside each component are semantically related (just as with the contents of classes). Because of this principle, it is often said that components are modular and cohesive.

So, according to this definition, a component can be anything as long as it does one thing really well and only one thing.

With regards to system-wide co-ordination, components communicate with each other via interfaces. [...] This principle results in components referred to as encapsulated.

So this is sounding more and more like what we think of good API or SOA should look like.

The provided interfaces are represented by a lollipop and required interfaces are represented by an open socket symbol attached to the outer edge of the component in UML.

alt text

Another important attribute of components is that they are substitutable, so that a component could be replaced by another (at design time or run-time), if the requirements of the initial component (expressed via the interfaces) are met by the successor component.

Reusability is an important characteristic of a high quality software component. A software component should be designed and implemented so that it can be reused in many different programs.

Substitutability and reusability is what makes a component a component. So what's the difference between this and Object-Oriented Programming?

The idea in object-oriented programming (OOP) is that software should be written according to a mental model of the actual or imagined objects it represents. [...]

Component-based software engineering, by contrast, makes no such assumptions, and instead states that software should be developed by gluing prefabricated components together much like in the field of electronics or mechanics.

Solution 3

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.

Solution 4

Hej,

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

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

Regards,

Ed.

Solution 5

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.

Share:
42,491

Related videos on Youtube

Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    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?

    • Kevin
      Kevin almost 9 years
      If code is truly modular, each component should be a black box. The less knowledge components know about each other, the more modular the system.
  • John
    John over 14 years
    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
    John over 14 years
    (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).
  • OrangeRind
    OrangeRind over 14 years
    altough it does get taken care of partly in refactoring and partly in independent testing of modules, still no harm in mentioning it separately!
  • Piovezan
    Piovezan almost 7 years
    The "check this out" link is broken, unfortunately.