Why modularity matters




















At AppLand, I work every day with companies both large and small who want to build and ship code more efficiently. We do that by helping developers onboard to new code faster, debug more efficiently, and avoid shipping with architecture flaws. Developing efficiently gets harder as code bases grow larger. On small code bases, concepts like modularity, boundaries, internal APIs, and clear areas of responsibility can seem like abstract or academic concerns.

At this scale, clean architecture and modularity are critical, not academic concerns. The most compelling reason for this that I have seen so far is testability.

On a small codebase, all available automated tests are typically run on each change. As the codebase grows and the testing time starts to exceed an hour or so, developers become conscious about speeding up the test suite. Slow tests are optimized, and parallel testing is used to speed up the overall test time. When the code is internally modular and uses defined service boundaries, these boundaries can be used to identify the subsets of the test suite that need to be run.

This is the approach used by Google. Blaze requires service boundaries to be defined using a strongly typed interface definition language such as protocol buffers , making it possible to compute the blast radius of most code changes. Eclipse developers will recognize this as the model supported by the Eclipse IDE itself, but we can leverage this model for our own applications. This RCP application provides a core workbench providing many global services.

Individual applications can leverage the workbench and global services and so can be developed and deployed much more quickly. Another use case enabled by modularity is the support for license control. It is common especially for commercial software to license parts of their software separately.

These parts might represent different domains stocks, commodities, forex or different levels of functionality basic, professional, etc. These licensable parts correlate well to modules. And the dynamic nature of OSGi allows you to upgrade a client by simply supplying a new module.

They may not even have to restart their application. The final use case illustrating the power of modularity is the case where you have an application that needs to be slightly modified for each customer.

Modularity in general and OSGi specifically are not fringe technologies useful in highly specialized circumstances. Quite the opposite. A strong argument can be made that in the future we will all be using these technologies or something similar to develop our applications. The benefits of Java Modularity, both to software developers and to end-users, are too great to ignore.

What this talk is about The purpose of this talk is convince you that Java modularity represents an important evolution in the way we develop software.

Modularity offers huge benefits to both software developers and end users: Modularity benefits software developers by increasing the granularity of the abstractions we deal with. These benefits are comparable to those gained by moving from a procedural-based language to an object-oriented one.

A very short history of software development The history of software development is often seen as a battle between clients and servers. An alternative history An alternative history of software development is based on the idea that progress has been made by increasing the granularity of the abstractions we can deal with. Why is abstraction so important? Managing complexity First, abstraction allows us to manage complexity. Refactoring Second, abstraction allows for refactoring.

Modules are the next level of abstraction For years we have been using the class as our highest-level abstraction. What is OSGi? What is a bundle during development? What is a bundle at runtime? A bundle is deployed if it is available to the OSGi framework e. A bundle moves to an installed state when it is cataloged by a running OSGi framework or if a request is made to install it.

When a request is made for a class inside a bundle, it will be activated and first enters a starting state. After the start method completes, the bundle is in an active state and will stay in this state until a request is made to uninstall the bundle. When the stop method completes, the bundle is in an uninstalled state. One of the earliest and most popular was the JBoss application server. The JBoss designers realized early on the power of modularity.

They were one of the first to build a modular architecture on the top of the JMX though JMX was designed for management, not a general purpose lightweight component server, its standardized API provided the tools needed to build a modular systems. Other examples of well-known, successful modular systems include the Eclipse and the NetBeans desktop platforms. Modularity in Software So, the question remains: how does one develop modular code?

In disciplines such as engineering and manufacturing, for example, there is a natural affinity to design modularity along the physical attributes of materials. In software development, however, there are little or no affordances to provide guidance to shape code into standardized modules. As such, developers tend to take the path of least resistance and write software systems organically i. The next few paragraphs review provide some points on creating modular software.

If you already create your software as modules great, otherwise, you can use the following text as guidelines for your next projects. Logical Modularity Generally in software, modularity can be categorized as logical or physical. Logical Modularity is associated with the internal organization of code into logically-related units. In modern high level languages, logical modularity usually starts with the class, the smallest code group that can be defined. In languages such as Java and C , classes can be further aggregated into packages namespace in C which allows developers to organize code into group of related classes languages such as Ruby, Scala, Smalltak, Java7 support similar organizational structure with additional semantics for managed components.

Regardless of the implementation scale of your module, you should be able to describe its functionality in a single sentence i. Your module should expose its functionality as simple interfaces that shield callers from all implementation details. The functionality of a module should be accessible through a published interface that allows the module to expose its functionalities to the outside world while hiding its implementation details it is way beyond the scope of this blog entry to provide a comprehensive treatments of design patterns and rules for modularity in software.

Physical Modularity Physical Modularity , is probably the earliest form of modularity introduced in software creation. Physical modularity is comprised of two main components 1 a file that contains compiled code and other resources 2 an executing environment that understand how to execute the file. Generally in software, modularity can be categorized as logical or physical.

Logical Modularity is associated with the internal organization of code into logically-related units. In modern high level languages, logical modularity usually starts with the class, the smallest code group that can be defined. In languages such as Java and C , classes can be further aggregated into packages namespace in C which allows developers to organize code into group of related classes languages such as Ruby, Scala, Smalltak, Java7 support similar organizational structure with additional semantics for managed components.

Raymond provides an iconic rule for modularity that states " Regardless of the implementation scale of your module, you should be able to describe its functionality in a single sentence i. Your module should expose its functionality as simple interfaces that shield callers from all implementation details. The functionality of a module should be accessible through a published interface that allows the module to expose its functionalities to the outside world while hiding its implementation details it is way beyond the scope of this blog entry to provide a comprehensive treatments of design patterns and rules for modularity in software.

Physical Modularity Physical Modularity , is probably the earliest form of modularity introduced in software creation. Physical modularity is comprised of two main components 1 a file that contains compiled code and other resources 2 an executing environment that understand how to execute the file.

Developers build and assemble their modules into compiled assets that can be distributed as single or multiple files. In Java for instance, the jar file is the unit of physical modularity for code distribution. Net has the assembly. The file and its associated meta data is designed to be loaded and executed by the run time environment that understands how run the compiled code.

Physical modularity can also be affected by the context and scale of abstraction. Within Java, for instance, the developer community has created and adopted s everal physical modularity strategies to address different aspects of enterprise development 1 WAR for web components 2 EJB for distributed enterprise components 3 EAR for enterprise application components 4 vendor specific modules such as JBoss Service Archive SAR. These are usually a variation of the JAR file format with special meta data to target the intended runtime environment.

The current trend of adoption seems to be pointing to OSGi as a generic physical module format see previous post. OSGi provides the Java environment with additional functionalties that should allow developers to model their modules to scale from small emddeable to complex enterprise components a lofty goal in deed. We have seen numerous disciplines have benefited by adopting modularity in process and development efforts.

So, why should you invest time in implementing a modular architecture for your next project? After all, adopting a modular design introduces new overhead such as change in design practices, module files management as project grows, design- and build-time dependency management, and each group working on a module has a narrow knowledge of the code.

The following is a list of benefits that you gain that outweigh the headaches you may encounter in modular design.



0コメント

  • 1000 / 1000