An aspect-oriented framework for developing ... - Semantic Scholar

10 downloads 24290 Views 670KB Size Report
object-oriented software development techniques have the limitation in reusability by ...... ponents, PhD Thesis, University of Texas at Austin, 1999. [5] G. Helm, I.
Information and Software Technology 46 (2004) 81–97 www.elsevier.com/locate/infsof

An aspect-oriented framework for developing component-based software with the collaboration-based architectural style Joon-Sang Leea,*, Doo-Hwan Baeb a Diznet Group, Digital Media Research Lab., LG Electronics Corp., 16 Woomyeon-Dong, Seocho-Gu, Seoul 137-724, South Korea Department of Electrical Engineering and Computer Science, Korea Advanced Institute of Science and Technology, 373-1 Guseong-dong, Yuseong-gu, Daejeon 305-701, South Korea

b

Received 2 August 2002; revised 4 February 2003; accepted 19 June 2003

Abstract Component-based development (CBD) technique for software has emerged to fulfill the demand on the reuse of existing artifacts. In comparison to traditional object-oriented techniques, CBD can provide more advanced abstraction concepts such as subsystem-level reusability, gross structure abstraction, and global control flow abstraction. Unfortunately, existing software development techniques are not mature enough to make it come true that components developed in the third party can be used in a highly flexible way. It is notable that there are certain kinds of software requirements, such as non-functional requirements, that must be implemented cross-cutting multiple classes, largely losing the modularity in object-oriented design and implementation code. Therefore, it is not easy that components are reused without consideration of their low-level implementation details. In this article, we propose Aspect-Oriented Development Framework (AODF) in which functional behaviors are encapsulated in each component and connector, and particular non-functional requirements are flexibly tuned separately in the course of software composition. To support the modularity for non-functional requirements in component-based software systems, we devise Aspectual Composition Rules (ACR) and Aspectual Collaborative Composition Rule (ACCR). Note that AODF makes component-based software built to provide both supports of modularity and manageability of non-functional requirements such as synchronization, performance, physical distribution, fault tolerance, atomic transaction, and so on. With the Collaboration-Based architectural style, AODF explicitly enables to deal with nonfunctional requirements at the intra-component and inter-component levels. q 2003 Elsevier B.V. All rights reserved. Keywords: Component-based development; Software architecture; Aspect-oriented programming; Collaboration-based design; Non-functional requirements

1. Introduction The evolution of software design and implementation techniques mainly has been focused on how to improve software quality attributes such as modularity, composability, and reusability to construct so-called open systems [1]. Currently, object-orientation seems to best support a software engineering principle, abstraction, e.g. data abstraction, super abstraction, and meta-abstraction as classified in Ref. [2], compared to all other existing techniques. However, it has been often addressed that object-oriented software development techniques have the limitation in reusability by the work related to collabor* Corresponding author. E-mail addresses: [email protected] (J.-S. Lee), [email protected] (D.-H. Bae). 0950-5849/$ - see front matter q 2003 Elsevier B.V. All rights reserved. doi:10.1016/S0950-5849(03)00111-3

ation-based design [3,4] including Contracts [5], SubjectOriented Programming (SOP) [6], Hyperspaces [7], Role components [8,9], Aspect-Oriented Programming (AOP) [10], Adaptive Programming (AP) [11], Adaptive And PlugAnd-Play Components (APPC) [3], and so on. Namely, traditional object-oriented techniques provide quite a high degree of reusability at the class level, but very poor at the level of collaborations among classes. This limitation stems from the fact that class collaborations cannot be encapsulated. Those classes, which are tangled up with behavior necessary to participate in various collaborations tend to be highly dependent on the architectural context. For such a class to be reused in other architectural contexts, it must be analyzed code by code, reusing a set of classes realizing a collaboration requires error-prone tasks taking lot of time and cost.

82

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

Collaboration-based designs are aiming at overcoming the inherent limitation of reusability in traditional objectoriented techniques, and support two types of first-class modeling entities for class and collaboration. Currently, Catalysis [12] and Rational Unified Process [13] are regarded as the prominent software development methodologies for object-oriented systems and component-based systems based on UML. They apparently support collaboration-based scheme during the requirement capturing and design phases, but do not address collaboration-development issues during the design and implementation phases sufficiently. Analogously to collaboration-based design scheme, Component-Based development (CBD) [14,15] approaches usually view high reusability as one of its primary goals, supporting more advanced software engineering techniques such as software architecture and strong black-box reuse. CBD is not an entirely new technology, all the more, a fabric one well composed of various features of the prior software engineering technologies for the purpose of the same fundamental goal: high reusability. An ideal style of software system developments may be that a new reliable software system can be developed by just gluing existing reusable software components, on the assumption that there exists an efficient way to access and retrieve components which are validated already. In CBD, software architecture and strong reuse mechanism based on a black-box style play the major roles of further achieving the fundamental goal of software engineering by means of gross structure and global control flow abstractions, and application-builder level1 reusability, respectively. However, CBD as well as collaboration-based design only takes into account the functional modularity, just leaving good modularity and realization of non-functional requirements be trade-off. In AOP [10], Kiczales et al. address that a software system can be built more modular and efficient by encapsulating concerns that cross-cut multiple kinds of classes in it via aspects. AOP can be viewed as a kind of collaboration-based development technique in the sense that each collaboration can be regarded as an aspect that cross-cuts the set of classes. Off-the-shelf or domain specific components may be often delivered in the form of binary or intermediate codes without any source codes and documents. As a result, it seems almost impossible to customize target components for several particular needs of non-functional requirements. Even rewriting its source codes in a hard-wired fashion may easily lead to the tangled codes incomprehensible or several errors. In addition, the internal structure of off-the-shelf or domain specific components should not be altered permanently for their particular uses in future. AOP can manage those two problematic characteristics of reusable components through both computational reflection and late binding concepts of non-functional aspect. 1 Without any need of manual effort and fully supported by computeraided tool.

Fig. 1. Functional and non-functional decomposition of component-based system behaviors.

As you can see in Fig. 1, CBD components can support the encapsulation of collaborative behaviors crossing multiple components by means of the explicit architectural element, connectors, which enables to explicitly contain and reveal the information about gross structure and global control flows in a component-based system. Thus, the nonfunctional aspects required in a component-based system can be incorporated into behaviors of the entire system from the collaborative viewpoint. In this article, we present Aspect-Oriented Development Framework (AODF) for late and flexibly incorporating a variety of non-functional requirements with the functional behaviors of a target component-based system in a systematic and separated way. The AODF mainly draws its inspiration and techniques from AOP, meta-level architecture, collaboration-based design, software architecture, and CBD. It can help to promote reusability in developing component-based systems by supporting separation of concerns between functional and non-functional aspects. It is notable that AODF enables to explicitly deal with collaborative non-functional aspects as well as intra-component’s non-functional aspects, by considering connector as a higher-level and n-ary composition unit gluing the behaviors of several basic functional units (i.e. component). A collaborative non-functional aspect can be described by programming an Aspectual Collaborative Composition Rule2 (ACCR) as a specific composition mechanism. The non-functional behavior in a connector is not actually tuned in the way a particular ACCR describes until the ACCR has been associated with the connector through Meta-Object Protocol (MOP). 2. Backgrounds 2.1. Software architecture The emergence of a new concept of programming technique usually motivates a lot of researchers and 2 An ACCR plays a role of the aspect program for the connector that is a basic functional unit in component-based systems.

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

practitioners to devise new design methods appropriate to systematically support that programming technique. In this sense, the evolution process of software development techniques can be well understood with the evolution process of programming techniques, as shown in Fig. 2. The evolution process is extended based on the reference model presented in Ref. [2]. In this evolution, the abstraction principle plays a key role. On the paradigm transition from object-oriented programming to component-oriented programming, several additional concepts of abstraction such as real data abstraction [16], gross structure abstraction, and global control flow abstraction [17] are considered. The real data abstraction means that the interfaces of a software module can be defined completely separated from its implementation details, so each software module can be handled as a black box. The gross structure abstraction provides a birdeye view on the overall system, and the global control flow abstraction allows each component to be constructed with as less dependency on application-dependent collaborations as possible. As a result, software system could be well understood, maintained, and reused in other application contexts. These kinds of abstractions can be efficiently realized by employing software architecture. In general, any design method or programming language supporting CBD provides a software architecture, even though it is just a simple one such as pipe-and-filter and implicit invocation. From the middle of 1990s, software architecture has received a great deal of attentions by practitioners, as well as researchers. Unfortunately, there has not been presented any

83

consensual and universal definition of software architecture yet, but can be defined as follows: The structure of the components of a program/system their interrelationships, and principles and guidelines governing their design and evolution over time [18]. During the software development process, software architecture plays a lead role of the template basis with respect to structural and behavioral aspects of the overall system. The software architecture of a component-based software must be traceably preserved throughout its entire lifecycle so that the software could be efficiently understood, reused, extended, analyzed, and maintained at any abstraction level of model by architects or software analysis tools. Also, a software architecture must provide multiple and consistent viewpoints on product just as other engineering disciplines. Essentially, the software architecture should support the structure and interaction viewpoints. In addition, some additional viewpoints should be devised and employed according to the characteristics of target software. The major goal of software architecture is to completely separate design and implementation phases, and to decompose and handle large and complex software into manageable and loosely coupled pieces over the whole software lifecycle. 2.2. Architectural style The style of software architecture can be defined as the following statements: An architectural style is a description of component types and a pattern of their run-time control and/or data transfer. A style can be thought of as a set of constraints on an architecture-constraints on component types and their interactions and these constraints define a set or family of architectures that satisfy them [19].

Fig. 2. The evolution process in programming techniques.

An architectural style defines a type of architectural instances sharing much of commonality in terms of both structural and behavioral aspects. There is no discrete boundary between architecture and architectural style as addressed in Ref. [17]. Architectural style is the abstract and general representation against relatively concrete software architecture. In other words, they could be discriminated from each other with the relative relation of abstraction levels. Until now, there have been presented several common architectural styles such as Pipe-and-filter system, Layered system, event-based system, repository-oriented system, blackboard-oriented system, object-based system, tabledriven system, client-server system, and so on. Those styles are widely used in modeling architectural designs in either a formal or an informal manner. The architectural style

84

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

typically defines a set of vocabulary as core architectural elements, constraints among them, and rationale. Chiron-2 (C2) [20] is an event-based architectural style, devised for building GUI software. C2 regards both component and connector as explicit architectural elements, where the component is the architectural element that is active and concurrent, and on the other hand the connector binds a collection of components and asynchronously routes the in-coming events from its top-side ports to all architectural elements listening to its corresponding bottom-side ports. This kind of communication scheme among architectural elements free the client component from the responsibility for event routing based on observer pattern [21]. It is often called implicit invocation in contrast to explicit invocation that is a typical communication fashion in traditional software modules. As the result, the inter-dependency between the requesting components and the notifying components comes to be less dependent, on the environment context. The definition of C2 architectural style was formalized using Z in Ref. [22]. The formalization of a particular architectural style can be very important to analyze some properties in an architectural instance. Otherwise, the definition of a specific software architecture style must be sufficiently complete with a sufficient amount of unambiguous descriptions in a semi-formal or even informal style. As in case of C2 architectural style, a well-defined software architecture style assists and enforces architects to build large and complex software systems that obey all essential properties a corresponding type of software architecture describes, and also enables to reason about some useful properties for verification. We will propose a software architectural style: CollaborationBased style (CB-style) in a semi-formal way, with which a software can be built, managed, and analyzed efficiently with respect to modularity and non-functionality. 2.3. Collaboration-based developments In the beginning, the necessity of separating intra-class behaviors and inter-class behaviors is explicitly recognized by Helm in Contracts [5]. That work presents a specification

language that allows the behavioral composition between a collaborative protocol (defined as a contract) and a class behavior, where they can be specified in a totally separated way. In addition, for modeling efficiency, it presents the white-box and black-box reuse mechanism for contracts. In SOP [6], the subjectivity in object-oriented systems is made emphasis on by Harrison and Ossher. It is the core description that each object could be viewed variously by the subjects, so it should provide an appropriate set of services according to the subjects. As for SOP, a message sent to a class is automatically bound to a concrete method body in a fashion polymorphic to what subject the message is sent. Importantly, SOP distinguishes the intrinsic behavior and extrinsic behavior of each class when constructing models. Roles and role model [8] separate the role hierarchy from the class hierarchy, so that reusability and dynamic evolvability are remarkably improved in object-oriented systems. In AOP [10], Kiczales et al. address that a software system can be built more modular and efficient by cross-cutting several important aspects. In general, AOP enables to provide separation of concerns among various aspects such as functional and non-functional behaviors, internal computation and collaboration, and so on by adapting the crosscutting principle for the programming main concerns. AP [11] and APPC [3] make the behaviors in an object-oriented system rarely sensitive to the changes of its structure by employing Visitor Pattern [21] as the conceptual architecture. In addition, since AP and APPC provide separation of concerns between internal computations of classes and their collaborations by defining all collaborations as the behaviors of visitors in Visitor Pattern. As a representative implementation-level support for collaboration-based design, Seiter et al. extend the syntax of ordinary Java language with Context relations in Ref. [23]. The context relation provides the syntax and semantics necessary to update the behavior of individual object dynamically in terms of instance method and collaboration. As a prior work similar to our approach, Netinant et al. [24] proposed a layered approach to building open aspect-oriented systems. That approach provides a functional abstraction based on the layered architecture in building software systems, and also the openness for adapting

Table 1 The comparisons of collaboration-based developments

Contracts SOP AOP AP APPC Role Software architecture CB-style

Collaboration unit

Core behavior unit

Separation of concerns

Contract Subject Aspect Adaptive method Inlined-adaptive method and main methods Role model Connector

Class Operation Component Class Class

Collaboration and core behavior Intrinsic and extrinsic behaviors Various aspects Structure and collaboration Structure and collaboration

Class model Component

Role and class Structure and behavior and interaction

Connector

Component

High-level collaboration and internal computation

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

85

Fig. 3. Meta-model of CB-style software architecture.

a variety of cross-cutting concerns on non-functional requirements in terms of intra-layer and inter-layer. The above work can be compared as shown in Table 1. In contrast to other technologies listed in that table, the software architecture can provide the corresponding separation of concerns explicitly or not, and entirely or partially, depending on the definition of a particular software architecture.

3. Collaboration-based architectural style A component-based software may be built with one of the well known, or explicitly defined architectural styles, and then can be effectively comprehended by software analysis tools or architects in a highly abstract way. We propose a new software architecture style called Collaboration-Based style (CB-style). CB-style defines all of the constraints, guidelines, principles, compositions, and properties of the architectural elements necessary to construct a component-based software system with the concept of collaboration-based designs. It provides the support for an explicit separation of concerns between intra-component and inter-component behaviors. In this section, we represent the characteristic properties of CB-style software architecture by means of the metamodel described with Object Constraint Language (OCL) [25]. Finally, to demonstrate how well a CB-style software architecture works as designed, we present a simple example built in CB-style.

3.1. Components and connectors The software architecture of CB-style is instantiated based on all structural relations and constraints defined in its meta-model (Fig. 3). The key architectural elements of CB-style are the component and connector. From the viewpoint of a connector, both the two types of architectural elements can be viewed as the same kind of architectural elements, each of which may be bound to some roles3 owned by the connector. In contrast to C2 architectural style [20] where the connector is a passive architectural element that initially has no responsibility for its own collaborations and threads of control, the connector in CB-style may have threads of control, a state, and a type as a subject entity. The component implements its operations for providing its functionality, but every architectural element outside the component is not allowed to look into the implementation detail of each operation directly. Before accessing to the functionality of operations, a channel linking the out-going interfaces of a requesting element with the in-coming interfaces of a requested element must be established beforehand. After establishing such a channel, all of the corresponding events that occur in the requesting element are implicitly dispatched to one or more number of requested elements for invoking appropriate operations. This kind of communication scheme is based on observer 3

Here, each role actually means both the provision for a particular set of in-coming and out-going interfaces, and the support of properly responding collaborative protocols in the connector.

86

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

pattern [21], or implicit invocation. We vest both component and connector to have their types. In contrast, several component-oriented programming languages and architectural description languages do not support their own type theory, trading model simplicity and verifiability with such potential benefits as composability, substitutability, and reusability sufficiently as expected in the component-based system built with an explicit software architecture, as noted in Ref. [26]. So, to preserve those potential benefits, a software architecture should be described in terms of component types or component classes (conceptual component) on the basis of existing type theories such as object-oriented typing, rather than concrete components. The in-coming and out-going interfaces enable for a program module to be constructed without consideration of what type its expected client program modules are, and what type its expected server program modules are, respectively. As a result, program modules that have been independently developed by various organizations can be composed at application-builder level by just wiring out-going interfaces and in-coming interfaces. Unlike conventional program modules that only provide in-coming interfaces, the architectural elements of CB-style can be constructed in a more modular way by using the two types of interfaces. The in-coming interfaces associated with a particular operation in a software component have causal dependency on the corresponding types of out-going interfaces. The causal dependency from in-coming interfaces to out-going interfaces is described and used for analyzing the control dependency among operations at the software architecture level. Such causal connections could be captured by using primitive meta-level operations provided by a particular programming language or a component writing standard. However, for the sake of either simplicity or efficiency, that kind of meta-level information can be directly reified from a concrete component-based system by implementing the appropriate high-level meta-operations. On the basis of the meta-model depicted in Fig. 3, the constraints on components and its related entities can be defined in a semiformal way, as listed in Table 2. As another key architectural element, a connector has the similar properties to the component for the most parts. However, in contrast to the component, the connector is an active architectural element that initially has responsibility for its own collaborations and threads of control, and bind components or other connectors together into a CB-style software architecture as a high-level compositional unit. Since the connector is also the first-class modeling entity like the component in a CB-style software architecture, it plays the role of coordinating collaborative protocols, if needed, keeping its own state in terms of various aspects as well as simply gluing between components. In this sense, the connector of CB-style is defined to be taken a first-class status, as addressed in Ref. [27]. A connector has a set of collaborations, instead of operations, for implementing its

Table 2 The descriptions of CB-style constraints with OCL (a partial view) State state ! transit( f: Function): Boolean True if both Function f is terminated correctly, and State state is changed according to the result of performing that Function f. Function function ! perform( ): Boolean post: result ¼ function.element.state ! transit(function) Function Function ! fireEvent(e:Outgoing_Event): Boolean pre: Function.element.functions ! exists(function.out_events ! includes(e)) and e.interface.in_port , .NULL and e.interface.in_port.sinks ! forAll(i: Incoming_Interfacel i.out_pair.oclIsTypeOf(e.interface)) post: result ¼ e.interface.in_port.sinks ! for All(i: Incomming_Interfaceli.event.functions ! for All( f: Functionlf ! perform( ))) Channel self.source.event.functions ! for All( f:Functionl f.ocllsKindOf(Component) implies self.sinks ! forAll( inf:Incomming Interfacel inf.event.functions ! forAll( f1: Functionlnot f1.oclIsKindOf(Component)))) Software_Architecture self.elements ! exists(e:Architectural_Elementl e.oclIsTypeOf(Connector) and self.elements ! select(e:Architectural_Elementl e.oclIsTypeOf(Connector) ! exists(c:Connectorl c.collaborations ! exists(cb:Collaborationl cb.thread ,. NULL))

own coordinative behavior. Each collaboration initially has either one or no thread of control, and there must be at least a collaboration that has its own thread of control as well. Basically, a component-based system built in CB-style is to have one or more connectors in order to construct a minimal structure. An association class in either object-oriented analysis or design model defines several properties that are necessary only while its related association link is available. Those properties would usually migrate to some parts of the associated classes in the detailed design model or implementation model, even though they should be owned by neither one of the two classes in order to avoid low cohesion and high coupling modules. An association class describes several states only to which the collaborative behavior may run sensitively, therefore within a software architecture using CB-style it must be designed and implemented into a connector that coordinates their aggregated components. On the basis of the meta-model shown in Fig. 3, those constraints related

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

to connectors can be partially described with OCL expression, as listed in Table 2. Although the definition of CB-style presented above is not sufficient for its precise description, we think that the definition given here is sufficient to explain our idea throughout the paper.

87

a transaction, aborting a transaction, and so on. When a requested transaction service fails or explicitly is aborted by invoking a transactional primitive abort, the system state is restored automatically to the state before the transaction started. In Section 4.3, this issue is explained as an intercomponent non-functional aspect in detail.

3.2. Composition and communication In order to allow two active program modules to interact with each other, one of them must be, at least in an instant, in an inactive state while they are actually interacting together. Thus, for a smooth, efficient, and safe execution of a component-based system, it is desirable that architects can arrange architectural elements in a way of alternating active and passive software components. In CB-style, components are the architectural elements that are initially in the passive state, and also can be in the active state by external requests until the reaction to the request ends. In contrast, connectors are the architectural elements that include zero or more active collaborations, so they can have their own threads of control, and may be usually in the active or blocked state. Consequently, CB-style does not allow to make the inactive architectural elements (i.e. components) directly interact with each other. In other words, a CB-style software architecture is built in a way of mainly linking components with connectors, or connectors with other connectors according to the topological constraint of CB-style. Thus, a CB-style software architecture can fundamentally help to construct a component-based system in such an interleaving way of composition, but not enforce such an architectural composition fashion. Connector takes the role of owning the references to its aggregated architectural elements, which can be components or other connectors. A connector establishes channels between the interfaces of the aggregated architectural elements and its interfaces and controls the collaborative behaviors among the aggregated architectural elements. There would be multiple threads of control while a component-based system is running. For the sake of making such threads to perform both efficiently and correctly as expected in its design specification, it is necessary to manipulate such threads of control in an appropriate way according to the type of architectural elements. Since component-based systems bear many analogies to objectoriented systems with respect to communications, compositions, structural aspects, etc. it would be quite reasonable to synchronize threads of control in the two types of architectural elements via monitor [1,2]. However, the connector encapsulates a set of independent, concurrent, and explicit execution units, i.e. collaborations. So, it allows a straightforward implementation in which all initially active collaborations in connectors are synchronized by means of atomic transactions [28]. In this case, all concurrency controls in an application can be handled by only transactional primitives such as for beginning a transaction, ending

3.3. A simple CB-style application: horizontal-edges image processing system We present a CB-style component-based software system that realizes the horizontal-edges image processing application borrowed from Ref. [10], but with the different intention and reason. This application provides the functionality of extracting only the horizontal-edges from a given image data. Its collaboration diagram representing the CB-style architectural design is shown in Fig. 4. In the collaboration diagram, the causal dependency between incoming interfaces and out-going interfaces is omitted for simplicity, and instead the internal computation notes4 attached to the connectors imply such information indirectly. There exist two distinct collaborations that can run independently in that collaboration diagram. In order to bring out the horizontal-edges from a given image, the collaboration horImage(Image) in the connector Horizontal-edges implicitly invokes the two sub-collaborations: topImage(Image) and bottomImage(Image) in other connectors: Top-edge and Bottom-edge, respectively. Such aspect can be modeled to run concurrently in the collaboration diagram by design decisions. The source code of the component-based system presented in Fig. 4 is listed in Fig. 5, stripped out of the Java introspection-related code. Throughout this article, we use JavaBeans [29] as a component writing standard. In the constructor of a CBstyle component-based system SimpleImageProcessingSystem, its architectural elements are instantiated, and then the configuration among them are established up all. The statements for firing out-going events are implemented in a fashion of two-way communication scheme that always requires a return value. Thus, if there are multiple number of clients that are registered as observers in order to respond to the occurrence of a specific type of out-going events from a server component, the number of the return values resulted from the fired event become to be one or more. To deal with this situation, the event communications are by default implemented to select the first one among the arrived return values and pass it to the server component. This kind of strategies can be variously

4 The notes associated with the connectors state the coordinative responsibility for the corresponding collaborations.

88

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

Fig. 4. Collaboration diagram for horizontal-edges image processing system.

modified by applying an appropriate Aspectual Composition Rule (ACR) to the target collaboration or operation. The component-based system shown in Fig. 5 represents only functional aspects, and it can naturally meet the requirements of a desired-level 5 modularity and understandability. The source code written in CB-style is implemented in a Java language simply extended with four new keywords: Connector, Component, Collaboration, and Operation, and can be systematically translated into the ordinary Java code via OpenJava [31,32] translator. Those extended keywords help much in building component-based systems and programming ACRs in CB-style, by explicitly defining the types of architectural elements and functions at the programming language level. The keywords are used to examine whether a component-based system is written in CB-style or not, and provide useful information from the point of ACRs. 5

To an extent that program modules can be constructed so loosely coupled with aids of separation of concerns between intra-component computations and inter-component collaborations, and also between functional and non-functional aspects.

4. Aspect-oriented development framework The main goal of the integration framework for software composition is to support separation of concerns enough to deal with non-functional aspects and functional aspects, if possible, at an application-builder level. Unfortunately, most of the existing techniques for developing component-based systems do not support such advanced separation of concerns at the software architecture level. At most, they provide a support for acceptable-level6 reusability through the advanced notions of software architecture and strong black-box reuse. This section presents Aspect-Oriented Development Framework (AODF) that promotes modularity and understandability as well as allows to incorporate nonfunctional aspects in a flexible way through modular composition. 4.1. Overview The overall structure of AODF for developing component-based systems is shown in Fig. 6. In AODF, 6 At least, support for separation of concerns between intra-component and inter-component behaviors.

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

89

Fig. 5. A CB-style implementation of the horizontal-edges image processing system.

non-functional aspects can be additively weaved with the functional behaviors of components and connectors by the proposed two-layered approach as shown in Fig. 6. After an architect has constructed a component architecture, the behavior of each architectural element can be tuned with a variety of non-functional requirements. The first layer plays the role of incorporating non-functional aspects into each component. In the first layer, the internal structure of the component such as the basic strategies of internal computations can be modified just as in Open Implementation (OI) [33] by defining ACRs. The second layer plays the role of incorporating non-functional aspects into each connector. In the second layer, each connector is considered as a high-level and n-ary extension of the composition unit, and its collaborations are appropriately tuned by defining ACCRs. ACR is a generalized and primitive form of ACCR, in that ACR handles binary composition rules. On the other hand, ACCR handles n-ary composition rules encapsulating higher-level and more complicated non-functional aspects.

Thus, we call ACRs dealing with non-functional aspects for collaboration, ACCRs. Maybe, architects mainly develop a set of connectors for software composition rather than each component, thus they are more focusing on ACCRs to incorporate application-specific non-functional requirements into those connectors. The shaded rectangles in Fig. 6 mean the architectural elements containing both functional and non-functional behaviors. It is notable that consequently, we can deal with collaborative non-functional aspects as well as isolated non-functional aspects of the component or connector into the entire component architecture in an additive and separated way, i.e. in an aspect-oriented way. Hierarchically, a partial component architecture that does not need to interact with and depend on other architectural elements for the completion of requested jobs can be regarded as a larger-grained component with the interface provided by its connectors. A variety of ACRs would be delivered along with the corresponding component or

90

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

Fig. 6. The overall structure of aspect-oriented framework.

component sub-architecture (a connector aggregating several components), or newly defined and applied by component assemblers or architects during the software composition. In traditional object-oriented development techniques, MOP [34] is used as a key mechanism to separately handle functional and non-functional behaviors and also weave them systematically via meta-class hierarchies. With respect to the structural aspects such as entities, relationships, types, constraints, and so on, component-based systems have so many analogies to object-based systems, except that the basic functional unit is not object, but component and connector. These kinds of analogies enable to directly use MOP as the weaving mechanism of non-functional aspects in a component-based system; a set of ACRs can be sequentially composed into an ACR based on the concept of the metatower in MOP. For example, ACR1 for method synchronization and ACR2 for method scheduling can be composed into ACR3 for method synchronization and scheduling by making the sequential composition from ACR1 to ACR2 : We define a set of composition rules between ACRs as follows: association ( ) ) is an operation signature ),r;elm;r_elm. : ACR £ AE7!AE for function returning r_elm as the result of weaving the non-functional aspect defined in the ACR rð[ ACRÞ into an architectural element elm: sequential composition (†) is an operation signature †,r1 ;r2 ;r3 . : ACR £ ACR ! ACR for function returning a new ACR r3 as the result of making the sequential composition from r1 to r2 : The well-formed ACRs (WF7

Architectural element.

ACR) should satisfy the following constraints. All ACRs to be actually implemented should be designed as a form of WF-ACR for the purpose of their safe sequential compositions. (1) Iððr1 †r2 Þ ) elmÞ ¼ Iðr2 ) ðr1 ) elmÞÞ: (2) Iððr1 †r2 Þ†r3 Þ ¼ Iðr1 †ðr2 †r3 ÞÞ In general, meta-level programming requires to handle a greater deal of complexity than base-level programming, since it usually includes very complicated computations such as transformation from language expressions to data, and vice versa. So, it would require much effort to implement an ACCR, despite such advantage that nonfunctional aspects can be dealt with in an aspect-oriented way. In order to realize AODF at the application-builder level, it is necessary to provide a support for higher-level abstraction in programming ACCRs. A refactoring is a parameterized behavior-preserving program transformation that updates an application’s design and underlying source code [39]. A particular refactoring method includes a set of operations that have been already proven never to make any change in terms of the system’s functional behaviors. After being applied to a target system, a refactoring method results in making the target system restructured satisfying several non-functional requirements. Thus, a designer can safely restructure a target system for several new nonfunctional requirements by applying a sequence of the operations to the target system, still preserving the behavioral equivalence. Similarly, ACCRs describing nonfunctional aspects do not and should not make any effect on

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

91

the functional behaviors of a component-based system; an ACCR can be defined as a sequence of behavior-preserving operations in a safer and more abstract fashion. More detailed discussion about this issue will be discarded here. 4.2. Intra-component non-functionality The intra-component non-functional aspects deal with only the meta-level strategies for internal computations. Within a component, we may need some operations each of which implement a different computational strategy. Some examples of such computational strategies are as follows: † logging particular traces run by a thread of control to debug some errors † writing several mutual exclusion properties on the attributes or methods, and scheduling policies on threads or methods This kind of meta-level strategies could be implemented by inserting some additional codes into components by hand, invasively. However, in that case, it may not be so easy to understand what functions such components provide, and to reuse such components in other component-based applications by cutting out only desired portion from the tangled source code of a target component and then tailoring them appropriately. The way of handling this kind of non-functional requirements can be well realized by employing OI technique. The main goal of OI is to acquire higher reusability beyond the conventional black-box abstractions [33] by providing an effective means to access and modify several implementational information. OI defines software modules, externally providing two types of interfaces: baselevel interface8 and meta-level interface.9 Meta-level interface enables for users to reify and make several modifications on the particular internal structure of software modules, so that the software modules delivered to users can be flexibly customized according to the user’s flavors. In object-oriented systems, meta-classes reflect such internal structures of their instance classes, and provide several meta-level interfaces by defining their methods. In a very similar fashion to the object-oriented systems, we can deal with component’s non-functional aspects at this stage by declaring meta-relationships for component classes or types. 4.2.1. Internal concurrency of components As in object-oriented systems, the synchronization for each operation in a component-based system can be specified as a constraint expression consisting of state 8 This kind of interface plays the role of conventional interfaces, and preserves the benefits of black-box abstraction. 9 Meta-level operations which modify the internal strategies in software modules are invoked through meta-level interfaces.

Fig. 7. Java constructs needed for component synchronization.

conditions, and then directly implemented by simply inserting several code with the language constructs such as waiting-notifyAll of Java into the original body of operations. For illustration, as shown in Fig. 7 a Java component A has two attributes: int a, b, and an operation: int c( ). If the synchronization constraint of the operation c is a . b, the modified operation c is presented in Fig. 7. If the target method has a return value, the notifyAll( ) statement should be placed immediately after the statement for invoking the target method instead of being inserted at the end of the target method. Considering the issues presented above, we can write an ACR for handling internal concurrency of components or connectors appropriately. The concrete ACR is represented as a meta-class, and its description is omitted here. 4.3. Inter-component non-functionality Notably, a component-based system that has been developed based on a well-defined software architecture encapsulates its global control flows with a first-class modeling construct: connector. The used architectural style may define how to encapsulate and compose the big picture of the component-based system. When it comes to the comprehension of legacy software system for the sake of reusing or maintaining it, such the component-based system explicitly provides the explicit facilities to deal with the global control flows apparently. In contrast, the conventional object-oriented systems may disperse the behavior of every collaboration over the classes participating in the collaboration, and unfortunately make developers who are trying to understand how the object-oriented system works come to be fallen in a maze of the blurred global control flows in the object-oriented system. The encapsulation of collaborations in a component-based system enables to promote the reusability of components and connectors, and also to deal with collaborative non-functional aspects (intercomponent non-functionality) effectively. In a CB-style software architecture, connector can be considered as a type of high-level composition unit that connects basic functional units: component and connector, to compose and coordinate collaborations in the form of nary relationship. In contrast to a simple procedure call that is

92

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

just a binary composition unit, the connector plays a role of realizing collaborative protocols having its own state, as well as just wiring components together. Thus, the captured collaborative non-functional aspects can be well weaved into the functional behavior of connectors by newly defining or modifying the composition mechanisms, that is called Aspectual Collaborative Composition (ACC) in AODF. In this section, we present four typical examples of collaborative non-functional aspects and explain how they can be incorporated into the functional behaviors of a component system by means of ACCRs. 4.3.1. An optimizing policy to increase the degree of concurrency The connector coordinating a set of use-case level collaborations encapsulates the collaborative protocols and also serves as a partial but easily composable map capable of keeping track of the global control flow over the related primitive computations. Thus, the connector and its dependent connectors can be well optimized from the perspective of the global concurrency according to the diverse optimization policies. In other words, the potential concurrency inherently existing in the use-case level collaborations can be systematically identified via explicit types of the architectural elements and functions, and then realized in the implementation code of the component-based system by restructuring its code arrangement. We present an exemplary ACCR for increasing the degree of concurrency in connectors. The definition of this ACCR is summarized in the following two-phase process: (1) By making all event firing statements in a target collaboration and its underlying10 collaborations work in an asynchronous fashion, the observing architectural elements can receive the event without any sequential dependency. (2) After analyzing the dependency among the statements within the target collaboration and all of its calleddependent functions, the statements are grouped into a set of concurrent segments each of which can perform independently. The concurrent segments are newly disposed so as to increase the degree of concurrency within the connectors, still keeping the entire system consistent, in other words, without making any sideeffect on its functional behaviors. Let us see the basic implementation code of the connector Horizontal_edges presented in Fig. 5 once again. If the number of clients that is responding to a specific type of event firings within the connector is two or more, the connector takes the first-position element from a result vector by default. This simple design decision may be unreasonable in terms of system performance. For instance, if each client has 10 That means all entities that are casually related to it when a collaboration or operation is called.

a variation in response time, it would not be efficient for the connector to wait until all of the other responses arrive. Moreover, even if such a first-position element is not valid due to some hardware faults, the connector should be able to admit the result of firstly arrived element. To cope with the above problem, the ACCR is defined so as to take only a result event that arrives first without any extra-latency time. Consequently, the ACCR makes all collaborations causally related to a target connector perform as concurrently as possible, keeping its system consistent. A CB-style software architecture explicitly shows the causal relationship of events among the architectural elements. So, inter-element control/data dependency, i.e. def-use relation between statements, can be effectively, without high complexity of analysis, analyzed at the software architecture level by using some inter-class dependency graph, i.e. CIDG proposed in Ref. [30]. The result of analyzing def-use relations in the connector Horizontal_edges and its underlying elements reveals all possible sets of statement segments that can run independently of each other, as shown in Fig. 8. As the result of the inter-dependency analysis among the statements, the set of statements marked with A; and the set of statements marked with B can run independently. The ACCR plays the roles of detecting those concurrent sets of statements, and restructuring them to perform concurrently preserving the original behavior (Fig. 9). The precise semantics of the relations used in the ACCR are omitted here for simplicity. In the implementation of the ACCR with OpenJava 1.0 [31], the statements in a collaboration reified as a class OJMethod can be logically viewed as a list of statements, so it is possible to change the execution order of statements, and to add or delete several Java statements. In addition, since OpenJava provides a complete support for meta-level architecture [35], each statement in the collaborations can be dealt with at the parse tree level. 4.3.2. Fault tolerance A component that would be used to build various component-based applications could be implemented into a diversity of concrete products by either the different component vendors or the same component vendor. This diversity may come from the heterogeneities in implementation language, run-time platform, specific technology used, or the version of component product, and so on. In case that faults of a software system are so critical that their resulting effects could make the entire software system work totally invalid, n-version programming technique [36] is often used for dealing with such fault tolerance issue. However, although each component used in a component-based system is correct in terms of its logical functionality, such fault-tolerance issue may still remain problematic. If the run-time environment consists of several distributed computers, network lines, and TCP/IP socket packages, the same components could return the different or erroneous results due to the faults of the hardware and

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

93

Fig. 8. def-use relations in the connector Horizontal_edges (a partial view).

network, or the errors of other underlying software packages. This kind of fault tolerant property can be weaved into the behaviors of components or connectors through ACCRs that alter how to deal with receiving, processing, and returning the results of a specific type of event firings. In case of JavaBeans, components communicate with each other based on the delegation event model

of Java, thus some commonalities in the event firing operations could be found. For instance, if there are more listener components to a server component than expected in the normal usage pattern, the server component may be designed to deal with such problem by ignoring extra responses, choosing only one response thought of as the best valid response, or reasoning out a new valid result from all

Fig. 9. The result of applying the concurrency-increasing ACCR to the connector Horizontal_edges.

94

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

Fig. 10. Internal architecture for event firing parts in the components.

responses. In most Beans components, such handling may be implemented in the form of conditional statement such as if-then-else or switch in the immediately following part of event firing statements. Architects (component assemblers) could systematically modify those behavioral parts by describing an appropriate ACCR and then applying it to a target architectural element without making any hard-wired code modification, if all of the event firing operations are constructed according to the pattern depicted above. We define an internal architecture for event firing parts in a CB-style software architecture to handle the fault tolerance issue in a fashion of n-version programming. As shown in Fig. 10, the internal architecture describes and restricts a component writing pattern for event firing parts concretely so that architects can liberally modify the policy of dealing with such fault tolerance issue in the course of software composition. All components and connectors in the Horizontal-edges Image Processing System presented in Fig. 5 are developed without any consideration of the issue of fault tolerance. Assume that an architect is delivered several off-the-shelf or domain-specific components from a third party. After

Fig. 11. The result of applying the fault-tolerance improving ACCR to the connector Horizontal_edges.

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

architects build the entire system up out of those architectural elements, they may customize the fault tolerant aspect within each architectural element by writing and applying an appropriate ACCR. For instance, applying an ACCR that describes how to elect a response among all arrived responses according to the principle of majority rule to the connector Horizontal_edges shown in Fig. 4 results in the transformed code as listed in Fig. 11. 4.3.3. Atomic transactions A distributed system may include a lot of concurrent processes running on physically or logically isolated computers, and also some probability of faults in the associated computers and network lines. For keeping such processes to run correctly and consistently, many synchronization schemes such as Semaphores, Monitors, Messages, Signals, Locks, Barriers, etc. have been developed so far. Each of those synchronization techniques may provide the best solution within a respected situation. However, they just handle the issue of process synchronization in a very low-level fashion, although several high-level synchronization schemes such as Monitors and Barriers are used to implement higher-level constructs for collaborative synchronization. Atomic transaction can help to realize very high-level synchronization behaviors without any consideration of lowlevel details on a specific synchronization mechanism, and also it provides a good support for fault handling by using recovery or shadow blocking [28], preserving so-called Atomic Consistent Isolated Durable (ACID) properties. The required primitives for atomic transactions can vary depending on the specific run-time environments and products. However, the most widely used set of those primitives generally includes the following three primitives: BEGIN_TRANSACTION, END_TRANSACTION, and ABORT_TRANSACTION. As a high-level synchronization scheme, atomic transactions is so straightforward and appropriate for controlling

95

multiple threads of control running on a CB-style architecture, since the granularity of synchronization unit of atomic transaction is very similar to that of the unit of collaborations in connectors with respect to both structure and semantics. The language construct for defining collaborations encapsulated in connectors is just a good joint point where the non-functionality: synchronization and fault handling can be weaved with the functional behaviors of connectors and tuned according to the intention of component assemblers. What the ACCR that handles atomic transactions in a component-base system must do is just to augment the appropriate keywords provided by a particular atomic transaction technology such as Microsoft Transaction Systems (MTS) and Enterprise Java Beans (EJB) on the target collaborations. 4.3.4. Remote communications Distributed computing system means a special type of software systems which have several isolated processes with different address spaces and allow cooperation through message passing. In similar to object-oriented systems, component-based systems run in a distributed computing fashion. In distributed computing systems, there could be two categories: logically distributed systems and physically distributed systems [1]. The physically distributed systems satisfy not only the basic properties of distributed computing systems but also several additional properties, for example, its constituent processes must be deployed on designated sites that are remote from one another. Thus, in contrast to the logically distributed systems, they must be designed to deal with physical phenomenon such as network communications and partial faults of system hardwares. The role of middlewares, such as Java RMI, DCOM, CORBA, and so on, is to bridge the gap between the logically and physically distributed systems. They support distribution transparency for a distributed computing system by adding a layer among interacting processes to realize its logical

Fig. 12. A composite hierarchy example in a CB-style software architecture.

96

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97

computations in the real physical environment transparently. A facility for such distribution concern could be developed within a given component writing standard, and so non-functional behaviors for physically remote communications are implemented within each component. However, this kind of non-functional aspect is not for individual components but for the set of interacting components. Therefore, it is more reasonable that such non-functional behaviors should be implemented within connectors rather than components. There is a composite hierarchy among architectural elements in a CB-style software architecture, as shown in Fig. 12. A connector may take several components and connectors as its constituents, but all components do not have any lower part. The composite elements are responsible for deploying their lower constituents and dispatching the remote messages between them. This semantics or role is very similar to that of composite aggregation of UML extended for specifying distributed object-oriented systems in Ref. [37]. The collaborative non-functional aspects related to all connectors and components except the top-level architectural elements (i.e. conceptual elements) are dealt with in their aggregating connectors. Since conceptual element is usually in contact with human actors or other sub-architectures, their remote communications may be managed by actors and by the aggregating connectors in other sub-architectures. In the former case, the human actor can play the role of deploying the top-level connectors on appropriate sites and cooperating with other component-based applications.

5. Conclusion We have proposed an AODF for component-based software systems, with which a component-based software can be constructed so as to support separation of concerns on non-functional aspects as well as intra-component and inter-component functional aspects. In a component-based software, AODF enables to encapsulate intra-component behavior with the component, and inter-component behavior with the connector by means of the CB-style. In addition, several kinds of non-functional aspects to be considered when building distributed systems can be developed encapsulating intra- and inter-component nonfunctional aspects in AODF. Apart from AODF, employing which kinds of component writing standard and architectural style could largely affect the degrees of reusability, composability, and maintainability in component-based software. And, the way of incorporating various non-functional aspects into functional behavior may lead to a great deal of complexity and productivity in building and maintaining componentbased systems. For higher reusability, it is necessary that components should be developed with as less consideration of the architectural context as possible. AODF helps in incorporating various non-functional aspects into

the behavior of a target component-based system in the course of software composition. AODF requires a fullsupport11 for reflective architecture providing both structural and behavioral reflections. However, unfortunately there has been neither a component writing standard nor a programming language which completely provides such reflective architecture at runtime, except for several Java extensions such as Javassist [38] that support structural reflection at the load time but do not provide the reflective architecture at the fine-grained level, i.e. at the statement level. Therefore, to illustrate how well this framework works, we temporarily use OpenJava [31,32] as a reflective language completely providing a full-support reflective architecture at the compile time. We believe that some component writing standard or programming language that supports a full-support reflective architecture at runtime will certainly emerge in the near future. This work has not been completed yet itself, but we believe that it is an important step to guiding what features component writing standards and architectural styles should provide to effectively deal with intra-component behavior, inter-component behavior, and non-functional behavior in component-based software developments. To make our approach more practical and useful, we are developing a prototype development tool for supporting our approach in a very similar form to Beanbox12, in order to help systematically incorporate and customize component non-functional behaviors at application-builder level. To do so, the way of writing ACCRs needs to be abstracted up to either the design-level or application-builder level by employing some technique such as refactorings [39] in our approach. In other words, each ACCR can be described and developed as a sequence of refactoring rules whose applications have been already proven to preserve system behaviors with respect to the pure functionality.

References [1] P. Wegner, Dimensions of object-oriented modeling, IEEE Computer 25 (1992) 12–20. [2] P. Wegner, OOPS Messenger, A Quarterly Publication of the SIGPLAN 1 (1990). [3] M. Mezini, K.J. Lieberherr, Adaptive plug-and-play components for evolutionary software development, Proceedings of International Conference on Object Oriented Programming Systems Languages and Applications, ACM Press, New York, 1998, pp. 97–116. [4] Y. Smaragdakis, Implementing large-scale object-oriented components, PhD Thesis, University of Texas at Austin, 1999. [5] G. Helm, I. Holland, D. Gangopadhyay, Contracts: specifying behavioral compositions in object-oriented systems, ACM SIGPLAN Notices 25 (10) (1990) 303 –311. 11

Support for both reification and deification capable of not only a specific language-level access control but also unrestricted access control [15] for low-level services. 12 A Java-implemented tool that provides a support for composing Beans components at application-builder level.

J.-S. Lee, D.-H. Bae / Information and Software Technology 46 (2004) 81–97 [6] W. Harrison, H. Ossher, Subject-oriented programming (a critique of pure objects), ACM SIGPLAN Notices 28 (1993) 411–428. [7] P. Tarr, H. Ossher, W. Harrison, S. Sutton, N degrees of separation: multi-dimensional separation of concerns, Proceedings of International Conference on Software Engineering, 1999, pp. 107–119. [8] M. VanHilst, D. Notkin, Using role components to implement collaboration-based designs, Proceedings of International Conference on Object Oriented Programming Systems Languages and Applications, ACM Press, New York, 1996, pp. 359–369. [9] J.S. Lee, D.H. Bae, An enhanced role model for alleviating the rolebinding anomaly, Software: Practice and Experience 32 (14) (2002) 1317–1344. [10] G. Kiczales, J.Lamping, A. Mendhekar, C. Maeda, C.V. Lopes, J. Loingtier, J. Irwin, Aspect-oriented programming, Proceedings of European Conference on Object-Oriented Programming, LNCS 1241, Springer, Berlin, 1997, pp. 220 –243. [11] K.J. Lieberherr, Adaptive Object-Oriented Software Evolution: The Demeter Method with Propagation Patterns, PWS Publishing Company, Boston, 1996. [12] D. D’Souza, A.C. Wills, Objects, Components and Frameworks with UML: the Catalysis Approach, Addison-Wesley, Reading, MA, 1998. [13] I. Jacobson, G. Booch, J. Rumbaugh, The Unified Software Development Process, Addison-Wesley, Reading, MA, 1999. [14] A.W. Brown, K.C. Wallnau, Engineering of component-based systems, In Component-Based Software Engineering: Selected Papers from the Software Engineering Institute, IEEE Computer Society Press, Silver Spring, MD, 1996, pp. 7–15. [15] C. Szyperski, Component Software: Beyond Object-Oriented Programming, ACM Press, New York, 1997. [16] C. Szyperski, Component-oriented programming a refined variation on object-oriented programming, The Oberon Tribune 1 (1995). [17] D.E. Perry, A.L. Wolf, Foundations for the study of software architecture, Software Engineering Notes 17 (1992). [18] D. Galran, D.E. Perry, Introduction to the special issue on software architecture, IEEE Transactions on Software Engineering 21 (1995) 269–274. [19] L. Bass, P. Clements, R. Kazman, Software Architecture in Practice, Addison-Wesely, Reading, MA, 1998. [20] R.N. Taylor, N. Medvidovic, K.M. Anderson, E.J. Whitehead Jr., J.E. Robbins. A component- and message-based architectural style for gui software, IEEE Transactions on Software Engineering 22 (1996) 390–406. [21] E. Gamma, R. Helm, R. Johnson, J. Vlissides, Design Patterns: Elements of Reusable Object-oriented Software, Addison-Wesely, Reading, MA, 1994. [22] N. Medvidovic, Formal definition of the chiron-2 software architectural style,Technical ReportUCI-ICS-95-24, Departmentof Information and Computer Science, University of California, Irvine, July 1995. [23] L.M. Seiter, J. Palsberg, K.J. Lieberherr, Evolution of object behavior

[24]

[25] [26]

[27]

[28] [29] [30]

[31]

[32]

[33] [34] [35] [36] [37]

[38]

[39]

97

using context relations, IEEE Transactions on Software Engineering 24 (1998) 79 –92. P. Netinant, T. Elard, M.E. Fayad, A layered approach to building Oopen aspect-oriented systems: a framework for the design of on-demand system remodularization, Communications of the ACM 44 (10) (2001) 83– 85. Object constraint language specification, Rational Software Corporation, 1997. N. Medvidovic, P. Oreizy, J.E. Robbins, R.N. Taylor, Using objectoriented typing to support architectural design in the c2 style, Proceedings of SIGSOFT’96: The Fourth Symposium on the Foundations of Software Engineering (FSE4), October, 1996, pp. 16 –18. M. Shaw, Procedure calls are the assembly language of software interconnections: connectors deserve first-class status, Proceedings of Workshop on Studies of Software Design, May, 1993. A.S. Tanenbaum, Distributed Operating Systems, Prentice-Hall, Englewood Cliffs, NJ, 1995. P. Sridharan, JavaBeans: Developer’s Resource, Prentice-Hall, Englewood Cliffs, NJ, 1997. G. Roghermel, M.J. Harrold, Selecting regression tests for objectoriented software, Proceedings of International Conference on Software Maintenance, 1994, pp. 14– 25. M. Tatsubori, S. Chiba, Openjava: yet another reflection support for java, Proceedings of JSSST International Symposium on Object Technologies for Advanced Software, 1997, pp. 201 –204. M. Tatsubori, S. Chiba, M. Killijian, K. Itano, Openjava: a class-based macro system for java, Proceedings of Reflection and Software Engineering, LNCS 1826, Springer, Berlin, 2000. G. Kiczales, Beyond the black box abstraction: open implementation, IEEE Software 13 (1996) 8–11. G. Kiczales, J. ds Rivieres, D. Bobrow, The Art of the Metaobject Protocol, MIT Press, Cambridge, MA, 1991. P. Maes, D. Nardi, Meta-level Architectures and Reflection, Elsevier, Amsterdam, 1988. C.M. Krishna, K.N.G. Shin, Real-time Systems, McGraw Hill, New York, 1997. J.S. Lee, D.H. Bae, An approach to specifying concurrent, distributed, and autonomous object behaviors using a high-level meta-object protocol, IEICE Transactions on Communications, IEICE/IEEE Joint Special Issue on Autonomous Decentralized Systems 83-B (2000) 999–1012. S. Chiba, Load-time structural reflection in java, Proceedings of European Conference for Object-Oriented Programming, LNCS 1850, Springer, Berlin, 2000, pp. 313 –336. L. Tokuda, D. Batory, Evolving object-oriented designs with refactorings, Proceedings of International Conference on Automated Software Engineering, 1999.

Suggest Documents