Section 4.5. EVALUATION


4.5. EVALUATION

We begin this section with a discussion of a variety of prototype implementations. In Section 4.5.2, we address the technique of inlining since this is an important implementation technique that also demonstrates the ability to generate efficient code for (at least for a subset of) composition filters. Finally, in Section 4.5, we evaluate the CF model based on the objectives that were presented in Section 4.1 and the example case of this paper, and we relate these issues to some other work in this area. In the sidebar, "Common Misconceptions about Composition Filters," we have listed a number of examples of what composition filters are not and what they do not do.

4.5.1. Implementations of the CF Model

Throughout the years, a wide range of implementations of the composition filters model has been realized. These differ from each other in several respects:

The adopted base language. That is, the language that expresses the implementation part.

The level of integration with the base language. For example, whether the syntax of the interface part is adapted to the syntax of the base language.

Translation time. Ranging from a pure interpreter to a byte code interpreter to a compiler.

These implementations have been proof-of-concept research prototypes. We now present various implementations, focusing on their distinguishing characteristics. The aim of this presentation is to give an impression of the wide range of possible implementation strategies.

Sina. The Sina language [36] was the first implementation of composition filters, which were at that time referred to as interface predicates [6]. The Sina compiler translated the Sina language into a byte code representation that was interpreted by a dedicated virtual machine. The latter was built on top of Smalltalk.

Sina/st. Sina/st [27] was another implementation of the Sina language on top of Smalltalk, but this version supported the full composition filters mechanism. The implementation was based on an interpreted, reflective, runtime, first-class model of filters and messages.

CFIST. CFIST [37] aimed at the integration of Smalltalk programming and composition filters, both at the language level and at the tool level. A key concept of this prototype was that it kept the Smalltalk class definitions completely separate and independent of the composition filters part.

C++/CF. The C++/CF language [21] investigated the integration of composition filters with C++. It was based on the explicit reification of message invocations (implemented through macros).

ComposeJ. ComposeJ [39] is an inlining compiler for an integrated Java/CF language.

ConcernJ. ConcernJ [34] is the implementation of composition filters including the superimposition mechanism as a front-end to ComposeJ. It resolves the crosscutting and generates corresponding filter specifications for ComposeJ.

JCFF. An alternative, more pragmatic, approach has been taken in JCFF (Java Composition Filters Framework) [35], where composition filters are implemented in Java as a library. This has the advantage of allowing software engineers to remain completely in a familiar programming language.

Compose*.NET. Recently, we have initiated the design and development of Compose*.NET [18, 23, 30], which adds the capability of adding composition filters to .NET assemblies. The latter are a universal, object-oriented representation of programs in any (one of many) programming language. This gives us the ability to add composition filters to any programming language that has been implemented by .NET.

Further, we would like to point out that composition filters seem to be well suited to extend (other) component models such as CORBA. This has been investigated, for example, in [16].

4.5.2. Inlining Composition Filters

As another example of the benefits of the implementation-independent model and to address the issue of performance, we present an example of inlining of filters as a compilation technique to achieve efficient execution of composition filters. The principle of filter inlining is to generate a custom version of the filter code for a specific message selector, thereby typically eliding the bulk of the filter code. This custom version is then inserted at the start of the method with the corresponding selector.

To demonstrate the effect of inlining, we show how the example filter code in Listing 4-4 is translated by the ComposeJ tool.

Listing 4-4. Example filter code from an email application
 inputfilters   verifyUserView : Error = {     userView()=>{putOriginator, putReceiver,                  putContent, getContent,                  send, reply },     true~>{putOriginator, putReceiver,            putContent, getContent, send,            reply }   };   verifySystemView : Error = {     systemView()=>{approve, putRoute, deliver},     true~>{approve, putRoute, deliver}   };   dis: Dispatch = { inner.*, mail.* }; 

This example consists of three filters that every message should pass. It uses two conditions that must be evaluated at runtime. Further, the last line involves signature matching. Obviously, literally processing the full filter specifications for every message is, even when generating efficient code, quite expensive.

However, a look at the generated code that is inlined in USVMail::reply() after a clean-up reveals that the amount of code to be executed for this message is quite limited:

 if (!userView())   throw new FilterException("Error filter exception"); return mail.reply(); 

For message reply(), this is the full code that is needed to execute the filters in Listing 4-4.

The ability to inline filters is simplified by the fact that the filter specifications are declarative and easy to analyze statically.

There are a few considerations, however:

  • Not all the messages that an object receives may correspond to the execution of an inlined filter implementation. In those cases, a potentially more elaborate execution of the whole set of filters is required.

  • The code above does not show some overhead in our implementation; e.g., for the purpose of bookkeeping pseudovariables.

  • Code inlining generally results in increased code size.

An important lesson to be learned from this example, as well as from the range of examples in the previous subsection, is that general conclusions about the efficiency of the implementation of filters must be drawn with great care.

Common Misconceptions About Composition Filters

Composition filters have been around for a substantial amount of time. Among the feedback we have received, we have discovered some common misconceptions. By explicitly addressing these issues, we hope that the readers of this chapter will gain an improved understanding of these specific issues.

Composition filters can only "filter out" messages. The term filtering may suggest that the only purpose of filters is to selectively allow certain messages. In general, filters can observe and manipulate messages, as well as trigger certain actions.

Composition filters objects are equivalent to "wrappers." Traditional object wrapping is similar to the composition filters approach, but it differs in at least two important ways. First, the behavior of object wrappers is implemented by regular methods, whereas composition filters are tailor-made abstractions for composing the behavior of objects. Second, object wrapping suffers from some modeling problems such as object schizophrenia [33]. Composition filters, among others by the merit of the dispatching mechanism, do not suffer from these problems.

Composition filters are a tool for adapting existing classes. The fact that the implementation object is separate and can be an already implemented class does not mean that this is the actual purpose. Although there certainly are useful applications in this area, it is important to realize that the filters depend only on the offered interface of methods and conditions. This interface must in general be designed before constructing the implementation and the filters. Hence, the approach of choice is to identify the filters along with other properties of classes during the design phase.

The filtering mechanism must be very inefficient. The declarative style of composition filters allows for various optimizations, in particular avoiding overhead that is irrelevant for specific messages. We refer to Section 4.5.2 for more details about this topic. It should be noted that some mechanisms that are offered by filters, such as synchronization and message reflection, have inherent performance penalties that cannot be avoided.

There are only a few composition filter types. Most publications about composition filters, including this chapter, discuss only a limited set of filter types. The presented filter types are the result of our attempts to define filter types that are canonical models for some common aspects of software systems. However, there are no inherent restrictions on the number or behavior of filter types.

Composition filters cannot express application-specific "advice." Clearly, the aim of the composition filters model is to offer predefined and programmer-defined abstractions to address common problems. To attach application-specific advice to messages, a Meta filter can be defined, which designates a specific method for the implementation of the advice. This was exemplified by the logging example in this paper (Listing 4-3).

Composition filters implementations must be multi-language. We have stressed that the CF model is language-independent; the filtering mechanism can be made to work with implementation parts expressed a variety languages. However, we make no claims about the support of multi-language systems or for heterogeneous platforms: This depends strictly on a particular implementation. Typically, existing implementations work with a single language/platform [21, 27, 37, 39]. Clearly, a multi-language implementation is possible, in particular by relying on a multi-language platform such as CORBA [16] or .NET [23, 30].

Composition filters are strictly reactive. This would mean that filters can only be active when triggered by incoming messages. Although this is an important category (e.g., Error, Substitute, and Dispatch filters), some other filters can be active without being triggered by incoming messages. For example, the Wait filter must repeatedly reconsider whether some of the blocked messages in the queue can be activated again. Similarly, the RealTime filter is responsible for continuously rescheduling threads such that deadlines are met.




Aspect-Oriented Software Development
Aspect-Oriented Software Development with Use Cases
ISBN: 0321268881
EAN: 2147483647
Year: 2003
Pages: 307

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net