- Object-Oriented Technology
- Component-Oriented Technology
- Technology Ownership
- Client-Server Technology
- Internet Technology
- Architectural Layers and When to Use Them
- Software Application Experience
- Technology and Application Architecture
- Applying Standards to Application Systems
- Distributed Infrastructures
- Conclusions
- Exercises
3.2 Component-Oriented Technology
Moving to the next level of software sophistication requires fundamental changes in systems thinking, software processes, and technology utilization. The next major area of technology, componentware (or component orientation), contains key elements of the solution to today's critical software problems.
The componentware approach introduces a set of closely interrelated techniques and technologies. Componentware introduces a sophisticated mindset for generating business results. These componentware elements include
-
Component infrastructures
-
Software patterns
-
Software architecture
-
Component-based development
Componentware technologies provide sophisticated approaches to software development that challenge outdated assumptions. Together these elements create a major new technology trend. Componentware represents as fundamental a change in technology as object orientation did in previous generations. These componentware technologies are discussed after a brief introduction to componentware's unique principles.
Components versus Objects
Componentware can be understood as a reincarnation of object orientation and other software technologies. Distinguishing componentware from previous generations of technology are four principles: encapsulation, polymorphism, late binding, and safety. This list overlaps with object orientation, except that it eliminates the emphasis on inheritance. In component thinking, inheritance is a tightly coupled, white-box relationship that is unsuitable for most forms of packaging and reuse. Instead, components reuse functionality by invoking other objects and components instead of inheriting from them. In component terminology, these invocations are called delegations.
"Fit the parts together, one into the other, and build your figure like a carpenter builds a house. Everything must be constructed, composed of parts that make a whole..."
Henri Matisse
By convention, all components have specifications corresponding to their implementations. The specification defines the component encapsulation (i.e., its public interfaces to other components). Reuse of component specifications is a form of polymorphism that is strongly encouraged. Ideally, component specifications are local or global standards that are widely reused throughout a system, an enterprise, or an industry.
Componentware utilizes composition for building systems. In composition, two or more components are integrated to create a larger entity, which could be a new component, a component framework, or an entire system. Composition is the integration of components. The combined component acquires joint specifications from the constituent component.
If the components have matching specifications for client calls and services, then they can interoperate with no extra coding. This is often called plug-and-play integration. When executed at runtime, this is a form of late binding. For example, a client component can discover a component server through an online directory, such as the CORBA Trader Service. With matching client and service interface specifications, the components can establish a runtime binding to each other and interact seamlessly through the component infrastructure.
In a perfect world, all components would be fully conformant with their specifications and free from all defects. Successful operation and interoperation of components depend on many internal and external factors. Safety properties can help because they can minimize entire classes of defects in a component environment. As society becomes increasingly dependent upon software technology, safety has become a serious legal concern and one of the most important areas of computer science research. For example, Java's garbage collection feature guarantees memory safety, or freedom from memory deallocation defects (which are problematic in C++ programs). Other kinds of safety include type safety (guaranteed data type compatibility) and module safety, which controls the effects of software extension and component composition.
Component Infrastructures
The componentware revolution has already arrived in the form of component infrastructures. Major platform vendors have bet their futures on componentware product lines. In particular, Microsoft, Sun Microsystems, IBM, and the CORBA consortia have established significant componentware infrastructures through massive technology and marketing investments.
These component infrastructures (Microsoft .Net and Sun Java Enterprise JavaBeans including CORBA) are dominant infrastructures for competing industry segmentscomponent-oriented enterprise application development. Interestingly, these technologies are also mutually interoperable to a great extent through the mutual support of XML, Web services, and other emerging standards for enterprise application development.
Microsoft has completely revamped its component infrastructure in its current .Net product suite. The Microsoft .Net product suite is focused on the development and deployment of enterprise-level applications and distributed services. While it incorporates a lot of new code, it also includes many of the products and technologies that were successful in Microsoft's previous distributed development platforms, Microsoft Distributed Network Architecture (DNA) and Distributed Common Object Model (DCOM) such as the Microsoft Transactions Server (MTS), Microsoft SQL Server, and the long-lived Common Object Model (COM)/COM+ components. The existing .Net suite upgrades these products in an integrated enterprise product suite along with new support for XML data, Web services, and a much improved development environment. Microsoft .Net is the concrete proof the software industry needed to verify that Microsoft will remain a major player in the emerging world of components for the foreseeable future.
Sun Microsystems' invention of the Java language is a continuing evolution of programming language features, infrastructures, and related class libraries. The Java language technology has created tremendous industry excitement and support from independent developers. The extensions for Java-Beans and Enterprise JavaBeans establish an evolving component model that rivals COM and ActiveX in the cross-platform application space. Enterprise JavaBeans and the IBM San Francisco project are using Java Remote Method Invocation (RMI) for distributed computing, one of several proprietary infrastructures available to Java language programmers. More recently, the Java language has included RMI over OMG's Internet Inter ORB Protocol (IIOP), which allows for Java to interoperate with distributed components in other programming languages that have a CORBA IDL interface. While proprietary Java language infrastructures do provide convenience for programmers, they require additional complexity to interoperate with other programming languages, especially locally using the Java Native Interface (JNI) to invoke routines in programming languages other than Java. This may be a significant hindrance for corporate projects because it slows legacy integration and cross-language development, which is commonplace for server applications.
Java application servers have overtaken CORBA's role in many Internet-savvy organizations. What CORBA lacks is direct support for scalability, reliability, and maintainability. These capabilities are standard features supported by most Java application servers today.
Componentware infrastructures are having a significant impact on software development. In many respects, these infrastructures are well on their way to becoming mainstream development platforms. Because they are all becoming interoperable (through CORBA IIOP), there is a well-understood relationship between infrastructure models. Their similarities are much greater than their proprietary differences might imply.
Infrastructure selection is one of the most discussed, but least important, aspects of implementing componentware. For corporate developers, the most critical issues are confronted well after infrastructure selection. These issues include how to master designing with the technology, how to architect systems, and how to coordinate one's development efforts..
Component Software Design Patterns
Software design patterns comprise a common body of software knowledge that can be applied across all component infrastructures. Software design patterns are proven design approaches to a specific category of structural software problems that are documented for reuse by other developers. Other important categories of patterns include analysis patterns and AntiPatterns. Analysis patterns define proven ways of modeling business information that can be directly applied to the modeling of new software systems and databases.
Software design patterns are a necessary element of componentware. The development of new, reusable components requires an expert-level quality of design, specification, and implementation. Proven design solutions are necessary to establish successful component architectures and frameworks for families of applications. Often, there are too many variables to take chances on unproven design concepts.
The popularity of software design patterns can be explained as a response to the practical shortcomings of object orientation. AntiPatterns explain the common mistakes that people make when developing object-oriented software systems (as well as other types of systems). Much more is needed than basic object-oriented principles to build successful systems. Design patterns explain the additional, sophisticated ideas that are required for effective software designs. Analysis patterns present the sophisticated ideas necessary for the effective modeling of concepts and data.
It is still commonplace in software development to reinvent design ideas, incurring the risks and delays of trial-and-error experimentation. In fact, most software methods encourage reinvention as the normal mode of development. Given the challenging forces of requirements change, technology innovation, and distributed computing, reinvention is an unnecessary risk in many circumstances. This comment is especially applicable to the development of components, where the costs of defects and redesigns can affect multiple systems.
Altogether, software design patterns can be described as knowledge reuse. It is interesting to note that most patterns are considered as simple as common sense by expert-level developers. However, for the majority of developers, patterns are a necessary part of the technical training that can help them to achieve world-class results.
Component Software Architecture
Software architecture concerns the planning and maintenance of system structure from earliest system concept through development and operations. Good architectures are stable system structures that can accommodate changes in requirements and technologies. Good architectures ensure the continuous satisfaction of human needs (i.e., quality) throughout system life cycles. Reusable components are examples of good architecture. They support stable interface specifications, which can accommodate changes that are the result of reuse in many system contexts.
Software architecture plays an important role in component design, specification, and use. Software architecture provides the design context within which components are designed and reused. Components have a role in predetermining aspects of software architecture. For example, a component framework may predefine the architecture of a significant portion of a system.
One of the most exciting aspects of software architecture for componentware is supporting distributed project teams. Software architecture comprises a system specification that enables parallel, independent development of the system or its parts. Proper software architecture defines computational boundaries (i.e., APIs) that divide the system into separate testable subsystems. These subsystems can be outsourced to one or more distributed project teams.