Why Consider Implementation-Level Decisions in Software Architectures? Nikunj Mehta Nenad Medvidović Marija Rakić {mehta, neno, marija}@sunset.usc.edu Department of Computer Science University of Southern California Los Angeles CA 90007 1. Abstract Software architecture provides a high-level abstraction of the structure, behavior, and properties of a software system aimed at enabling early analysis of the system and its easier implementation. Often, however, important details about a system are left to be addressed in its implementation, resulting in differences between conceptual and concrete architectures. This paper describes an approach towards bringing these two closer by making certain implementation-level decisions explicit in the architecture. Specifically, we focus on the choices made in modeling and implementing component interactions. The process is based on a taxonomy of software connectors that the authors have developed to better understand component interactions, and an architectural framework developed to support a variety of connectors. 2. Introduction As software systems become more complex, there is an increasing need for employing higherlevel abstractions to better represent the system structure, behavior, and properties in terms of underlying building blocks. Software architectures provide such high level abstractions and can be formed through the composition of lower level building blocks. Conceptual software system architectures are often described via “boxes and lines” diagrams. However, such diagrams depict only the top-level computing blocks and fail to show those implementation properties of the blocks that can affect global system behavior. Additionally, the lines fail to provide enough (detailed) information about the interactions among the blocks. This can render meaningful analysis of architectural properties difficult and can result in divergent conceptual and concrete architectures. A possible solution to this problem is to provide some details about the implementation in the architecture itself. One approach for doing this is to describe important attributes of the building blocks that form the high-level abstraction of the system. The utility of software architectures can increase significantly when such attributes aid analysis. Further, by emphasizing the need to make decisions that affect global system properties early, rather than waiting for the programmers to make locally optimal decisions, it becomes possible to deliver systems that better match user expectations. To illustrate this point, consider the importance of identifying critical algorithms and data structures, communication patterns, distribution profile, need for concurrency and synchronization, and so on, in modern software systems, which tend to be distributed and involve complex interactions among the computing blocks. Unless the basic protocols and frameworks are identified at architecture modeling-time, a number of problems are likely to arise during implementation. Formal representation techniques such as ADLs [1,2,3] allow a more precise description of a system in terms of abstract components, connectors, and configurations. The purpose of having an explicit conceptual architecture is to elegantly represent the system structure and act as an aid in understanding the system. Further, it becomes possible to analyze the architecture for certain properties such as deadlocks, reliability, and performance. However, as discussed above, certain implementation-level decisions regarding components and their interactions may also need to be considered in a concrete architecture. In this paper, we present a practical approach towards reasoning about implementation level decisions of component interactions. It is based on devising a taxonomy of software connectors that, in turn, provides a sound basis for understanding the range of possible interactions. Section 3 presents the proposed approach and Section 4 briefly discusses an illustrative example. Discussion and conclusions follow in Section 5. 3. Motivation and Approach Procrastination is considered a virtue in software design as it enhances design flexibility. However, this virtue can prove to be harmful when programmers, unsure of the impact of their choices in implementing a particular system element, make locally optimal decisions. For this reason, at times the decisions made in the implementation do not fully correspond to those made in the architecture, resulting in a mismatch between conceptual and concrete architecture. It is possible that some of those decisions and abstractions affect global system properties adversely, especially if they are not identified in the overall context of the system. An example of such a property is transactional interaction between components. If choices about the characteristics of transaction management such as nesting, isolation level, concurrency management, etc. are not made in the architecture, the realized system can differ significantly from that expected. This points to the occasional necessity of considering the implementation characteristics of the architectural elements. High-level abstractions with some important implementation details can be used to model the architectural elements. Those elements can then be transformed into physical modules of the realized system while consistently provisioning the architectural properties.1 1 An example can also be seen in the use off-the-shelf (OTS) middleware such as Java’s RMI, CORBA, or COM in the place of custom client-server communication protocols. The above example of transaction-based interaction indicates that decisions made at the architectural level can significantly impact global system properties. Since architectures are composed of components and connectors, it would make sense to identify possible decisions for each of them. Components usually pertain to a specific domain and embody application-specific functionality, while connectors embody component interaction details and can thus be employed across domains. Furthermore, the number and type of components employed in software systems is essentially boundless, while the number of interaction mechanisms is comparatively much smaller. We have thus decided to address the issue of providing the needed architecture-level abstractions in the context of component interactions. To this end, we have focused on the range of choices available for designing the interactions (i.e., the connectors), resulting in the creation of a classification framework and a comprehensive taxonomy of software connectors [4]. The taxonomy identifies various types of connectors (Figure a shows an excerpt of the taxonomy), along with dimensions that characterize the behavior of each connector and the range of values that each dimension can take. Based on this taxonomy, we have found that it is possible to build connectors in a modular fashion where sophisticated connectors are built from more primitive ones. We are studying the construction of connectors as part of the infrastructure for providing message-based component interactions, as well as component wrappers and adaptors in the C2 style [6]. Much work still remains to be done in supporting other types of connectors. We have found that the use of explicit connectors both enables architectural understanding in a manner that is consistent with the actual implementation and supports a modular design of the system. Note that developers of component interoperability (or middleware) infrastructures, such as the one we are developing for C2, can optimize the infrastructures’ underlying characteristics, whereas their users are aware of only the top-level abstractions. By deciding to use an OTS interaction mechanism, architects can increase the reliability of their solutions by enabling developers to focus on application-specific functionality. Additionally, middleware platforms that provide a large number of primitives for use in system development can accelerate the development process.2 However, as the architecture is implemented, it is possible that the underlying middleware platform causes performance penalties. In our specific case, the C2 infrastructure employs messages for component interactions involved in multithreaded processing, and allows control for the secure distribution of messages [6]. C2 style architectures 2 An in-depth treatment of the relationship between middleware on the one hand, and architectures and architectural styles on the other is provided in [5]. make a high-level decision about the use of a particular set of interaction mechanism -- messages. It is possible to enhance system understanding and employ reusable assets in such systems: the underlying infrastructure allows implementation-level decisions to be considered at an architecture level. Better understanding of the overheads involved in messaging has allowed us to optimize the under-performing areas of the connector implementation infrastructure. Protected, persistent data access, globally available Storage Clock People Account Authenticated, encrypted privacy single session security with weight based load distribution Nested, read-write serialized transaction Business Manager Security / Load Balance Teller UI Manager UI Customer UI Graphics Event Graphics Event Graphics Event Graphic Binding Graphic Binding Graphic Binding Central update notification, eacttly once semantics, asynchronous events gure a. Figure a Connector taxonomy excerpt used in making connector choices Figure b A simple banking application with highlighted connector choices An added benefit of the connector classification framework and taxonomy (highlighted in Figure a) is that it allows architects to concentrate on the most important dimensions of a connector for a particular system. Other dimensions can be left for resolution to the developers if the choice of those dimensions is not considered architecturally significant. Since there is a finite range of decisions to be made in the case of each connector, it is feasible to explore each dimension in order to identify its utility in a specific application. Moreover, if implementation support is available that allows choices of various dimensions to be specified as configuration information, the task of system development can be greatly accelerated. Composite connectors built on top of basic a connector infrastructure can support a wide range of decisions regarding the interaction mechanisms, as demonstrated in [5]. In order to validate these hypotheses and support their underlying concepts, we are currently extending the message passing implementation infrastructure for C2-style architectures [6] to provide security, transactional, load balancing and fault-tolerant interactions. 4. Illustrative example Figure b presents the architecture of a simple banking application, designed and implemented in C2. The example illustrates the kinds of important implementation choices, highlighted in callouts, that can be identified in the architecture. In particular, for each connector, a set of specific choices was made, helping the architects to decide whether OTS technologies can be used to perform the required tasks or whether new software solutions need to be developed. In any case, the eventual system can be validated against the original architecture by measuring the identified attributes of the component interactions. A formal representation of such an architecture is provided in an ADL, enabling its automated analysis. 5. Conclusions Architecturally relevant implementation-level decisions need to be represented in the architecture. Our taxonomy of connectors [4] forms a starting point for making decisions about the interactions in which architecture-level components engage. At the same time, our current understanding of the taxonomy is incomplete. Many new connectors can be created through careful combination of dimensions across connector types. For example, it is, in principle, possible to merge a procedure call connector with unicast distribution to form a remote procedure call connector. However, it is unknown as yet which of the original connectors’ dimensions can be merged successfully to create the resulting connector. This comprises a potentially rich research area whose ultimate outcome may be the creation of a handbook of software connectors that can serve as a reference to architects. Furthermore, when using such connector abstractions, it also becomes necessary to create infrastructures that support principled implementation and realization of connectors. Our goal is just such an infrastructure in which a desired connector is configured with the appropriate values for its dimensions and then automatically generated. References 1. R. Allen and D. Garlan. Formalizing Architectural Connection. Proc. 16th ICSE, pp. 71-80, Sorreno, Italy, May 1994. 2. D. Garlan, R. Monroe and D. Wile. ACME: An Architecture Description Interchange Language. Proc. CASCON ’97, Toronto, Canada, Nov 1997. 3. N. Medvidovic and R. N. Taylor, A Classification and Comparison Framework for Software Architecture Description Languages. IEEE Transactions on Software Engineering, January 2000. 4. N. Mehta, N. Medvidovic and S. Phadke, Towards a Taxonomy of Software Connectors, Proc 22nd ICSE, (to appear), Limerick, Ireland, 2000. 5. E. Di Nitto and D.S. Rosenblum. Exploiting ADLs to Specify Architectural Styles Induced by Middleware Infrastructures. Proc. 21st ICSE, Los Angeles, CA, May 1999. 6. R. N. Taylor, N. Medvidovic, K. M. Anderson, E. J. Whitehead, Jr., J. E. Robbins, K. A. Nies, P. Oreizy, and D. L. Dubrow. A Component- and Message-Based Architectural Style for GUI Software. IEEE Transactions on Software Engineering, June 1996.
© Copyright 2024 Paperzz