Business Object Components?
Department of Computer Science
Lund Institute of Technology
Lund University
Box 118
S-221 00 Lund
Sweden
Abstract: Although the term business objects is notoriously polysemous, most authors making use of it seem to assume that business objects, apart from being objects in the object-oriented sense, should also be reusable, “plug-and-play” components. However, the starting-point of the vision of object-orientation is fundamentally different from that of software components, and objects and components cannot, as is often taken for granted, be fitted together without considerable difficulties. To be more precise, these two programming paradigms clash in the concept of implementation inheritance, which, while being fundamental to most strains of object-oriented programming, viciously undermines the plug-and-play composability required by software componentry, owing to a set of issues commonly, albeit somewhat ineptly, referred to as “the fragile base class problem”. Below, having outlined what class fragility is, I will try to show how it affects business objects and how three important candidate platforms for the implementation of business objects, viz. Newi, Java, and COM+, fare with reference to it. Hereupon will follow a brief description of encapsulated programming, which is a novel style of programming attempting to harmonise object-orientation and software componentry on the basis of encapsulated inheritance. This reformed inheritance mechanism, designed so as to eschew all kinds of class fragility, forms the basis of a new basic building block of software, the capsule, which in effect will assimilate the object and component concepts. Finally, I will also discuss how encapsulated programming can be brought to bear on the three aforementioned candidates for a business objects platform.
Keywords: business objects, software components, encapsulated programming
1 Introduction
Business objects are often held to be, as it were, the ultimate software components, potentially providing for very high levels of reuse and software agility. For such business objects to become viable, various obstacles, will, however, have to be overcome, of which a very serious one, viz. class fragility, provides the topic of this study.
The idea that the assembly of prefabricated parts or components, forming the basis of the industrial production of computer hardware and most other artefacts, can be taken advantage of also in the production of software was broached in Douglas McIlroy’s famous invited address Mass Produced Software Components, delivered at the NATO conference on software engineering in Garmisch in 1968.[1] The basis of such software componentry is the machine metaphor, a conception of a computer programme as a machine-like contrivance built from parts, making encapsulation and reuse the keystones of software construction. In contrast, object-orientation, originating slightly earlier with the SIMULA 67 language, rests on a world metaphor, which arises naturally in the domain of software simulations targeted by the SIMULA language.[2] The allure of object-oriented software – including business objects – largely consists in its embodiment of a mental model of a set of real-world or imaginative entities that renders an object-oriented programme akin to a “microcosm” of message-exchanging objects. In an oddly Platonic vein, the dynamically changing, ‘material world’ of objects inside an executing object-oriented programme mirrors the unchanging, hierarchically structured, ‘ideational world’ of classes sculpted by a programmer demiurge. In sum, the lodestar of object-orientation is hierarchical modelling, that of software componentry the encapsulation of parts. Can these two fundamentally different outlooks be reconciled?
In the 80s, as the interest in object-orientation, software componentry, and software reuse started to grow rapidly, Brad Cox made the ingenious and intriguing attempt to amalgamate the component and object concepts through his notion of Software-ICs.[3] These were binary packaged Objective-C objects, possessing many of the dynamic properties now widely held to be necessary for components. The support for implementation inheritance implied by the object-oriented paradigm, however, gave rise to a number of “fragility” problems that tend to seriously undermine the component idea. Through clever design, Cox attempted to counter the problems, although he was not able to resolve all the issues involved.
Since the early 90s, the suitability of objects as components has become increasingly contentious. In particular, weighty criticism has been levelled at implementation inheritance, the bedrock of object-orientation, but also the source of the fragility problems. For example, Cuno Pfister, the chairman of Oberon microsystems, strikingly declares, “It may well turn out that implementation inheritance is the GOTO statement of the nineties”.[4] Additionally, various problems pertaining to object-oriented frameworks seem to be derivable from implementation inheritance.[5] ‘The fragile base class problem’ caused the designers of Microsoft’s Component Object Model (COM), the as yet most successful component infrastructure, to abandon implementation inheritance altogether. Rival component technologies, such as OpenDoc and JavaBeans, have retained full support for implementation inheritance and the object-oriented approach, thereby, however, also retaining the liability to the class fragility problems. Pace the many advocates of such ‘traditional’ object-orientation, the swiftly rising star of component-oriented programming, as advocated in e.g. Szyperski’s suggestively named book Component Software. Beyond Object-Oriented Programming[6], seems to be beaming in the direction taken by the designers of COM.
Below, I will briefly adumbrate what class fragility is and why it is harmful to the business objects vision. I will then suggest how object-orientation and software componentry can be reconciled through encapsulated programming, a novel programming style that attempts to correct the deficiencies of the object-oriented inheritance mechanism.[7] I will also discuss how the adoption of this programming style would affect classical Newi-style business objects as well as business objects implemented as COM components or as Java language objects, such as JavaBeans.
2 Class Fragility and Business Objects
Inheritance is widely held to be the differentia specifica of object-orientation[8], but has become increasingly debated, as it clearly is also the
source of miscellaneous problems.[9] According to Wegner and others, inheritance is essentially a
mechanism for the “incremental modification” of a superclass by a subclass[10], making possible the programming style called programming-by-difference.[11] Besides inheritance, polymorphism
is generally considered essential to object-oriented programming.[12] Where polymorphism is supported,
values and variables may be of more than a single type, whereas the antonym monomorphism implies that any value
or variable in a programme may be of one and only one type. In object-oriented
programming, polymorphism is yoked closely together with inheritance,
insofar as object references usually are polymorphic
and refer to objects that may be either of the type of the object reference
or of any subtype of this particular
type. In some programming languages that support dynamic typing, such as Smalltalk
or Objective-C, object references
may hold references to any type of object. When polymorphism is taken advantage
of, method resolution will happen at run-time by means of dynamic or late binding.
There are two distinct variants of inheritance, interface inheritance (or subtyping) and implementation inheritance (or subclassing). The former term denotes the inheritance of type (i.e. interface or protocol), the latter the inheritance of behaviour and state (i.e. implementation). Whereas the virtuousness of interface inheritance is not very controversial[13], implementation inheritance has ever and anon been decried as uninteresting[14] or potentially maleficent[15]. Technologies such as COM and CORBA directly support only interface inheritance, whereas most object-oriented programming languages merge interface and implementation inheritance into one concept. An important exception is Java, which offers a clear separation of the two inheritance types. In C++, interface inheritance may be simulated through public inheritance of an abstract class, which has only pure virtual function members, whilst pure implementation inheritance may be simulated with private inheritance.[16]
Inheritance is sometimes said to “break encapsulation”, because it makes superclasses expose implementation details to their subclasses.[17] In this context, it is noteworthy that, in general, a class exposes two interfaces that usually intersect: the client interface intended for ‘ordinary’ run-time usage and the specialisation interface intended for subclassing.[18] In many object-oriented languages, such as C++ and Java, it is possible to restrict access to methods and instance data by the use of access modifiers. In C++ and Java, the methods and data of the client interface are declared public, those of the specialisation interface protected, and implementation details, which are to be accessible through neither interface, private. In both these languages, members of the client interface will always be part of the specialisation interface as well.
Whereas strict observance of the principles of information hiding and data abstraction will mitigate the problem of encapsulation break[19], it will still at times be necessary to have access to the source code of a superclass in order to be able to implement a subclass correctly. In particular, this may be the case when a superclass method is overridden by a method in a subclass or when a subclass defines a method that will be recursively called from the superclass.[20] The cause of this need is that a subclass – in contrast to an ordinary client – will share the important variable self (also known as this) with its superclass. Inheritance-based reuse is at times referred to as white-box reuse, because source code access is required for the specialisation of the reused code. This need for source code access is evidently a serious obstacle on the road to markets for plug-and-play software components or business objects. For software componentry, extensibility mechanisms supporting black-box reuse, such as aggregation, are, hence, frequently claimed to be superior to white-box mechanisms.
2.1 “The Fragile Base Class Problem”
The locution “the fragile base class problem” emerged within Microsoft during the design and development of COM. Strictly speaking, this term seems inappropriate, since, what is “broken” and thus “fragile”, will in most cases be a subclass rather than a base class, although the underlying causes of the fragility often lie with a base class. Some authors use the term also for scenarios, where neither a base class, nor a subclass, but a client of a class is what “breaks”. In my contention, the term “the fragile base class problem” is misleading and should be abandoned. Instead, I suggest class fragility as an overriding term for all fragility problems that pertain to the use of classes; these can be further subdivided into subclass fragility and client fragility.[21]
Moreover, the term “the fragile base class
problem” is made to refer to different phenomena by different authors. Mostly,
the concept is understood as referring to problems that occur when base
class implementations evolve independently of their subclasses, and
this will also be the sense used here.[22] There are two distinct varieties of the problem, viz. syntactic and semantic fragility.[23] Since it will not be possible to explore these problems, which are
both quite intricate and quite technical in nature, in detail here, we will
focus on their consequences for components
and business objects.
2.2 Syntactic Fragility
Source code references to external functions and data (i.e. functions and data defined outside the current source code file) are traditionally resolved at “link time” through static linking by a linker. However, in GUI environments, such as Windows and OS/2, run-time or dynamic linking to Dynamic Link Libraries (DLLs) has caught the wind.[24] At the cost of an extra memory indirection for each external reference, dynamic linking makes it possible to upgrade a DLL without having to re-compile and re-link all applications that make use of it, provided that the functions and the data referred to by these are not removed, renamed, or their types/signatures changed in the new DLL. This is a major benefit, making it easy to distribute fixes and upgrades of binaries shared by a large number of programmes without breaking them. For one thing, the Windows API is distributed as a set of DLLs. Unfortunately, such flexibility is only possible when procedure-oriented languages, such as C, are used; when object-oriented languages are relied upon, the syntactic fragile class problem will stand in the way.
Syntactic fragility will make it necessary to recompile unmodified subclasses and clients, whenever changes in the interface of a base class have been made, lest the subclasses should “break” during execution. Recompilation will be necessary even upon apparently very harmless changes to the interface of the base class, such as a simple reordering of its members. The problems derive from the way virtual methods and instance data are organised in tables and referenced by tabular offsets in the compiled and linked binaries of object-oriented programmes. Unfortunately, the layout and size of these tables, which need to be known at compile-time, will tend to be affected by any modification to the class interface, however slight.
Syntactic fragility causes two problems, recompilation avalanches and the breakdown of release-to-release binary compatibility. Recompilation avalanches tend to affect programmer productivity very adversely, as applications grow large and compilation- and link-times become increasingly protracted. In compiled object-oriented languages, this is exacerbated by the across-the-board use of file inclusion directives and file time stamps to determine which code needs recompilation. In C++ and some other languages, the problem is primarily restricted to class interface changes by a clear-cut separation of the class interface from its implementation through header files, although some implementation details exposed by the interface of a class, such as in-line function members, may occasionally add to the fragility.[25] Languages that do not keep interface and implementation apart in different files will be more vulnerable to syntactic fragility, as not only interface changes, but any changes to the implementation part of a class will trigger the recompilation of subclasses and clients.
The breakdown of release-to-release binary compatibility affects system reliability adversely, inasmuch as the introduction of a new version of an object-oriented DLL will possibly invalidate all applications that rely on this DLL, as the offsets used to address data and virtual function members as well as the table sizes and layouts presumed by any existing subclasses may no longer be correct. This obviously is a major obstacle for plug-and-play software componentry and business objects.
Various attempts to dispel syntactic class fragility have been made. Some of these, such as the run-time method dispatch of Smalltalk-80, Brad Cox’ Software-ICs[26], or IBM’s SOM (System Object Model)[27], only provide partial solutions and in doing so incur a more or less serious performance penalty to boot.
In the Java Virtual Machine (JVM), syntactic fragility is avoided by suspending 1) name resolution to link time (which happens either at load-time or at run-time) and 2) the determination of the storage layout of objects to run-time.[28] Unfortunately, the considerable load-time/run-time performance penalty implied by this approach will have to be paid afresh every time a Java programme is executed and will grow considerably worse with code size and code complexity.[29] The success of Java is largely a consequence of the security benefits of the virtual machine approach for the – not very performance-critical – browser-based execution of code snippets downloaded over the Internet. On the other hand, if the JVM approach is abandoned for compilation to native code, as is often suggested when the performance problems of Java are debated or performance-critical application areas, such as web server or embedded systems programming, are considered, syntactic fragility will necessarily reappear.
Microsoft’s COM (Component Object Model) eschews syntactic fragility through the convention that published COM interfaces must be immutable.[30] Finally, Newi’s cooperative business objects[31], which rely on semantic messaging for intercommunication, are not liable to syntactic fragility at all, since dispatch is made dynamically at message-time in a message loop. Although this kind of semantic messaging is much slower than ordinary method calls, the granularity of Newi’s business objects will ensure that inter-object messaging will be comparatively rare, primarily happening due to direct user interaction.[32] Notably, both COM and Newi introduce a “layered” programming model, where inter-component calls differ significantly from intra-component calls. This two-layered approach allows both these technologies to provide language independence through the definition of a binary interface at the upper component/business object echelon.
2.3 Semantic Fragility
Semantic
fragility is much more elusive in nature than its syntactic sibling, as it arises from evolutionary
changes not to the interface of a
class, but to its implementation. It
may show up, whenever a new version of a base class, from which subclasses
have been derived through implementation
inheritance, is introduced, provided the base class makes a – direct
or indirect – polymorphic self-recursive
down-call. Since every polymorphic
self-call may potentially be resolved into a down-call, we can just as
well say that the problem is latently overhanging in any class that makes at
least one polymorphic self-call. In
addition, it may show up upon revision of a base class, the instance data of
which are directly accessed from a subclass. Mikhajlov and Sekerinski, who
have investigated this problem at length, discern five distinct cases of
it, some of which are quite involved.[33]
These cases will not need to be retold here; the bottom line is that whenever a base class is revised, any (unmodified) code taking advantage of the base class through subclassing may unexpectedly start to malfunction, although care has been taken to ensure that the modifications in the base class will be entirely behaviour-preserving.[34] This will cause a breakdown of release-to-release semantic compatibility and will compel subclass programmers to get access to and analyse the source code of base classes. Just like the lack of release-to-release binary compatibility, this will of course seriously undermine the software componentry and business objects visions.
Since implementation inheritance is a crucial feature of object-oriented languages and these languages eo ipso are liable to semantic fragility, the problem has attracted considerable attention by researchers. Two kinds of countermeasures against semantic fragility that have been suggested are:
· to “discipline” implementation inheritance by the establishment of a set of “rules”
· to abandon implementation inheritance altogether
The former
avenue, which has been dealt with in a number of research papers, seems to lead
up to awkward and byzantine schemes that will force programmers to perform
complex analyses of the source code interdependencies
of methods, method groupings, self calls, etc.[35] Furthermore, these schemes presume that the subclass programmer
has access to the source code of superclasses, which will be highly undesirable
in component/business objects scenarios.
The latter avenue of forgoing implementation
inheritance altogether – taken, for instance, in Microsoft’s COM – will raise the hackles of many advocates of object-orientation accustomed to the
reliance on inheritance as a handy extensibility mechanism.
3 Encapsulated Programming and Business Objects
Elsewhere, we have suggested that the clash
of object-orientation and component-orientation can be resolved
through encapsulated programming,
a new programming style designed so as to be impervious to all kinds of
class fragility, while still retaining support for a restricted, “disciplined”
form of implementation inheritance.[36] Encapsulated
programming is based on two basic mandates:
· Firstly, syntactic fragility is to be eschewed in one way or the other, be it through a semantic messaging mechanism as in Newi, an interface immutability convention as in COM, or the postponement to load-time/run-time of name lookup and of the computation of object layout as in JVM.[37]
· Secondly, semantic fragility is to be addressed through the espousal of encapsulated inheritance, which modifies implementation inheritance by banning polymorphic self-recursive down-calls and direct access to superclass data.[38]
In our terminology, an object that avoids syntactic fragility and supports encapsulated inheritance is called a capsule. Since, in our view at least, class fragility must be overcome, if the visions of software components and business objects are not to remain on the drawing-board, capsules should provide a suitable shape for the implementation of components and business objects.
We will now try to clarify how encapsulated programming will affect business objects, using Newi-style business objects, Java objects, and COM components as examples. We have chosen to look at Java and COM because of their current importance on the market overt, whereas Newi will be considered both because of its historical impact on the business object community through the writings of Oliver Sims, “the father of business objects”, and because of its principal importance.
3.1 Newi-style business objects
Newi’s semantic messaging mechanism effectively immunised Newi classes against syntactic fragility, although, by virtue of its support for implementation inheritance and polymorphic self-recursive down-calls, its objects were amenable to semantic fragility. However, this was somewhat mitigated by the fact that subclasses and clients did not have direct access to superclass data. Thus, by removing the possibility of sending messages to self (but, of course, not to super!) from the Newi infrastructure, Newi could easily have been made to support encapsulated inheritance and the encapsulated programming paradigm.
3.2 Java and JavaBeans
Java code executed in the Java Virtual Machine is not liable to syntactic fragility, although the virtual machine approach may imply a significant performance penalty. This can be countered through dynamic linking and compiling with caching, which is a scheme that refines the JVM approach by caching the linked and verified bytecodes – as well as any snippets of binary code resulting from dynamic compilation – in a cached image that, after a version control, can be taken advantage of on subsequent execution of the code.[39] This approach will, I believe, reduce the performance penalty of the virtual machine approach considerably and still steer clear of syntactic fragility.
In order to avoid semantic fragility, the Java inheritance
mechanism needs an overhaul so as to provide support for encapsulated inheritance. Two minor measures will suffice:
Firstly, all data members should be made private;
thus, one should not be allowed to use the access modifiers protected and public on data members. Secondly, polymorphic self-calls of methods that are neither final, nor private should be disallowed. As the Java designers will not be likely to accept such bold reformation
of their language, one may instead choose to use these rules as guidelines for
the design of Java or JavaBeans classes intended as reusable components or business objects.
In this context, it should be noted that encapsulated programming clashes with
the workings of white-box frameworks,
which tend to make heavy use of polymorphic
down calls in accordance with the so-called Hollywood principle (don’t call us, we call you). Although
certainly controversial, giving up the current framework reliance of the object-oriented
approach appears to us a both necessary and highly beneficial step. In our
experience, the chief cause for the low productivity and steep learning curves
of object-oriented programmers as compared to developers that work with component-based
RAD tools stems from the reliance on application frameworks, which have an
extremely high surface area[40] and thus are very difficult to master and use. Application
frameworks also violate fundamental principles of software engineering,
such as encapsulation, information
hiding, and the minimisation of cross-module coupling, and, thus, tend to breed code complexity, undermine maintainability,
and create dangerously tight couplings between application code and frameworks.[41]
The Java approach is, however, highly framework-oriented, and the thickets of frameworks surrounding the Java language tend to grow increasingly dense every day. For the Java programmer, it will not be a realistic option to dispense with all these frameworks. He can, however, use a two-layer strategy to mitigate the problems by abiding by the principles of encapsulated programming in Java and JavaBeans classes intended as reusable components or business objects, while still taking advantage of the Java frameworks internally in these.
3.3 COM
COM is already immune both to syntactic and to semantic fragility, but lacks support for implementation inheritance. It seems that COM would gain much by getting support for a simple-to-use extension mechanism, such as encapsulated inheritance, since the extension mechanisms presently available to the COM programmer, delegation and aggregation, tend to be both unwieldy and difficult to use correctly.[42]
4 Conclusions
If business objects are to be objects in the object-oriented sense and also capable of being used as plug-and-play components, the problems of class fragility caused by the flawed inheritance mechanism of today’s object-oriented approach must be addressed. We have argued that the fragility problems can be expunged through the adoption of encapsulated programming and outlined how technologies such as Newi, Java, and COM can be modified so as to adhere to this style.
Business objects, being
software representations of the things and entities of ‘the real world’, will
need to be much more large-grained and flexible than the ordinary objects of
object-oriented programming. Although the Newi
product now seems to have faded out of sight in the hands of SSA, I believe that Newi-style, large-granular, directly user-manipulable components
interoperating through semantic messaging as envisioned by Oliver Sims in his
first book[43] still hold great promise as the proper shape for business objects, in particular if
modified according to the lines suggested above. For one thing, various on-going developments, such as the rise
of XML and SOAP and the possibly imminent
arrival of 3-D user interfaces, may
make for a better appreciation of this vision of business objects. By reliance not on proprietary
niche-technology, but on the rapidly maturing COM+, Java, or CORBA technology
compages as infrastructural underpinnings, such business objects should be able to gain in attractiveness in the
marketplace. In the Panopeus project, of which this essay is
a spin-off, I am currently in the process of developing and exploring
the agenda of realistic computing on
the basis of this kind of large-grained business
objects, semantic messaging, 3‑D user interface technology, and encapsulated programming.[44]
5 Acknowledgements
This research has been supported by Crafoordska stiftelsen and Helge Ax:son Johnsons stiftelse.
6 References
[Berr95] G. Berrisford: How the Fuzziness of the Real-World Limits Reuse by Inheritance between Business Objects, in J. Murphy, B. Stone (eds.): OOIS’95. 1995 International Conference on Object Oriented Information Systems. Proceedings, Springer-Verlag, 1996, pp. 3-18
[Betz94] M. Betz: Interoperable Objects, Dr. Dobb’s Journal, October 1994, pp. 18-39
[BM98] J. Bosch, S. Mitchell (eds.): Object-Oriented Technology. ECOOP’97 Workshop Reader. ECOOP’97 Workshops. Jyväskylä, Finland, June 1997. Proceedings, Lecture Notes in Computer Science 1357, Springer-Verlag, 1998
[BMMB99] J. Bosch, P. Molin, M. Mattsson, P.-O. Bengtsson: Object-Oriented Frameworks: Problems & Experiences, in [FSJ99] pp. 55-82, see also see http://www.ipd.hk-r.se/bosch/papers/ex-frame.ps
[Booc87] G. Booch: Software Components with Ada, Benjamin/ Cummings, 1987
[Booc94] G. Booch: Object-Oriented Analysis and Design (2nd ed.), Addison-Wesley, 1994
[Broc95] K. Brockschmidt: Inside OLE (2nd ed.), Microsoft Press, 1995
[Chap96] D. Chappell: Understanding ActiveX and OLE. A Guide for Developers & Managers, Microsoft Press, 1996
[CN91] B. Cox, A. J. Novobilski: Object-Oriented Programming - An Evolutionary Approach (2nd ed.), Addison Wesley, 1991
[Coll95] D. Collins: Designing Object-Oriented User Interfaces, Benjamin/Cummings, 1995
[Cook89] S. Cook (ed.): ECOOP 89. Proceedings of the Third European Conference on Object-Oriented Programming, British Computer Society Workshop Series, Cambridge University Press, 1989
[Cox86] B. J. Cox: Object-Oriented Programming - An Evolutionary Approach, Addison Wesley, 1986
[CV65] F. J. Corbató, V. A. Vyssotsky: Introduction and Overview of the Multics System, in AFIPS Conference Proceedings of the 1965 Fall Joint Computer Conference, AFIPS Press, 1965, pp. 185-196
[CW85] L. Cardelli, P. Wegner: On Understanding Types, Data Abstraction, and Polymorphism, Computing Surveys, Vol. 17, No. 4, December 1985, pp. 471-522
[DLS97] K. De Hondt, C. Lucas, P. Steyaert: Reuse Contracts as Component Interface Descriptions, in [WBS97] pp. 43-49 and [BM98] pp. 338-342
[DN66] O.-J. Dahl, K. Nygaard: SIMULA- An Algol Based Simulation Language, Communications of the ACM, Vol. 9, No. 9, pp. 671-678, 1966
[Duga94] B. Dugan: Simula and Smalltalk: A Social and Political History 1994, see http://www.cs.washington.edu/homes/brd/history.html
[FCDR95] I. R. Forman, M. H. Conner, S. H. Danforth, L. K. Raper: Release-to-Release Binary Compatibility in SOM, in OOPSLA’95 Tenth Annual Conference on Object-Oriented Programming Systems, Languages, and Applications, ACM SIGPLAN Notices, Vol. 30, No. 10, October 1995, pp. 426-438
[Fran97] M. Franz: Dynamic Linking of Software Components, Computer, March 1997, pp. 74-81, see also http://dlib.computer.org/co/books/co1997/pdf/r3074.pdf
[Free87] P. Freeman (ed.): Tutorial: Software Reusability, IEEE Computer Society Press, 1987
[FSJ99] M. E. Fayad, D. C. Schmidt, R. E. Johnson (eds.): Building Application Frameworks, John Wiley & Sons, 1999
[GHJV94] E. Gamma, R. Helm, R. Johnson, J. Vlissides: Design Patterns. Elements of Reusable Object-Oriented Software, Addison-Wesley, 1996
[GJS96] J. Gosling, B. Joy, G. Steele: The Java™ Language Specification, Addison-Wesley, 1996, see also ftp://ftp.javasoft.com/docs/specs/langspec-1.0.pdf
[GM96] J. Gosling, H. McGilton: The Java Language Environment. A White Paper, May 1996, see http://java.sun.com/docs/white/langenv
[GR83] A. Goldberg, D. Robson: Smalltalk-80. The Language and its Implementation, Addison-Wesley, 1983
[Hami97] J. Hamilton: Programming with DirectToSOM™ C++, John Wiley & Sons, 1997
[Hauc93] F. Hauck: Inheritance Modeled with Explicit Bindings, in OOPSLA’93 Eight Annual Conference on Object-Oriented Programming Systems, Languages, and Applications, ACM SIGPLAN Notices, Vol. 28, No. 10, October 1993, pp. 231-239
[Ichb83] J. D. Ichbiah: On the Design of Ada, in R. E. A. Mason (ed.): Information Processing 83. Proceedings of the IFIP 9th World Computer Congress. Paris, France, September 19-23, 1983. IFIP Congress Series. Volume 9. Participants Edition, North-Holland, 1983, reprinted in [Free87] pp. 59-68
[Jell97] T. Jell (ed.): CUC96. Component-Based Software Engineering, SIGS Books, 1997
[JF88] R. E. Johnson, B. Foote: Designing Reuseable Classes, Journal of Object-Oriented Programming, Vol. 1, No. 2, June/July 1988, pp. 22-35
[Kay93] A. C. Kay: The Early History of Smalltalk, ACM SIGPLAN Notices, Vol. 28, No. 3, March 1993, pp. 69-95
[Kerr93] R. Kerr: Inheritance––Just a Programmer’s Hack?, Object Magazine, March-April 1993, pp. 18-20
[Kind97] Charlie Kindel: COM: What Makes it Work. Black-box Encapsulation through Multiple, Immutable Interfaces, in Proceedings First International Enterprise Distributed Object Computing Workshop. October 24-26, 1997. Gold Coast, Australia, IEEE Computer Society, 1997, pp. 68-77
[KL92] G. Kiczales J. Lamping: Issues in the Design and Specification of Class Libraries, in OOPSLA’92 Seventh Annual Conference on Object-Oriented Programming Systems, Languages, and Applications, ACM SIGPLAN Notices, Vol. 27, No. 10, October 1992, pp. 435-451
[Lamp93] J. Lamping: Typing the Specialization Interface, in OOPSLA’93 Eight Annual Conference on Object-Oriented Programming Systems, Languages, and Applications, ACM SIGPLAN Notices, Vol. 28, No. 10, October 1993, pp. 201-214
[LC85] L. Ledbetter, B. Cox: Software-ICs, BYTE, June 1985, pp. 307-316
[Lewi97] T. Lewis: If Java Is the Answer, What Was the Question?, Computer, March 1997, pp. 136, 133-135
[Lisk87] B. Liskov: Data Abstraction and Hierarchy, in L. Power, Z. Weiss (eds.): OOPSLA’87 Addendum to the Proceedings, ACM SIGPLAN Notices, Vol. 23, No. 5, May 1988
[LY99] T. Lindholm, F. Yellin: The Java™ Virtual Machine. Second Edition, Addison-Wesley, 1999, see also http://java.sun.com/docs/books/vmspec/2nd‑edition/html/VMSpecTOC.doc.html
[Magn91] B. Magnusson: Code Reuse Considered Harmful, Journal of Object-Oriented Programming, November/December, 1991, p. 8
[Matt00] M. Mattsson: Evolution and Composition of Object-Oriented Frameworks, Ph.D. thesis, Department of Software Engineering and Computer Science, University of Karlskrona/ Ronneby, 2000
[MB97] M. Mattsson, J. Bosch: Framework Composition: Problems, Causes and Solutions, in Proceedings TOOLS USA '97, see http://www.ipd.hk‑r.se/bosch/papers/frwkcomp.ps, also as Composition Problems, Causes and Solutions (slightly revised) in [FSJ99] pp. 467-487
[McIl68] M. D. McIlroy: Mass Produced Software Components, in P. Naur, J. Randell (eds.): Software Engineering. Report on A Conference Sponsored by the NATO Science Committee, Garmisch, Germany, 7th to 11th October, 1968, NATO Science Committee, 1969, pp. 138-150, also reprinted in [NRB76], pp. 88-98
[Meye97] B. Meyer: Object-Oriented Software Construction (2nd ed.), Prentice Hall, 1997
[Mezi97] M. Mezini: Maintaining the Consistency of Class Libraries During Their Evolution, in Proceedings of the 1997 ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages & Applications (OOPSLA’97), ACM SIGPLAN Notices, Vol. 32, No. 10, October 1997, pp. 1-21
[Micr94] Microsoft Corporation: OLE 2 Programmer’s Reference. Volume 1-2, Microsoft Press, 1994
[MS97a] L. Mikhajlov, E. Sekerinski: The Fragile Base Class Problem and Its Solution, Turku Centre for Computer Science Technical Report No 117, June 1997, see also http://www.tucs.abo.fi/publications/techreports/TR117.html
[MS97b] L. Mikhajlov, E. Sekerinski: The Fragile Base Class Problem and Its Impact on Component Systems, in [WBS97] pp. 59-68 and [BM98] pp. 353-358
[MS98] L. Mikhajlov, E. Sekerinski: A Study of the Fragile Base Class Problem, in E. Jul (ed.): ECOOP’98 – Object-Oriented Programming. 12th European Conference. Brussels, Belgium, July 20-24, 1998. Proceedings, in G. Goos, J. Hartmanis, J. van Leeuwen, Lecture Notes in Computer Science 1445, Springer-Verlag, 1998, pp. 354-382
[MSL96] K. Mens, P. Steyaert, C. Lucas: Reuse Contracts: Managing Evolution in Adaptable Systems, in [Mühl97] pp. 37-42
[Mühl97] M. Mühlhäuser (ed.): Special Issues in Object-Oriented Programming. Workshop Reader of the 10th European Conference on Object-Oriented Programming. ECOOP’96, Linz, July 1996, dpunkt.Verlag, 1997
[Myer96] B. A. Myers: A Brief History of Human Computer Interaction Technology, Carnegie-Mellon University School of Computer Science Technical Report CMU-CS-96-163 and Human Computer Interaction Institute Technical Report CMU-HCII-96-103, December 1996, see also http://www.cs.cmu.edu/~amulet/papaers/uihistory.tr.html
[ND78] K. Nygaard, O.-J. Dahl: The Development of the SIMULA language, ACM SIGPLAN Notices, Vol. 13, No. 8, August 1978, pp. 245-272
[NRB76] P. Naur, B. Randell, J.M. Buxton (eds.): Software Engineering: Concepts and Techniques, Petrocelli/ Charter, 1976
[PB92] C. Ponder, B. Bush: Polymorphism Considered Harmful, ACM SIGPLAN Notices, Vol. 27, No. 6, June 1992, pp. 76-79
[Pers98] E. Persson: The Quest for the Software Chip. The Roots of Software Components – A Study and Some Speculations, published with text loss in J. Bosch, G. Hedin, K. Koskimies, B. Bruun Kristensen (eds.): NOSA ’98. Proceedings of the First Nordic Workshop on Software Architecture, Research Report 14/98, Department of Computer Science and Business Administration, University of Karlskrona/Ronneby, ISSN 1103-1581, ISRN HK/R-RES–98/14–SE, for a revised version (without text loss) see http://www.ide.hk‑r.se/~bosch/NOSA98/ErikPersson.pdf or http://www.soc.hk-r.se/research/1998/tqsc.ps
[Pers99a] E. Persson: Wisps of Realistic Computing. Bestowing Utility upon Virtual Worlds through 3-D Business Objects, in J. Bosch (ed.): NOSA’99. Proceedings of the Second Nordic Workshop on Software Architecture, Research Report 13/99, Department of Computer Science and Software Engineering, University of Karlskrona/ Ronneby, ISSN 1103-1581, ISRN HK/R‑RES‑99/13‑SE, see also http://www.ipd.hk‑r.se/bosch/NOSAR/NOSA99/Erik-Persson.pdf
[Pers99b] E. Persson: The Twilight of Objects, Technical Report No. LU-CS-TR:99-215, ISSN 1404-1200 Report 83, 1999, Department of Computer Science, Lund Institute of Technology, Lund University, August 10, 1999
[Petz99] C. Petzold: Programming Windows (5th ed.), Microsoft Press, 1999
[Pfis97] C. Pfister: Component Software. A Case Study Using BlackBox Components, Draft, June 11, 1997, see http://www.oberon.ch/docu/case_study/index.html
[Potr97] P. Potrebic: Be Engineering Insights: What’s the Fragile Base Class (FBC) Problem?, Be Newsletter, Issue 79, June 25, 1997, see http://www‑classic.be.com/aboutbe/benewsletter/Issue79.html
[Pres93] L. Press: Before the Altair – The History of Personal Computing, Communications of the ACM, Vol. 36, No. 9, September 1993, pp. 27-33, see also http://som.csudh.edu/fac/lpress/articles/hist.htm
[PS94] D. Pountain, C. Szyperski: Extensible Software Systems, BYTE, May 1994, pp. 57-62
[PS96] C. Pfister, C. Szyperski: Why Objects Are Not Enough, in [Jell97] pp. 141-147, see also http://www.fit.qut.edu.au/~szypersk/pub/CUC96a.ps.gz
[Rich97] J. Richter: Advanced Windows (3rd ed.), Microsoft Press, 1997
[Roge97] D. Rogerson: Inside COM. Microsoft’s Component Object Model, Microsoft Press, 1997
[Sakk89] M. Sakkinen: Disciplined Inheritance, in [Cook89] pp. 39-56
[SG95] R. Stata, J. V. Guttag: Modular Reasoning in the Presence of Subclassing, in OOPSLA’95 Tenth Annual Conference on Object-Oriented Programming Systems, Languages, and Applications, ACM SIGPLAN Notices, Vol. 30, No. 10, October 1995, pp. 200-214
[Sims94] O. Sims: Business Objects: Delivering Cooperative Objects for Client/Server, McGraw-Hill, 1994
[SLMD96] P. Steyaert, C. Lucas, K. Mens, T. D’Hondt: Reuse Contracts: Managing the Evolution of Reusable Assets, in Proceedings of the 1996 ACM SIGPLAN Conference on Object-Oriented Programming Systems, Languages & Applications (OOPSLA’96), ACM SIGPLAN Notices, Vol. 31, No. 10, October 1996, pp. 268-285
[Snyd86] A. Snyder: Encapsulation and Inheritance in Object-Oriented Languages, in N. Meyrowitz (ed.): OOPSLA’86 Conference Proceedings. September 29 - October 2, 1986. Portland, Oregon, ACM SIGPLAN Notices, Vol. 21, No. 11, 1986, pp. 38-45
[Stein87] L. A. Stein: Delegation Is Inheritance, in N. Meyrowitz (ed.): OOPSLA ’87. Conference Proceedings. October 4 - 8, 1987. Orlando, Florida, ACM SIGPLAN Notices, Vol. 22, No. 12, December 1987, pp. 138-146
[Stro96] B. Stroustrup: A History of C++: 1979-1991, in T. J. Bergin, Jr., R. G. Gibson, Jr., History of Programming Languages–II, ACM Press/Addison-Wesley, 1996, pp. 699-767
[Sun99] Sun Microsystems, Inc.: The Java HotSpot™ Performance Engine Architecture, White Paper, April 1999, see http://www.javasoft.com/products/hotspot/whitepaper.html
[Szyp98] C. Szyperski: Component Software. Beyond Object-Oriented Programming, ACM Press/Addison-Wesley, 1998
[Taiv93] A. Taivalsaari: A Critical View of Inheritance and Reusability in Object-Oriented Programming, Ph.D. Thesis, University of Jyväskylä, Jyväskylä Studies in Computer Science, Economics and Statistics, 1993
[Taiv96] A. Taivalsaari: On the Notion of Inheritance, ACM Computing Surveys, Vol. 28, No. 3, September 1996, pp. 438-479
[TK89] R. P. Ten Dyke, J. C. Kunz: Object-Oriented Programming, IBM Systems Journal, Vol. 28, No. 3, 1989, pp. 465-478
[Venn99] B. Venners: Interview. James Gosling Looks Back at the Java Language’s Past and Forward to its Future, JavaOne Today, June 18, 1999, see http://www.javaworld.com/javaworld/javaone99/j1-99-gosling.html
[VMMD98] M. Vellon, K. Marple, D. Mitchell, S. Drucker: The Architecture of a Distributed Virtual Worlds System, Microsoft Research, 1998, see http://www.research.microsoft.com/vwg/papers/oousenix.htm
[WBS97] W. Weck, J. Bosch, C. Szyperski (eds.): Proceedings of the Second International Workshop on Component-Oriented Programming (WCOP '97), TUCS General Publication No. 5, September 1997, see also http://www.tucs.abo.fi/publications/general/G5.pdf
[Wegn87] P. Wegner: Dimensions of Object-Based Language Design, in N. Meyrowitz (ed.): OOPSLA ’87. Conference Proceedings. October 4 - 8, 1987. Orlando, Florida, ACM SIGPLAN Notices, Vol. 22, No. 12, December 1987, pp. 168-182
[Wegn88] P. Wegner: Inheritance as an Incremental Modification Mechanism or What Like Is and Isn’t Like, in S. Gjessing, K. Nygaard (eds.): ECOOP ’88. European Conference on Object-Oriented Programming. Oslo, Norway, August 15–17, 1988. Proceedings, (G. Goos, J. Hartmanis (eds.): Lecture Notes in Computer Science 322), Springer-Verlag, 1988, pp. 55-77
[WK94] S. Williams, C. Kindel: The Component Object Model: Technical Overview, Dr Dobb’s Journal, December, 1994, see also http://www.microsoft.com/oledev/olecom/Com_modl.htm
[1] [McIl68]. [Pers98] provides a survey of the history of the software component idea.
[2] SIMULA was devised by Dahl and Nygaard from 1961 onwards; see [ND78] and [DN66]. Cf. also [Duga94], where an attempt is made to expound and explicate the advent of object-orientation against the background of an “ideology of simulation” purportedly popular in science at this time. Simulation was also the application area that originally motivated Stroustrup to develop C++ (see [Stro96] p. 700 et seqq.). Cf. also [TK89], [Kay93], [Booc94] p. 36 et seq., [Coll95] p. 19 et seqq., [Pres93], and [Myer96].
[3] See [LC85] and [Cox86]. In an IFIP keynote speech [Ichb83], Jean Ichbiah also associated the package and generics facilities of Ada with McIlroy’s software component vision, and Grady Booch later (in [Booc87] p. 7 et passim) formulated and promulgated an Ada component programme. In popular lore, a Scandinavian modelling-oriented branch of object-orientation is often contraposed to an American reuse-oriented one; cf. e.g. [Kerr93].
[4] [Pfis97]. [PB92] criticises polymorphism as a disguised goto.
[5] [BMMB99] and [MB97]. See also [Matt00].
[6] [Szyp98]
[7] [Pers99b] provides a more detailed exposé of class fragility and encapsulated programming.
[8] So [Wegn87] p. 169, where the classical definition “object-oriented = objects + classes + inheritance” was set down. Not all will agree with this definition. For example, [Sakk89] argues that inheritance is dispensable to object-orientation.
[9] Thorough treatments of inheritance and its problems are found in [Szyp98] p. 72 et seqq. and [Meye97] p. 459 et seqq. et passim. Id. op. p. 809 et seqq. proposes an interesting taxonomy of inheritance and also includes a survey of biological taxonomy. [Taiv93] is a dissertation, [Taiv96] a survey article devoted exclusively to inheritance.
[10] [Wegn88]. Cf. also [Taiv96] p. 474. This interpretation holds quite well for single inheritance. When multiple inheritance is considered, inheritance may additionally become a mechanism for the combination or mix-in of useful behaviour.
[11] [JF88]
[12] [CW85] discerns and discusses various classes of polymorphism.
[13] However, [Berr95] questions the aptitude of inheritance for the modelling of an inherently fuzzy world.
[14] So, for example, [Lisk87] p. 33 and p. 24.
[15] [Magn91]
[16] [GHJV94] p. 17.
[17] [Snyd86]
[18] [Lamp93]
[19] Cf. [Lisk87].
[20] Just to get a glimpse of the severity of the problems, one may consider what happens, if a superclass method A calls a virtual method B that is overridden in a subclass and the subclass implementation of B then calls A. In order to be able to avoid vicious loops of recursive invocations or at least to comprehend why the code locks up, a subclass implementer unfortunately needs access to the source code of the superclasses.
[21] Cf. [Lewi97] p. 135.
[22] So, for example, [Betz94], [MS97a-b], [MS98], and [Szyp98] p. 102 et seqq. [MS97a], [MS98], and [Szyp98] provide detailed accounts of this problem.
[23] See [PS94], [PS96], [MS97a], [Pfis97] chapter 3.4., and [Szyp98] p. 102 et seqq.
[24] The UNIX counterpart is known as “shared libraries”. [Fran97] presents an interesting bird’s eye-view of the different varieties of dynamic linking and tracks the concept back to the Multics operating system of the 60s (see [CV65] p. 191). The functioning of Windows DLLs is detailed in [Rich97] p. 529 et seqq. and [Petz99] p. 1243 et seqq.
[25] Private member declarations are indeed implementation details and should consequently not be exposed in the interface of an object. In C++, modification of private members will, however, change the table layout and offsets and, thus, must be part of the class interface. Additionally, the existence of friend declarations or inline functions may bring to naught the encapsulation of private members. In the BeOS system APIs, which are exposed as C++ classes, various – mostly very unprepossessing – workarounds to the C++ fragility problems are resorted to, as documented by [Potr97].
[26] In both Smalltalk and Objective-C, the problem of instance data fragility is unresolved. See [GR83] p. 586 et seqq., [FCDR95] p. 435, and [CN91] p. 26, p. 69 et seqq., and p. 137 et seqq. In his book, Brad Cox made a strong plea for supplier-side binding as the basis for software componentry. Admitting that method resolution through run-time supplier-side searches will be very inefficient, he also proposed various optimisation techniques.
[27] [Hami97] p. 43 et seq. lists some of the unsupported changes. SOM also introduces a very complex programming model and a number of nasty catches that will force the programmer to acquire a thorough understanding of its – quite intricate – inner workings; see id. op. p. 37.
[28] See [Venn99], [GM96] section 5.1, [GJS96] p. 220 et seqq., and [LY99] sections 2.17.3 and 4.9.
[29] In order to enhance the run-time performance, Sun’s HotSpot™ Performance Engine uses a number of different techniques, including the dynamic compilation and adaptive optimisation of the code segments (called hot spots), where a programme spends most execution time. See [Sun99] and http://www.javasoft.com/products/hotspot. Recent benchmark results for various Java virtual machines are available at http://www.volano.com/benchmarks.html.
[30] See, for example, [Broc95], [Micr94], [WK94], [Kind97], [Roge97], or [Chap96]. Since interfaces are immutable, what may change between different versions of a COM class or component is not the interfaces per se, but the set of interfaces supported by the COM class. Through interface negotiation, which is supported by all COM interfaces, it is possible for a client to check, whether a COM object supports a particular interface.
[31] See [Sims94].
[32] [Sims94] p. 277 et seqq.
[33] See [MS97a] p. 4 et seqq. and [MS98] p. 359 et seqq.
[34] It is also possible to introduce similar semantic problems by the use of delegation, since delegation is equivalent to inheritance, as established by [Stein87]. [Szyp98] p. 48 et seqq. shows that similar difficulties also haunt libraries that use callbacks.
[35] Significant examples include Lamping’s type system for the specialisation interface (see [Lamp93]; cf. also [KL92] and [Hauc93]), Stata’s and Guttag’s division of labor specifications (see [SG95]), the reuse contracts of Steyaert et al. (see [SLMD96], [MSL96], and [DLS97]), Mezini’s metalevel declarations (see [Mezi97]; cf. also [Szyp98] p. 109 et seqq.), and Mikhajlov’s and Sekerinski’s rules for base class revision and subclass construction (see [MS97a-b] and [MS98]).
[36] See [Pers99b].
[37] Additionally, in systems that do not rely on Newi-style semantic messaging methods must not be deleted, nor method signatures be modified.
[38] Arguably, 1) direct access of data members from clients and 2) polymorphic self-calls of methods that are neither final, nor private should also be prohibited. It should be noted that the latter ban implicitly rules out polymorphic self-recursive down-calls. Although these two steps will not be strictly necessary in order to avoid semantic fragility, orthogonality and consistency concerns strongly vindicate them. See [Pers99b] p. 20 for a detailed motivation.
[39] See [Pers99b] p. 14 et seqq. for a more detailed discussion of this scheme.
[40] Surface area is defined by [CN91] p. 17 as the number of things that must be understood and properly dealt with for one programmer’s code to function correctly in combination with another’s.
[41] Some of these problems are discussed in [BMMB99] and [MB97]. Cf. also [Matt00].
[42] Interestingly, in the Microsoft Research V-Worlds project, support for implementation inheritance has been added to COM. See [VMMD98].
[43] [Sims94]
[44] [Pers99a] can be construed as a ‘manifesto’ for this agenda.