Scalable Component Abstractions/BoAdler
From GradTurkey
Contents |
[edit] Components
- minimize hard references
- smaller part of a larger whole
- reusable
- interface describing provided service
- interface describing required service - this is probably the tricky part, because when composing modules, you'd like to be able to specify how a module performs some computations. For example, you might like to use a generic mathematical expression parser/evaluator, but be able to specify that the underlying computation engine uses 64-bit arithmetic.
- distributed in binary form - this reminds me of one of the goals of the aspect oriented tools.
--BoAdler
[edit] Composition Techniques
Software reuse is all about composition of old code with new code. Some compositional techniques used are:
- aggregation
- I wasn't sure what this was. It seems to be the standard linking idea of lumping modules together and resolving references.
- parameterization
- classic reuse technique in functional languages? Abtract type members are a form of parameterization, but perhaps so are other arguments to an object constructor? Is it parameterization when the resulting types are different, as with C++ templates?
- inheritance
- classic reuse technique in object oriented languages.
- remote invocation
- uses well defined APIs to communicate with self-contained modules. Examples are CORBA, DCOM, and SOAP.
- message passing
- how is this different from remote invocation?
--BoAdler
[edit] Interfaces as Specification
In the introduction, the authors state:
While these languages offer some support for attaching interfaces describing the provided services of a component, they lack the capability to abstract over the services that are required.
But why can't required services also be described as interfaces? For instance, in Java, a helper class could be provided as an argument to a constructor, and still get the benefits of link time type checking.
--BoAdler April 2006 (PDT)
[edit] Useful Mixins
I had never seen mixins before this paper, and incremental composition seems like a wonderful idea, as demonstrated by the iterator example. During the discussion in our reading group, though, I realized that the SyncIterator didn't work the way I expected. Although the hasNext and next operations are synchronized, notice that the foreach method (in StringIterator) still has a race condition; a proper implementation would synchronize the hasNext and next call in the same block.
My conclusion, then, is that mixin composition isn't always safe unless you know how each of the components is implemented. But this really defeats the whole purpose of component reuse! I have a similar complaint about aspect oriented techniques, which makes me wonder if it's even really possible to always treat components as black boxes.
--BoAdler April 2006 (PDT)
[edit] Selftypes and Scala Compiler
I think that my basic question is, why are selftypes more than syntactic sugar or a "hack" to make static type checking work out? The end of section 2.3 declares that selftypes became the primary mechanism for componentizing the Scala compiler.
The case study in section 4 of the Scala compiler is confusing, though. The original Java implementation uses static members for five key classes, but doesn't explain why except to say that it "supports complex recursive references". Do the references on the rest of this page explain the problem more clearly?
--BoAdler April 2006 (PDT)
[edit] Component Adaptation
The logging example baffles me; it seems they are just using inheritance to extend functionality. In particular, to create LogSymbols, the programmer still needs to know about implementation details of the original components, and that log isn't an identifier used in any of those components. Perhaps the point was that this wasn't easy (or even possible?) with static class members, and I agree that this is important.
As a nitpick, the class LoggedCompiler specifies abstract classes as mixins, but I thought that the mixin section said that only traits could be mixins.
--BoAdler April 2006 (PDT)
