20.08.2013 Views

Composable Objects with Multiple Views and Layering - trese ...

Composable Objects with Multiple Views and Layering - trese ...

Composable Objects with Multiple Views and Layering - trese ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Universiteit Twente<br />

De ondernemende<br />

universiteit<br />

<strong>Composable</strong> <strong>Objects</strong><br />

<strong>with</strong> <strong>Multiple</strong> <strong>Views</strong><br />

<strong>and</strong> <strong>Layering</strong><br />

Graduation Committee<br />

Dr. ir. M. Aksit<br />

Dr. ir. K.G. van den Berg<br />

Dr. P.M. van den Broek<br />

Ing. R.R. van de Stadt<br />

S.G. de Bruijn, March 1998<br />

MSc. Thesis at the Department of Computer Science<br />

University of Twente, Department of Computer Science, SETI, TRESE


Abstract<br />

When software systems were becoming too complex, people developed the<br />

object-oriented model. It enabled them to build pieces of software more or less<br />

independent from each other. This resulted in better underst<strong>and</strong>able systems<br />

which were easier to maintain.<br />

The use of the object-oriented model has solved a lot of architectural<br />

problems, but the experience in using the model drives us further: We now<br />

want to enrich our software models <strong>with</strong> more problem-domain properties, by<br />

making these properties explicit. This enables us to represent these properties<br />

more precisely, making software systems even better underst<strong>and</strong>able <strong>and</strong><br />

maintainable.<br />

Introducing problem-domain properties in a software model should not<br />

interfere <strong>with</strong> the already existing elements of this model. This is often not true<br />

however. In this thesis, we presenttwo modelling issues. We give our de nition of<br />

the issues, <strong>and</strong> try to discuss them using a traditional object-oriented language.<br />

In doing so, we encounter a lot of problems, <strong>and</strong> nally must conclude that<br />

expressing the presented modelling issues in a language like C ++ cannot be<br />

done in a fully satisfactory way.<br />

Next to a traditional object-oriented language, we also use the modelling<br />

issues in a next-generation object-oriented language called Sina. This language<br />

is based on an enhanced object-oriented model, basically enabling the software<br />

engineer to h<strong>and</strong>le <strong>and</strong> manipulate message calls between objects explicitly. We<br />

will see that <strong>with</strong> the Composition Filters Object Model, as the enhanced model<br />

is called, it is perfectly possible to express the presented modelling issues in a<br />

natural way, while preserving all the properties of the object-oriented model.<br />

Next to using modelling issues in software systems, it is also important<br />

to record them for later reuse. A Software Design Pattern has proved to<br />

be an e cient medium for the propagation of modelling knowledge. When we<br />

try to present our modelling issues as design patterns however, we discover<br />

that Gamma, Helm, Johnson <strong>and</strong> Vlissides's (1995) pattern scheme is not rich<br />

enough to express our modelling issues. In this thesis, we extend this Design<br />

Pattern notation, <strong>and</strong> represent our design issues using this extended notation.


Samenvatting<br />

Toen softwaresystemen te complex werden, ontstond het object-georienteerde<br />

model. Dit model stelde de softwareontwikkelaars in staat om softwaresystemen<br />

te bouwen die bestonden uit een aantal min of meer onafhankelijke bouwstenen.<br />

Deze opzet resulteerde in systemen die beter te begrijpen en te onderhouden<br />

waren.<br />

Door het gebruik van object-georienteerde technieken zijn veel problemen<br />

in de softwarebouw met betrekking tot de interne architectuur opgelost. Nu<br />

men daar wat meer ervaring mee heeft, is het gewenst om meer voordeel uit<br />

de inzet van deze technieken te halen. We willen de eigenschappen van het<br />

probleemdomein van de software explicieter gaan modelleren. Dit geeft meer<br />

inzicht in de materie dan de \normale" impliciete modellering. Tevens leidt dit<br />

tot beter inzichtelijke softwaresystemen die ook beter te onderhouden zijn.<br />

Wanneer we het probleemdomein expliciet gaan modelleren, mag dit uiteraard<br />

niet in strijd zijn met reeds aanwezige softwaremodellen. Vaak blijkt<br />

echter dat dit juist wel het geval is. In dit afstudeerverslag presenteren we twee<br />

modelleringskwesties. We geven de door ons gebruikte de nities en proberen<br />

de modellen in een normale object-georienteerde taal te realiseren. We komen<br />

hierbij veel problemen tegen die niet eenvoudig oplosbaar blijken en uiteindelijk<br />

moeten we tot de conclusie komen dat het niet mogelijk is om probleemdomeinen<br />

op een acceptabele wijze expliciet in een object-georienteerde taal als C ++<br />

te realiseren.<br />

Naast realisatie in een normale object-georienteerde taal, bouwen we ook<br />

modellen voor dezelfde modelleringskwesties in de moderne object-georienteerde<br />

taal Sina. Deze taal is gebaseerd op een verbeterd objectmodel dat in principe<br />

de software engineer de middelen geeft om methode-aanroepen expliciet af te<br />

h<strong>and</strong>elen en ze te manipuleren. We zullen laten zien dat met dit Compositie<br />

Filters Object Model de gepresenteerde modelleringskwesties uitstekend zijn<br />

te realiseren, zonder de oorspronkelijke voordelen van het object-georienteerde<br />

model te verliezen.<br />

Wanneer modelleringskwesties goed zijn uitgewerkt in afgebakende modellen,<br />

zijn ze in principe geschikt om later opnieuw te worden ingezet in een<br />

<strong>and</strong>er softwaresysteem. Software Design Patterns blijken tot op heden een e ectieve<br />

notatie voor dergelijke modelleringskennis en -ervaring te zijn. De notatie<br />

van (Gamma et al. 1995) is geent op het normale object model en blijkt tekort<br />

te schieten wanneer we onze oplossingen uitgedrukt in het Compositie<br />

Filters Object Model willen presenteren. Daarom geven we in dit verslag ook<br />

een aanpassing van de Design Pattern notatie en drukken hierin de door ons<br />

aangedragen modellen uit.


Preface<br />

You would not be reading this if I had not received the unlimited patience that<br />

my family, my friends, my graduation committee <strong>and</strong>, last but not least, my<br />

employer gave me.<br />

Thank you all.<br />

S.G. de Bruijn<br />

March 1998, Laren{NH


Contents<br />

1 Introduction 1<br />

1.1 Project boundaries . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />

1.2 Structure of this thesis . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

2 Background <strong>and</strong> related work 7<br />

2.1 Object models . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

2.1.1 Conventional Object Model . . . . . . . . . . . . . . . . . 7<br />

2.1.2 Composition Filters Object Model . . . . . . . . . . . . . 8<br />

2.2 Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

2.3 Position of this work in the TRESE project . . . . . . . . . . . . 10<br />

3 Modelling Issue: <strong>Multiple</strong> <strong>Views</strong> 11<br />

3.1 Modelling <strong>Multiple</strong> <strong>Views</strong> . . . . . . . . . . . . . . . . . . . . . . 11<br />

3.1.1 What is a View? . . . . . . . . . . . . . . . . . . . . . . . 12<br />

3.1.2 Conceptual View Model . . . . . . . . . . . . . . . . . . . 14<br />

3.1.3 Scenario of Changes . . . . . . . . . . . . . . . . . . . . . 17<br />

3.2 C ++ Implementation . . . . . . . . . . . . . . . . . . . . . . . . . 20<br />

3.2.1 Simple Mail System . . . . . . . . . . . . . . . . . . . . . 22<br />

3.2.2 Add <strong>Views</strong>: UserSystemView Mail System . . . . . . . . . 24<br />

3.2.3 View Partitioning: OriginatorReceiverView Mail System . 26<br />

3.2.4 View Extension: Group Mail System . . . . . . . . . . . . 28<br />

3.2.5 Dynamic Behaviour Extension: Secure Mail System . . . 30<br />

3.2.6 Static Meta Behaviour Extension: Warning2 Mail System 31<br />

3.2.7 View Composition: Protected Mail System . . . . . . . . 34<br />

3.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35<br />

4 Modelling Issue: <strong>Layering</strong> 39<br />

4.1 Modelling Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . 39<br />

4.1.1 What is <strong>Layering</strong>? . . . . . . . . . . . . . . . . . . . . . . 39<br />

4.1.2 Conceptual <strong>Layering</strong> Model . . . . . . . . . . . . . . . . . 42<br />

4.1.3 Scenario of Changes . . . . . . . . . . . . . . . . . . . . . 49<br />

4.2 C ++ implementation . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />

4.2.1 Add Methods: Heading Mail System . . . . . . . . . . . . 51<br />

4.2.2 Rede ne Methods: Attachment Mail System . . . . . . . . 53<br />

i


ii Contents<br />

4.2.3 Extend Methods: ReadNoti cation Mail System . . . . . 53<br />

4.2.4 Add Object-Orthogonal Behaviour: History Mail System . 55<br />

4.2.5 Dynamic <strong>Layering</strong>: Dynamic Mail System . . . . . . . . . 56<br />

4.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57<br />

5 Composition Filters Solutions for the Modelling Issues 61<br />

5.1 The Sina Language . . . . . . . . . . . . . . . . . . . . . . . . . . 61<br />

5.2 <strong>Multiple</strong> <strong>Views</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62<br />

5.2.1 Simple Mail System . . . . . . . . . . . . . . . . . . . . . 62<br />

5.2.2 Add <strong>Views</strong>: UserSystemView Mail System . . . . . . . . . 62<br />

5.2.3 View Partitioning: OriginatorReceiverView Mail System . 64<br />

5.2.4 View Extension: Group Mail System . . . . . . . . . . . . 67<br />

5.2.5 Dynamic Behaviour Extension: Secure Mail System . . . 68<br />

5.2.6 Static Meta Behaviour Extension: Warning2 Mail System 68<br />

5.2.7 View Composition: Protected Mail System . . . . . . . . 68<br />

5.3 <strong>Layering</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

5.3.1 Add Methods: Heading Mail System . . . . . . . . . . . . 70<br />

5.3.2 Rede ne Methods: Attachment Mail System . . . . . . . . 70<br />

5.3.3 Extend Methods: ReadNoti cation Mail System . . . . . 70<br />

5.3.4 Add Object-Orthogonal Behaviour: History Mail System . 71<br />

5.3.5 Dynamic <strong>Layering</strong>: Dynamic Mail System . . . . . . . . . 72<br />

5.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72<br />

6 <strong>Composable</strong> Models Presented as Design Patterns 75<br />

6.1 Enabling Design Patterns to Present <strong>Composable</strong> Models . . . . 75<br />

6.2 Design Pattern: <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong> . . . . . . . 80<br />

6.3 Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong> . . . . . . . . . . . 85<br />

6.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

7 Conclusions <strong>and</strong> Future Work 93<br />

7.1 Comparison of the C ++ <strong>and</strong> the Sina implementations . . . . . . 93<br />

7.1.1 <strong>Multiple</strong> <strong>Views</strong> . . . . . . . . . . . . . . . . . . . . . . . . 93<br />

7.1.2 <strong>Layering</strong> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94<br />

7.2 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95<br />

7.3 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96<br />

A C++ Implementation of <strong>Multiple</strong> <strong>Views</strong> 99<br />

A.1 Simple Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

A.2 UserSystemView Mail System . . . . . . . . . . . . . . . . . . . . 104<br />

A.3 OriginatorReceiverView Mail System . . . . . . . . . . . . . . . . 113<br />

A.4 Group Mail System . . . . . . . . . . . . . . . . . . . . . . . . . . 116<br />

A.5 Secure Mail System . . . . . . . . . . . . . . . . . . . . . . . . . . 118<br />

A.6 Warning2 Mail System . . . . . . . . . . . . . . . . . . . . . . . . 121<br />

A.7 Protected Mail System . . . . . . . . . . . . . . . . . . . . . . . . 124


Contents iii<br />

B Sina Implementation of <strong>Multiple</strong> <strong>Views</strong> 129<br />

B.1 Simple Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 129<br />

B.2 UserSystemView Mail System . . . . . . . . . . . . . . . . . . . . 134<br />

B.3 OriginatorReceiverView Mail System . . . . . . . . . . . . . . . . 135<br />

B.4 Group Mail System . . . . . . . . . . . . . . . . . . . . . . . . . . 137<br />

B.5 Secure Mail System . . . . . . . . . . . . . . . . . . . . . . . . . . 139<br />

B.6 Warning2 Mail System . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

B.7 Protected Mail System . . . . . . . . . . . . . . . . . . . . . . . . 143<br />

C C++ Implementation of <strong>Layering</strong> 147<br />

C.1 Heading Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 147<br />

C.2 Attachment Mail System . . . . . . . . . . . . . . . . . . . . . . . 149<br />

C.3 ReadNoti cation Mail System . . . . . . . . . . . . . . . . . . . . 151<br />

C.4 History Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 153<br />

C.5 Dynamic Mail System . . . . . . . . . . . . . . . . . . . . . . . . 159<br />

D Sina Implementation of <strong>Layering</strong> 171<br />

D.1 Heading Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 171<br />

D.2 Attachment Mail System . . . . . . . . . . . . . . . . . . . . . . . 172<br />

D.3 ReadNoti cation Mail System . . . . . . . . . . . . . . . . . . . . 175<br />

D.4 History Mail System . . . . . . . . . . . . . . . . . . . . . . . . . 178<br />

D.5 Dynamic Mail System . . . . . . . . . . . . . . . . . . . . . . . . 180<br />

Bibliography 185


iv Contents


List of Figures<br />

2.1 Conventional Object Model . . . . . . . . . . . . . . . . . . . . . 8<br />

2.2 Composition Filters Object Model . . . . . . . . . . . . . . . . . 8<br />

3.1 <strong>Multiple</strong> <strong>Views</strong> in an object-oriented environment . . . . . . . . . 13<br />

3.2 Conceptual Model of <strong>Multiple</strong> <strong>Views</strong> . . . . . . . . . . . . . . . . 14<br />

3.3 Many-to-many relationship between methods M o <strong>and</strong> views V o . 16<br />

3.4 Set Operations on <strong>Views</strong> . . . . . . . . . . . . . . . . . . . . . . . 17<br />

3.5 <strong>Multiple</strong> <strong>Views</strong> Scenario . . . . . . . . . . . . . . . . . . . . . . . 21<br />

3.6 Object Interaction Diagram for the Mail System . . . . . . . . . 23<br />

3.7 Adding <strong>Views</strong> in C ++ . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

3.8 Partitioning <strong>Views</strong> in C ++ . . . . . . . . . . . . . . . . . . . . . . 29<br />

3.9 Dynamic Behaviour Extension in C ++ . . . . . . . . . . . . . . . 32<br />

3.10 Static Meta Behaviour Extension in C ++ . . . . . . . . . . . . . . 33<br />

3.11 View Composition in C ++ . . . . . . . . . . . . . . . . . . . . . . 35<br />

4.1 Object Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40<br />

4.2 Role playing modelled <strong>with</strong> a layer . . . . . . . . . . . . . . . . . 40<br />

4.3 The Unix operating system divided into several layers . . . . . . 41<br />

4.4 Layered Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42<br />

4.5 Conceptual Model of <strong>Layering</strong> . . . . . . . . . . . . . . . . . . . . 43<br />

4.6 Static layering generates complex class structures . . . . . . . . . 46<br />

4.7 Dynamic layering keeps class structures simple . . . . . . . . . . 47<br />

4.8 Separate Behaviour from Control: History recording of objects<br />

Obj1 <strong>and</strong> Obj2 is controlled by anOperator . . . . . . . . . . . 48<br />

4.9 <strong>Multiple</strong> Private Properties assigned to one single object . . . . . 49<br />

4.10 <strong>Layering</strong> Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . 51<br />

4.11 Never access \lower level" structures directly . . . . . . . . . . . 52<br />

4.12 Rede ned methods basically extending functionality must call<br />

the original method, <strong>and</strong> often are conditional in their extension 54<br />

4.13 Separate Mail Read <strong>and</strong> Send ReadNoti cation functionalities . . 55<br />

4.14 Every method has to be rede ned to implement history information<br />

recording . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56<br />

4.15 C ++ example of one simple function in a Decorator pattern . . 58<br />

5.1 Deadlock ofsend message in the MailH<strong>and</strong>ler . . . . . . . . . . . 63<br />

v


vi List of Figures<br />

5.2 Implementation of method-view coupling in Sina . . . . . . . . . 65<br />

5.3 Method View Composition . . . . . . . . . . . . . . . . . . . . . 67<br />

5.4 View Extension only rede nes the view . . . . . . . . . . . . . . . 67<br />

5.5 Conditionally redirect messages to specialized versions . . . . . . 68<br />

5.6 Coupling meta behaviour to an object . . . . . . . . . . . . . . . 69<br />

5.7 Composing views is extremely simple using Composition Filters . 69<br />

5.8 Code example of conditional method skipping . . . . . . . . . . . 71<br />

5.9 Orthogonal behaviour is very simple to add to an existing class . 71<br />

5.10 Structure of an object <strong>with</strong> dynamic layering property . . . . . . 72<br />

5.11 Composing functionalities goes rather well using Composition<br />

Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73<br />

6.1 Graphical message notations from the message's viewpoint. A<br />

message is either not ltered at all, or passes one or more lters<br />

which inspect <strong>and</strong>/or manipulate its runtime behaviour. . . . . . 77<br />

6.2 Filter Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78<br />

6.3 An example mail system . . . . . . . . . . . . . . . . . . . . . . . 80<br />

6.4 The structure of the <strong>Multiple</strong> <strong>Views</strong> pattern . . . . . . . . . . . . 81<br />

6.5 Code template for the <strong>Multiple</strong> <strong>Views</strong> Pattern . . . . . . . . . . . 83<br />

6.6 Interface de nition of the Mail class . . . . . . . . . . . . . . . . 83<br />

6.7 Implementation extract of the Mail class . . . . . . . . . . . . . 84<br />

6.8 An example mail system <strong>with</strong> history recording . . . . . . . . . . 85<br />

6.9 Mail system <strong>with</strong> a history recorder <strong>and</strong> a message decoder . . . 86<br />

6.10 Message Diagram of the Basic Dynamic Layer . . . . . . . . . . . 87<br />

6.11 Message Diagram of the <strong>Composable</strong> Object Layer Pattern . . . 87<br />

6.12 How tomake a generic property a dynamic layer . . . . . . . . . 90<br />

6.13 How tomake a normal class a dynamic layered class . . . . . . . 90<br />

6.14 How to use a dynamic layered object . . . . . . . . . . . . . . . . 91


Chapter 1<br />

Introduction<br />

This thesis is about objects. <strong>Objects</strong> have proven to have a positive e ect on<br />

the underst<strong>and</strong>ability <strong>and</strong> maintainability of software. This is the result of specifying<br />

individual components of a software architecture <strong>with</strong> a well-de ned interface,<br />

in such away that these components can be used elsewhere easily.<br />

Sometimes, it is not so easy to de ne these components correctly, <strong>and</strong><br />

when some modelling aspects are used, this will eventually result in implementations<br />

that can no longer be easily adapted or integrated <strong>with</strong> existing<br />

components.<br />

In this thesis, we focus on two di erent modelling issues, <strong>and</strong> try to<br />

model them in C ++, which is assumed to be familiar to the reader. Because we<br />

expect to encounter problems when using C ++, we also will use the language<br />

Sina for modelling purposes. We then are able to compare the two <strong>with</strong> respect<br />

to expressive power. The Sina language was developed at TRESE, <strong>and</strong> is based<br />

on the Composition Filters Object Model, which isintroduced in Section 2.1.<br />

This thesis is also about patterns. The working community is realising that<br />

experience is hard to catch. Every person entering the working community must<br />

learn all the ins <strong>and</strong> outs of his or her discipline. Unfortunately, this takes a<br />

considerable amount of time. Further, knowledge is present, but has not been<br />

written down.<br />

Christopher Alex<strong>and</strong>er was one of the rst to write down his experiences.<br />

In Alex<strong>and</strong>er (1977), he described the ins <strong>and</strong> outs of architecture. People starting<br />

to work in this area can speed up their knowledge acquisition signi cantly<br />

by using his work.<br />

The software industry is busy trying to achieve the same <strong>with</strong> Object Oriented<br />

Software Design Patterns. Gamma et al. (1995) wrote down how software<br />

objects can be arranged <strong>and</strong> built to achieve certain behaviour <strong>and</strong> characteristics.<br />

Section 2.2 gives a more complete introduction to this material.<br />

In this thesis, we will present two modelling issues for which the Composition<br />

Filters Object Model, the model on which the Sina language is based, will<br />

1


2 Chapter 1. Introduction<br />

provide adequate implementations. Although the Composition Filters Object<br />

Model solves a lot of problems, they are not all presented in a uniform format.<br />

Further, the current representation format of these solutions prevents the<br />

work that is done in the TRESE group from being spread enough. This is partly<br />

because the TRESE work is relatively theoretical, <strong>and</strong> \normal" developers<br />

can't clearly see the advantages that the Composition Filters Object Model<br />

has above the Conventional Object Model, on which languages like C ++ <strong>and</strong><br />

Smalltalk are based.<br />

To make our work accessible, we will present the addressed modelling<br />

issues in this thesis not only <strong>with</strong> examples, but also as Software Design Patterns.<br />

To be able to do this, we rst will have to look at the currently most used Design<br />

Pattern Denotation, <strong>and</strong> how problem solutions using the Composition Filters<br />

Object Model will t in.<br />

1.1 Project boundaries<br />

Terminology<br />

In this thesis several terms are used. These are explained here to avoid misunderst<strong>and</strong>ings.<br />

The word model is the most confusing word in this thesis. We identify<br />

three di erent meanings, which are explained here:<br />

Object model The object model is the foundations on which objects are constructed.<br />

Elements of an object model are for example classes, objects,<br />

attributes <strong>and</strong> methods. Properties are for example inheritance <strong>and</strong> encapsulation.<br />

There are di erent object models. The best known are the models of C ++<br />

<strong>and</strong> Smalltalk. These models are alike, but di er for example in metamodelling.<br />

Classes are implicit in C ++, while they are explicitly available<br />

in Smalltalk.<br />

Problem domain model Software engineering concepts, like distribution or<br />

views for example, are de ned by so-called conceptual models, which<br />

relate participants <strong>and</strong> other elements of the concepts to eachother. We<br />

will call this kind of model a problem domain model in this thesis. This<br />

is the model of the term \modelling issue".<br />

Software model The software model is also often referred to as the application<br />

model. By software model we mean the model that is constructed<br />

for the individual objects for the application itself. In a mail system for<br />

example, the MailMessage object is a part of the software model of the<br />

mail system.<br />

We will use these speci c terms instead of the generic term \model" as much<br />

as possible.


1.1. Project boundaries 3<br />

Some other terms that we use are:<br />

Conventional Object Model This is the \well-known" object model that is<br />

normally used.<br />

Composition Filters Object Model This is the object model that is used<br />

to show solutions to modelling problems. It is an enhancement of the<br />

Conventional Object Model, <strong>and</strong> extends the message sending semantics.<br />

Method The implementation of certain behaviour of an object.<br />

Message The \call" of a method of an object.<br />

Message sender The object that sends a message.<br />

Message receiver The object to which the message sender initially sent the<br />

message to.<br />

Access control The ability to block one or more messages, depending on internal<br />

state information, or the sender's class or object identity.<br />

Static vs. dynamic binding Static binding means compile-time binding of<br />

behaviour. Dynamic binding means runtime binding of behaviour.<br />

Message context This is all relevant context information of a message. This<br />

includes the sender, the receiver <strong>and</strong> the method that is called.<br />

Languages<br />

The examples will be worked out in two di erent implementation languages.<br />

These are C ++ <strong>and</strong> Sina. These languages are chosen for various reasons:<br />

C++ This language is hybrid. The origins are in the C language, to which OO<br />

extensions are added. When used well, one can get a reasonable implementation<br />

of an OO system. It scores high when it comes to speed, <strong>with</strong><br />

the cost of not having context information of message calls. The language<br />

supports static multiple inheritance <strong>and</strong> uses the Conventional Object<br />

Model. Access control is addressed in a limited way, <strong>and</strong> it is static. Meta<br />

information about objects, classes <strong>and</strong> messages is completely absent.<br />

Sina This is the only language known that supports the Composition Filters<br />

Object Model. 1 Sina does not support inheritance at all as a language<br />

construct (as well as the Composition Filters Object Model does not<br />

support this semantics as an explicit feature), but it is capable of implementing<br />

(even dynamic) multiple inheritance semantics. Access control<br />

is completely in the h<strong>and</strong>s of the designer, is dynamic <strong>and</strong> can be dependent<br />

of the context of the message.<br />

Although we do not work out the implementations in Smalltalk, we will sometimes<br />

use Smalltalk examples for illustrative purposes.<br />

1. Well, there are implementations of lters in Smalltalk (Mordhorst <strong>and</strong> van Dijk 1996) <strong>and</strong><br />

C ++ (Gl<strong>and</strong>rup 1995). An implementation in Java is being examined.


4 Chapter 1. Introduction<br />

1.2 Structure of this thesis<br />

In Chapter 2, a quick introduction is given about object orientation, design<br />

patterns, the Composition Filters Object Model <strong>and</strong> its relation <strong>with</strong> the Conventional<br />

Object Model.<br />

Chapter 3 <strong>and</strong> Chapter 4 both discuss a certain modelling issue in detail.<br />

Both chapters show a model, the various adaptations one can make to the model,<br />

<strong>and</strong> how it can be implemented in a conventional object oriented language (C ++<br />

in this case, see Section 1.1). Various (dis)advantages of the implementations<br />

are also discussed. Implementations of the examples are included in appendices<br />

A <strong>and</strong> C.<br />

The implementation of the examples from Chapters 3 <strong>and</strong> 4 in Sina<br />

is discussed in Chapter 5. It shows the advantage of the Composition Filters<br />

Object Model over the Conventional Object Model of a language like C ++.<br />

Appendices B <strong>and</strong> D show the full implementations.<br />

The solutions given in Chapter 5 are used as a basis for constructing an<br />

extension to Gamma et al.'s (1995) design pattern denotation, that is capable<br />

of expressing solutions in the Composition Filters Object Model. This format<br />

is described in Chapter 6. To show that the composable design pattern format<br />

works, we provide patterns for <strong>Multiple</strong> <strong>Views</strong> <strong>and</strong> Dynamic <strong>Layering</strong>.<br />

Chapter 7 summarises the conclusions of this work, <strong>and</strong> gives suggestions<br />

about future research activities.<br />

How to read this thesis<br />

When the reader is unfamiliar <strong>with</strong> one or more of the terms Object Orientation,<br />

Design Patterns <strong>and</strong> the Composition Filters Object Model, it is recommended<br />

to read the appropriate section(s) of Chapter 2 rst.<br />

Both Chapters 3 <strong>and</strong> 4 introduce <strong>and</strong> explain a speci c problem in object<br />

oriented modelling. When the reader is interested in these problems, it is<br />

recommended to read the chapters completely. Otherwise, certain sections can<br />

be skipped. The layout of both chapters is the same, <strong>and</strong> is brie y described<br />

here.<br />

First, in Sections 3.1.1 <strong>and</strong> 4.1.1, an intuitive de nition will be given<br />

of the problem at h<strong>and</strong>. When the reader is familiar <strong>with</strong> the material, these<br />

sections can be skipped. Sections 3.1.2 <strong>and</strong> 4.1.2 describe a conceptual model,<br />

which re ects our ideas about the subject, <strong>and</strong> on which the scenarios <strong>and</strong> the<br />

examples are based. When Chapter 5 is read also, it is strongly recommended<br />

to read these sections, also when the subject is familiar. Also interesting in that<br />

case are Sections 3.1.3 <strong>and</strong> 4.1.3, which describe the scenarios that are used<br />

in the examples in more detail. The example workouts (Sections 3.2 <strong>and</strong> 4.2)<br />

<strong>and</strong> the forthcoming conclusions in Sections 3.3 <strong>and</strong> 4.3 are only interesting to<br />

readers who want to know which problems can arise when using a language like<br />

C ++. People only interested in Sina solutions can jump directly to Chapter 5.<br />

Chapter 6 addresses the part about Software Design Patterns, <strong>and</strong> how


1.2. Structure of this thesis 5<br />

implementations using the Composition Filters Object Model can be expressed<br />

as Design Patterns. Basically, Chapter 6 can be read on its own, but it does assume<br />

some familiarity about the Mail System, the example that is used throughout<br />

this thesis, <strong>and</strong> the modelling issues addressed in Chapters 3 <strong>and</strong> 4.


6 Chapter 1. Introduction


Chapter 2<br />

Background <strong>and</strong> related work<br />

Object-orientation has proven to have a positive e ect on the development of<br />

software. The complexity of systems can be reduced by reusing several parts<br />

of other systems that have been built before. Also, the exibility is improved<br />

by separating the interface from the implementation. This enables the software<br />

engineers to `plug in' new or changed components <strong>with</strong>out changing other parts<br />

of the system, as long as the interface of these new parts conform to a certain<br />

pre-de ned interface. There are several object models from whichwe will use two<br />

di erent types. Section 2.1 explains the di erences between the Conventional<br />

Object Model <strong>and</strong> the Composition Filters Object Model.<br />

Software Quality is improved by reusing parts that have proven to be<br />

correct. If it is not possible to reuse existing object code, it still is very usefull<br />

to reuse modelling knowledge. In Section 2.2 Software Design Patterns are<br />

introduced, which have proven to be an e ective medium for distributing this<br />

knowledge.<br />

Section 2.3 nally positions this work in the TRESE project.<br />

2.1 Object models<br />

In this section, we will describe the two Object Models that we use in this thesis.<br />

These are not full introductions to the models, but merely simple descriptions<br />

which show the fundamental di erences between them. For a full description,<br />

we refer to Bergmans (1994, Chapter 2).<br />

2.1.1 Conventional Object Model<br />

The conventional object model describes objects as a collection of instance<br />

variables, methods <strong>and</strong> parent classes. The number of allowed parent classes is<br />

language dependent; some languages allow only one parent class (single inheritance)<br />

<strong>and</strong> others allow more than one parent class (multiple inheritance). A<br />

more or less st<strong>and</strong>ard picture for the Conventional Object Model is displayed<br />

in Figure 2.1.<br />

The gure shows an Object, associated <strong>with</strong> one Parent object. The<br />

Parent object is painted dotted, because it is not a real object (at least not in a<br />

7


8 Chapter 2. Background <strong>and</strong> related work<br />

00 11<br />

00 11<br />

objMethod<br />

Object Parent<br />

000 111<br />

000 111<br />

parMethod<br />

Figure 2.1: Conventional Object Model<br />

00 11<br />

00 11<br />

objMethod<br />

parAttr<br />

Object Parent<br />

000 111<br />

000 111<br />

000 111<br />

000 111 parAttr<br />

parMethod<br />

Figure 2.2: Composition Filters Object Model<br />

class-based language). All requests coming from the outside world are directly<br />

dispatched to the implementations in the Object itself, or one of its Parent<br />

objects. This is done transparantly, as is shown by using dotted arrows inside<br />

the Object. Also, all instance variables intrinsically are available to the outside<br />

world, although some languages de ne some restrictions on this. 1<br />

2.1.2 Composition Filters Object Model<br />

The Composition Filters Object Model is an extension of the Conventional<br />

Object Model. This Composition Filters Object Model adds semantics to the<br />

object model by placing lters on top of the object interface. These lters are<br />

capable of investigating all incoming <strong>and</strong> outgoing messages, as well as the<br />

object itself, <strong>and</strong> it is capable of modifying passing messages, or forward them<br />

to other objects. A picture of the Composition Filters Object Model is found<br />

in Figure 2.2.<br />

1. For example private, protected <strong>and</strong> public attributes <strong>and</strong> methods in C ++ (Ellis <strong>and</strong><br />

Stroustrup 1990)


2.2. Design Patterns 9<br />

This gure shows the same situation of Figure 2.1, but now <strong>with</strong> Composition<br />

Filters extensions. All incoming messages from the outside world pass<br />

the input lters of the Object. These lters send one type of message to the<br />

method present in the Object itself, while the other message types are delegated<br />

to the Parent object (which has its own lters of course). In contrast to<br />

the conventional situation, this Parent object is a real object, but its presence is<br />

hidden from the outside world. Also, the internal calls to the implementations<br />

is explicit.<br />

There are three fundamental di erences between the two models:<br />

1. In the Composition Filters Object Model the Parent object is a real<br />

rst-class object, while in the Conventional Object Model it is not;<br />

2. In the Composition Filters Object Model there is one entrypoint for all<br />

incoming messages, 2 while in the Conventional Object Model all methods<br />

have their own individual entry points|this means that no overall<br />

control is possible over incoming messages in the Conventional Object<br />

Model, because message entry is not explicitly modelled in this model.<br />

3. Distribution of the incoming messages over the present implementation(s)<br />

is done by the lters in the Composition Filters Object Model,<br />

while in the Conventional Object Model, this is de ned by the execution<br />

model of the language in question. 3<br />

2.2 Design Patterns<br />

A design pattern is an entity, which gives one or more context-dependent solutions<br />

for a particular problem, or an implementation structure for a particular<br />

design issue. Patterns were rst introduced by Alex<strong>and</strong>er (1977), who de ned<br />

patterns for the architectural world. The software community has borrowed this<br />

idea, <strong>and</strong> nowadays many patterns are de ned to capture software design.<br />

These software design patterns have proven to be an e ective medium<br />

for documentation <strong>and</strong> communication about domain knowledge (Gamma et al.<br />

1995, Buschmann, Meunier, Rohnert, Sommerlad <strong>and</strong> Stal 1996, Pree 1994).<br />

Their description is formalized by Gamma et al. (1995), <strong>and</strong> most design patterns<br />

de ned today are formatted conform their recipe.<br />

2. There is also one exit point for all outgoing messages. We do not depict this often explicitly<br />

in this thesis, but the reader must know that they exist.<br />

3. There are di erent implementations. In C ++ for example, there are things called virtual<br />

tables, which are in fact pointers to the actual function implementations for the \current"<br />

object. In Smalltalk the runtime engine searches for appropriate implementations in the class<br />

hierarchy.


10 Chapter 2. Background <strong>and</strong> related work<br />

2.3 Position of this work in the TRESE project<br />

Composition Filters Development<br />

By development of Composition Filters, we mean the development of the model<br />

<strong>and</strong> the de nition of di erent lter types. At the moment, the model is considered<br />

more or less complete, so there is not much work in this area now.<br />

Composition Filters Implementations<br />

Several implementations of Composition Filters are developed <strong>and</strong> others are<br />

under development. Implementations in C ++ (Gl<strong>and</strong>rup 1995) <strong>and</strong> Smalltalk<br />

(Mordhorst <strong>and</strong> van Dijk 1996) are ready. Another kind of implementation is<br />

the Message Manipulator de ned by Stuurman (1996), who de ned Composition<br />

Filters as rst-class objects in an object-oriented environment. An implementation<br />

in Java is being examined.<br />

Composition Filters Knowledge Distribution<br />

A lot of articles have been written which address several problems that Composition<br />

Filters can solve (Bergmans 1994, Aksit, Bosch, van der Sterren <strong>and</strong><br />

Bergmans 1994, Aksit, Wakita, Bosch, Bergmans <strong>and</strong> Yonezawa 1993, Aksit,<br />

Bergmans <strong>and</strong> Vural 1992, Aksit <strong>and</strong> Bergmans 1992, Aksit <strong>and</strong> Bosch 1994).<br />

With these articles, we try to make the outside world aware of potentional problems<br />

in daily object-oriented designs, <strong>and</strong> how one can avoid these problems.<br />

Besides the distribution of articles, also courses are lectured in objectoriented<br />

analysis <strong>and</strong> design. Further, there is an active participation in conferences<br />

<strong>and</strong> workshops which address object-orientation.<br />

Composition Filters Deployment<br />

There are several framework designs which use the Composition Filters Object<br />

Model. These include Algra (1994), Koehorst (1994), Tekinerdogan (1994) <strong>and</strong><br />

Vuijst (1994).<br />

Where does this thesis t in<br />

The work in this thesis is part of the Composition Filters Knowlegde Distribution.<br />

We think the bene ts of this work is twofold. First, we show how certain<br />

design issues can be addressed using Composition Filters. Second, by expressing<br />

our implementations as Design Patterns, we make our knowledge accessible to<br />

the world.


Chapter 3<br />

Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

In our daily lives we often have to deal <strong>with</strong> relatively complex materials. It is<br />

common practice then to look at the problem from di erent points of view. We<br />

will focus on a certain aspect of the problem, <strong>and</strong> forget the rest for a moment.<br />

With this simple trick we are able to underst<strong>and</strong> things that are so complex,<br />

that we could never have understood them otherwise.<br />

In this chapter, we will elaborate on the domain of views. This is how we call<br />

\the trick" when applied to software engineering. We will see how software<br />

models can be made better <strong>and</strong> easier to underst<strong>and</strong> by making views explicit<br />

in the software model.<br />

The goal of this chapter is twofold. First, we will introduce the modelling<br />

issue <strong>Multiple</strong> <strong>Views</strong> in Section 3.1. Second, we show how the concept can be<br />

modelled in C ++. In Section 3.2, we give an example implementation where<br />

the change scenario is implemented in C ++. Conclusions are summarised in<br />

Section 3.3.<br />

3.1 Modelling <strong>Multiple</strong> <strong>Views</strong><br />

In Section 3.1.1, we will show what views are, <strong>and</strong> try to give the reader enough<br />

basics to belief that views can be bene cial for h<strong>and</strong>ling complex software engineering<br />

problems. It should also give enough introduction of views to underst<strong>and</strong><br />

the rest of this chapter.<br />

In Section 3.1.2, we introduce a conceptual model of views. We will use<br />

this model as our reference throughout this chapter. It shows the di erent parts<br />

of the view model, <strong>and</strong> which changes we expect in implementations that are<br />

based on this model.<br />

These changes are detailed out in Section 3.1.3, in which we de ne a<br />

scenario where the di erent model changes are described in detail.<br />

11


12 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

3.1.1 What is a View?<br />

People often look at things around them from di erent viewpoints. This means<br />

that the same things get several di erent interpretations |even from the same<br />

person| dependent on how we look at them. We can see this often in crime<br />

scenes, where many di erent statements come from even so many witnesses.<br />

This is what we call a passive view, because the object is interpreted in several<br />

di erent ways, something this object cannot control.<br />

Also, people react di erently to the signals they receive from their environment.<br />

Some signals are always ignored, some are always accepted, <strong>and</strong> some<br />

are accepted only under certain conditions. Sometimes we even can react differently<br />

on the same signals in di erent situations. For example, when a total<br />

stranger asks your friend, say Joe,tomake him some co ee, this will probably<br />

have no e ect. It depends on the mood of Joe when some acquaintance asks the<br />

same question. When you ask it, Joe always will make your co ee (unless you<br />

just had an enormous ght of course). He will also always make co ee for his<br />

girlfriend, but he knows she does not want her co ee as strong as you want it.<br />

We will call this kind of views active, because Joe can decide for himself how<br />

he will react on the question of making co ee.<br />

These situations are very normal in our daily lives. When we model software<br />

implementations however, we tend to forget this quickly, <strong>and</strong> make all behaviour<br />

of the software components general. This does not mean that views don't exist<br />

in software models, we just don't model them explicitly.<br />

Communication happens always between two or more parties. There will<br />

always be at least one sender <strong>and</strong> one receiver of a communication message.<br />

We cannot model the passive view (i.e. the interpretation of the data that<br />

is returned from the receiver to the sender) of this communication. We can<br />

however model the active view that the receiver provides to the sender.<br />

In normal life, an active view is often dependent of the context of the communication<br />

message | think of Joe who does respond to you or an acquaintance,<br />

while ignoring a total stranger.<br />

We also want this in software models. We want to de ne communication<br />

channels explicitly. Di erent channels require di erent |or at least partly<br />

di erent| interfaces. When we model each communication channel on its own,<br />

an object appears to have an interface that in fact consists of several subinterfaces,<br />

each supporting a di erent communication channel.<br />

This division of the interface of an object is depicted in Figure 3.1. We<br />

call these sub-interfaces views. Our goal is to make views explicit in our implementations.<br />

This helps us underst<strong>and</strong>ing the communication channels that<br />

exist between di erent objects, <strong>and</strong> the respective responsibilities of the communication<br />

participants. Further, <strong>with</strong> explicit views we are able to test these<br />

views <strong>and</strong> therefore construct more robust applications, where misuse errors are


3.1. Modelling <strong>Multiple</strong> <strong>Views</strong> 13<br />

Channel 1<br />

Object Interface<br />

Chan 1 interf. Common interf. Chan 2 interf.<br />

Channel 2<br />

Figure 3.1: <strong>Multiple</strong> <strong>Views</strong> in an object-oriented environment


14 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

State<br />

spaces<br />

Relation<br />

S(t)<br />

S(o)<br />

S(c)<br />

Object<br />

functionalities<br />

Real-World<br />

<strong>Views</strong><br />

less likely to occur.<br />

Transformation functions<br />

T(v(2))<br />

T(v(1))<br />

T(M)<br />

T(v(3))<br />

T(R)<br />

M(o)<br />

Conceptual<br />

<strong>Views</strong><br />

v(1)<br />

v(2)<br />

Methods<br />

v(3)<br />

V(o)<br />

<strong>Views</strong><br />

Mapping functions<br />

Figure 3.2: Conceptual Model of <strong>Multiple</strong> <strong>Views</strong><br />

3.1.2 Conceptual View Model<br />

To be able to make a good implementation of views in an object-oriented system,<br />

we must rst supply the conceptual model of views. This model captures the<br />

di erent aspects of views, <strong>and</strong> gives us a reference model from which we will<br />

explore the whole domain.<br />

In Figure 3.1 we can see that views are de ned at the interface of an<br />

object. If we do not de ne views, they will be present, but we cannot \see" them<br />

in that case. All we have is an object <strong>with</strong> its state space (see below). The model<br />

is depicted in Figure 3.2. It shows the real world, where views are a natural part<br />

of the system. <strong>Views</strong> are present implicitly, but they are nowhere referenced<br />

explicitly. We can make views explicit by making the appropriate abstractions<br />

of the state space. We call these abstractions transformation functions.<br />

Model Components<br />

In the real world, there are three di erent elements <strong>with</strong> respect to views.<br />

1. State spaces;<br />

2. Object functionalities;<br />

3. Some interconnection between these two.<br />

These elements are discussed in detail below. In Figure 3.2, we also see three<br />

di erent kinds of transformation functions:<br />

1. The transformation from object functionalities to methods;<br />

2. The transformation from state spaces to views;<br />

3. The mapping between views <strong>and</strong> methods.


3.1. Modelling <strong>Multiple</strong> <strong>Views</strong> 15<br />

These transformation functions re ect the realisation of speci cations into models.<br />

Conventionally, only the transformation T M is realised. We de ne views<br />

explicitly by realising the other transformations as well.<br />

Methods The methods implement the application semantics, i.e. the functionalities<br />

that the class provides. The set of methods that an object supports, is<br />

denoted as<br />

M o = Object Methods (3.1)<br />

The transformation function T M provides a method for each functionality. This<br />

transformation is rather trivial <strong>and</strong> common practice to developers, <strong>and</strong> it is<br />

not further discussed here.<br />

<strong>Views</strong> The views de ne the abstractions of the State Space we are interested<br />

in. Therefore we make the following de nitions.<br />

The Object StateSpace represents the total state space of the object that<br />

receives the message. This state space is multi-dimensional, <strong>and</strong> can be seen as<br />

all possible combinations of values of all internal variables.<br />

S o = Object StateSpace (3.2)<br />

The Context StateSpace represents the total multi-dimensional state<br />

space of the context of a message. This context consists of all possible information<br />

about the message, such as the sender of the message, the selector of<br />

the message (the method that is called), the parameters of the message <strong>and</strong> the<br />

target or server (the object that the message is sent to).<br />

S c = Context StateSpace (3.3)<br />

The Total StateSpace S t represents the cartesian product of S o <strong>and</strong> S c,<br />

<strong>and</strong> thus represents the total state space of a message. The actual state of a<br />

message when it is sent is denoted as s m.<br />

S t = S o S c (3.4)<br />

s m 2 S t (3.5)<br />

A view is the abstraction from a certain situation in the real world, so from<br />

all possible states s m 2 S t there are a couple of them that are part of this<br />

abstraction:<br />

v S t (3.6)<br />

Each view v needs its own transformation function T v, because each view can<br />

cover another aspect of the state space S t. Some examples of view aspects are<br />

sender information <strong>and</strong> message history information.


16 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

Methods<br />

<strong>Views</strong><br />

Figure 3.3: Many-to-many relationship between methods M o <strong>and</strong> views V o<br />

The set of views V o now can be de ned as follows. First, we de ne the<br />

powerset P(S t) of the state space, which represents the set of all possible combinations<br />

of states from the state space S t. The set of views V o of an object<br />

then is a subset of this powerset.<br />

V o P(S t) (3.7)<br />

A view v 2P(S t) (see Equation 3.6 <strong>and</strong> Equation 3.7), so a view is in<br />

e ect when the actual state of the message s m 2 v (See Equation 3.5).<br />

Method-View Coupling The coupling between the methods M o <strong>and</strong> the views<br />

V o is done by de ning a mapping between V o <strong>and</strong> M o. This mapping is many-tomany,<br />

as is shown in Figure 3.3. This mapping occurs in the following possible<br />

cardinalities:<br />

V 7! M + (surjection) (3.8)<br />

V + 7! M (injection) (3.9)<br />

The possibilities V 7! M <strong>and</strong> V + 7! M + are both constructed from the two<br />

mentioned here.<br />

Implementation Requirements<br />

When the concepts of the previous section are implemented, wewant to preserve<br />

the exibility that the object-oriented paradigm has given us. As we have seen<br />

in Equation 3.6, a view is a set of states. When we de ne more views on an<br />

object, we also want to be able to manipulate these views using normal set<br />

operators (see Figure 3.4).<br />

Also, we want to be able to manipulate the transformation functions by<br />

de ning extensions to existing models (i.e. through subclassing) <strong>with</strong>out any<br />

unnecessary rede nitions. We want to be able to make changes, following the<br />

scenario discussed in Section 3.1.3. The changes that we want tocover are:


3.1. Modelling <strong>Multiple</strong> <strong>Views</strong> 17<br />

View<br />

Subview 1 Subview 2<br />

(a) View Partitioning<br />

View 1 View 2<br />

Combined View<br />

(b) View Composition<br />

Figure 3.4: Set Operations on <strong>Views</strong><br />

Add views;<br />

Partition views;<br />

Extend views;<br />

Add behaviour;<br />

Extend behaviour;<br />

Combine views.<br />

Note that removal of behaviour <strong>and</strong> views is not listed here. This operation<br />

also is not supported by the inheritance mechanism provided by object-oriented<br />

languages.<br />

3.1.3 Scenario of Changes<br />

In this section we describe a scenario, which covers the possible changes that<br />

can be made to an object model that incorporates views. In Section 3.1.2, we<br />

have described a model for views in an object-oriented environment. When we<br />

implement this model, we have to transform the elements of the view model<br />

to the object model that is used for the implementation. This transformation<br />

is not trivial, as we will see in the next section, <strong>and</strong> depends heavily on the<br />

implementation language.<br />

The scenario starts <strong>with</strong> an object model, where views are not present<br />

yet. The interface is assumed public, so all methods are visible to all potential<br />

clients. We will start from that point, <strong>and</strong> rst add view semantics to the model.<br />

Then we follow a scenario of changes to this model. This scenario will show how<br />

easy (or hard) it is to adjust an object model <strong>with</strong> views.<br />

Add <strong>Views</strong><br />

In order to be able to de ne views on the interface of a class, we have to identify<br />

a mapping between the view model <strong>and</strong> the object model. The view model has<br />

three types of transformations (see Figure 3.2). The transformation of views<br />

needs special attention, because we have to be able to cover all possible forms<br />

of transformations, like sender <strong>and</strong> history information.


18 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

In the example that we will discuss in Section 3.2, we need the following<br />

categories of transformations (these are all view transformations):<br />

Access Control We need to provide some means of access control to the methods<br />

we have de ned. We want to restrict the interface of a class to one<br />

or more other classes in such a way, that only classes that are granted<br />

access can use the object, <strong>and</strong> others can not.<br />

Context Information We need a way of determining context information<br />

about a message. For example, if we want to prevent access from some<br />

class to one or more methods, we need to know what object sent the<br />

message.<br />

Meta Information We need to determine the type of an object at runtime. In<br />

other words, we need some meta information about objects <strong>and</strong> classes.<br />

History Information Sometimes we want to de ne views that are not based<br />

on the actual situation, but on the things that have happened in the<br />

past. In this situation we need to be able to deduce history information<br />

about messages from the objects.<br />

View Partitioning<br />

Sometimes we want to partition a view into two or more views. This is the<br />

consequence of re ning some part(s) of the speci cation. Suppose we have a<br />

view v 2 V o, i.e. the original view that we want to re ne. We de ne the partition<br />

v = 1 [ 2;:::<br />

Note that i 2P(S t), because V o 2P(S t), where P(S t) is the powerset of S t.So<br />

we can conclude that the partitions i are ordinary views on the object! They<br />

only have an extra property, which is that they together form the original view,<br />

thus i 2P(V o).<br />

Partitioning a view into several sub-views, in a way invalidates the original<br />

view. Thus, all references made to this view also must be removed.<br />

View Extension<br />

Extending a view means enlarging the set of possible values under which the<br />

view is active. The requirements only involve changing the view v 2 V o, <strong>and</strong><br />

thus the set V o. The identi er of this view remains the same, in contrast <strong>with</strong><br />

Section 3.2.3, where we will see a change of the view set V o, the identi ers<br />

inclusive. The encapsulation property of the implementation ensures us that in<br />

this case only the implementation of this view needs to be rewritten.<br />

Add Behaviour<br />

When we add behaviour to an object, we need to extend the method set M o<br />

of the object (see Equation 3.1). Also, the new behaviour probably falls under<br />

one or more views that are de ned on the object, so the set of mappings also<br />

needs to be extended.


3.1. Modelling <strong>Multiple</strong> <strong>Views</strong> 19<br />

Behaviour Extension<br />

Behaviour extension can have the following interpretations.<br />

Application Behaviour Extension This form of behaviour extension is the normal<br />

one, for which the inheritance mechanism of object-oriented languages is<br />

used. The original behaviour is \overwritten" <strong>with</strong> another one, so that all objects<br />

of the new (sub)class have the adapted behaviour. Note that this form of<br />

behaviour extension is static, i.e. it yields for all objects of this class.<br />

In terms of the view model discussed in Section 3.1.2, the extension of<br />

application semantics maps to the extension of the object functionalities, <strong>and</strong><br />

the addition of a mapping from this functionality to an object method m 2 M o.<br />

Meta Behaviour Extension Meta behaviour extension is totally di erent, because<br />

it does not really adapt the normal behaviour of the objects. It interprets<br />

the in- <strong>and</strong> outgoing messages of objects, <strong>and</strong> according to this information the<br />

behaviour of the object can be changed. So, object behaviour can (but does not<br />

have to) change because of meta behaviour extension, but when it does, it will<br />

be indirectly. Also this form of extension is static.<br />

Meta behaviour extension does not alter the method set M o. It does alter<br />

the view set, where a view is added or extended, that uses not only object state<br />

space information from S o, but also context state space information from S c,<br />

where information about the message is used to check for the validity of the<br />

view.<br />

Dynamic Behaviour Extension Dynamic behaviour extension can be application<br />

as well as meta behaviour extension. The extra property here is dynamicity.<br />

Not all objects of the new class have to get the new behaviour. It is also possible<br />

that not all invocations to the same object result in the same behaviour. This<br />

dynamicity isanimportant property that must be used in an implementation<br />

where close resemblance of the real world is necessary.<br />

We can see this as follows in the model of Section 3.1.2. In Figure 3.2,<br />

we see a mapping between object functionalities <strong>and</strong> object methods. Normally,<br />

this mapping results in one method per functionality (ignoring the fact that this<br />

method will almost always be divided in several smaller methods). It is possible<br />

however, that two di erent implementations exist for one object functionality.<br />

Depending on some view speci cations, one or the other implementation for the<br />

message will be activated.<br />

Think for example of an object class Collection, where the implementation<br />

of the sort message is dependent of the size of the collection (i.e. the<br />

actual number of elements). The behaviour of the sort message then is dynamic.<br />

The needed implementation can be chosen at runtime, depending on some state<br />

information. When we de ne the needed states in views, we choose <strong>and</strong> activate<br />

the best implementation depending on the current object state. So in our exam-


20 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

ple, the sort functionality has two implementations: quickSort <strong>and</strong> bubbleSort.<br />

The views for these methods are smallCollection <strong>and</strong> largeCollection. When we<br />

map, for the message sort, the view smallCollection to the method bubbleSort<br />

<strong>and</strong> the view largeCollection to the method quickSort, we have implemented a<br />

system where the object itself chooses the best implementation for a speci c<br />

behaviour at runtime, depending on some view speci cation.<br />

View Composition<br />

<strong>Views</strong> can be partitioned, as is discussed in Section 3.1.3, but they also can be<br />

composed. This means that two or more di erent views together de ne another<br />

view which is used to express some situation. With this mechanism it is possible<br />

to build a hierarchy of views, so that mappings to methods can be performed<br />

at an arbitrary granularity.<br />

Further, when two object classes are combined through inheritance, their<br />

state spaces also will be combined. It is very likely that methods of the rst<br />

object have to be restricted by views of the second object, so that additional<br />

mappings between methods <strong>and</strong> views have to be de ned. This mapping however<br />

crosses class boundaries, which is not a trivial thing to do.<br />

3.2 C++ Implementation<br />

Now wehave a clear overview of what views are, <strong>and</strong> what changes we want to<br />

be able to perform on a view implementation. We de ne an example on which<br />

we can test these changes. In the previous section, we listed the changes that<br />

we want to perform. We map these changes directly to our example. We start<br />

<strong>with</strong> a fresh example <strong>with</strong>out any views, <strong>and</strong> then, in six di erent stages, we<br />

extend our speci cation following the steps of Section 3.1.3. In Figure 3.5, we<br />

see the Mail class, <strong>and</strong> all subsequent subclasses that implement the steps of<br />

the scenario. Note that the scenario must be read from top to bottom.<br />

As the legend says, the white coloured classes are classes <strong>with</strong> application<br />

semantics. They are present because they have direct meaning for the<br />

program. The light-grey coloured classes also implement application semantics,<br />

but this is <strong>with</strong> a lot of overhead. This means that the implementation is heavy<br />

relative to its functionality. The dark-grey coloured classes are pure overhead.<br />

The . . . User classes mostly only implement a test function. The Object class<br />

implements runtime type information. This is necessary for the meta information<br />

we use in our implementation, <strong>and</strong> also for declaring \typeless" function<br />

arguments. 1 We can see that the Object class is pure overhead, <strong>and</strong> it also<br />

requires us to de ne overhead code in all subclasses of it, in order to let the<br />

Object functions return correct values. Finally, the MVMailH<strong>and</strong>ler class<br />

1. C ++ is strictly typed, which means that a function <strong>with</strong> an argument oftype Object can<br />

only be passed arguments of type Object, or a subtype of this type.


3.2. C ++ Implementation 21<br />

Object<br />

SecureDocument<br />

Legend<br />

User<br />

MVUser<br />

VPUser<br />

GroupUser<br />

PGPUser<br />

Warning2User<br />

ProtectedUser<br />

Normal class<br />

Normal class (<strong>with</strong> overhead)<br />

Overhead class<br />

Mail<br />

UserSystemViewMail<br />

OriginatorReceiverViewMail<br />

GroupMail<br />

SecureMail<br />

Warning2Mail<br />

ProtectedMail<br />

Figure 3.5: <strong>Multiple</strong> <strong>Views</strong> Scenario<br />

MailH<strong>and</strong>ler<br />

MVMailH<strong>and</strong>ler<br />

Add <strong>Views</strong><br />

Partition <strong>Views</strong><br />

Extend <strong>Views</strong><br />

Extend Behaviour (dynamic)<br />

Extend Behaviour (static meta)<br />

Compose <strong>Views</strong><br />

Scenario direction


22 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

is only present because introducing views means adapting the class interface of<br />

UserSystemViewMail.<br />

Now we will describe the running example. It covers the implementation<br />

of a Mail System. This system is capable of sending <strong>and</strong> receiving mail messages<br />

from <strong>and</strong> to users via a so-called mail h<strong>and</strong>ler. The idea is that a user creates a<br />

mail message, <strong>and</strong> sends it to the mail h<strong>and</strong>ler. This mail h<strong>and</strong>ler then routes<br />

the mail message <strong>and</strong> delivers it to the recipient. For clarity, we provide a list<br />

of terminology here.<br />

MailMessage The mail message that is to be sent from one user to another.<br />

MailOriginator The user that sends a MailMessage.<br />

MailReceiver The user that receives a MailMessage.<br />

User A user of the mail system, i.e. a MailOriginator or a MailReceiver.<br />

MailH<strong>and</strong>ler The system that receives a MailMessage from a User (the Mail-<br />

Originator) <strong>and</strong> routes it to the appropriate User (the MailReceiver).<br />

3.2.1 Simple Mail System<br />

In this section we show the implementation of the Simple Mail System. It only<br />

implements the normal expected semantics <strong>with</strong>out views. It provides a real<br />

executable mail system.<br />

To implement this system, we introduce the following classes:<br />

MailH<strong>and</strong>ler This class implements the central post o ce that routes Mail-<br />

Messages from <strong>and</strong> to Users.<br />

User This class implements the person objects that send <strong>and</strong> receive MailMessages<br />

from <strong>and</strong> to each other (the MailOriginator <strong>and</strong> the MailReceiver<br />

objects).<br />

Mail This class implements the MailMessage itself. The <strong>Multiple</strong> <strong>Views</strong> that<br />

this chapter is about will be de ned on this class, so this is the only<br />

real important class of the example. The other two classes are present to<br />

support the example.<br />

Note that we only elaborate on the MailMessage de nition, because the User<br />

<strong>and</strong> the MailH<strong>and</strong>ler classes only are present to support the example. The<br />

class Mail has the following interface speci cation:<br />

setMailOriginator This method is used to set the originator of the MailMessage.<br />

getMailOriginator This method is used to inspect who sent the MailMessage.<br />

setMailReceiver This method is used to indicate to whom the MailMessage is<br />

to be sent.<br />

getMailReceiver This method is used to inspect the receiver of the MailMessage.<br />

setMailContents This method is for setting the contents of the MailMessage.<br />

getMailContents This method is used to inspect the contents of the MailMessage.<br />

send This method is used to send the MailMessage to the indicated MailReceiver.


3.2. C ++ Implementation 23<br />

MailOriginator MailMessage MailH<strong>and</strong>ler MailReceiver<br />

setMailOriginator<br />

setMailReceiver<br />

setMailContents<br />

send<br />

send<br />

getMailReceiver<br />

getMailContents<br />

approve<br />

setRoute<br />

setDelivered<br />

getMailOriginator<br />

getMailContents<br />

receive<br />

Figure 3.6: Object Interaction Diagram for the Mail System<br />

reply This method is used to send a reply to the MailOriginator.<br />

approve This method is used to tell the MailMessage that it is approved for<br />

delivery by the MailH<strong>and</strong>ler.<br />

isApproved This method is used to inspect if the MailMessage is approved for<br />

delivery.<br />

setDelivered This method is used to set the indication that the MailMessage is<br />

delivered to the MailReceiver.<br />

isDelivered This method is used to inspect if the MailMessage is delivered to<br />

the MailReceiver.<br />

setRoute This method is used to set the routing information of the MailMessage.<br />

getRoute This method is used to inspect the routing information of the Mail-<br />

Message.<br />

In Figure 3.6, the expected runtime behaviour of the system is displayed. Certain<br />

details are omitted here for simplicity. The order of the messages setMailOriginator,<br />

setMailReceiver <strong>and</strong> setMailContents from the MailOriginator to the<br />

MailMessage is irrelevant. Further, the MailOriginator will be inspecting the<br />

instance variables of the MailMessage via the get. . . methods.<br />

The implementation of this system is rather straightforward. The C ++<br />

implementation is listed in Appendix A.1.<br />

An interesting detail in Figure 3.6 is the call of getMailContents by the Mail-<br />

H<strong>and</strong>ler. This is unauthorised use of the method (we do not want the postman<br />

to read our love letters), <strong>and</strong> we want to prevent this in the next version of our


24 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

Mail System.<br />

setMailOriginator<br />

getMailOriginator<br />

setMailContents<br />

getMailContents<br />

setMailReceiver<br />

getMailReceiver<br />

send<br />

reply<br />

approve<br />

isApproved<br />

setDelivered<br />

isDelivered<br />

setRoute<br />

getRoute<br />

p<br />

p p<br />

p<br />

p<br />

p<br />

p p<br />

p<br />

p<br />

p<br />

p p<br />

p<br />

p p<br />

p<br />

p p<br />

UserView SystemView<br />

Table 3.1: Access rules for the Mail System<br />

3.2.2 Add <strong>Views</strong>: UserSystemView Mail System<br />

In the Simple Mail System we saw the implementation of a straightforward<br />

mailing system. It was capable of sending MailMessages from one User (the<br />

MailOriginator) to another (the MailReceiver) through the MailH<strong>and</strong>ler. Now<br />

we are going to extend this system <strong>with</strong> views.<br />

Motivation<br />

We want to divide the interface of Mail into di erent views, that clearly separate<br />

the di erent functionalities that the interface provides.<br />

We saw in Figure 3.6 that the MailH<strong>and</strong>ler was peeking into the Mail-<br />

Message. With the application of views, wewant to prevent such misuse in the<br />

future.<br />

The interface of Mail is rather \big" already. When the number of<br />

methods grows even larger, it is not clear anymore which methods serve what<br />

purpose. Being able to see the sub-interfaces of a relatively large class interface<br />

makes this interface much more readable.<br />

Semantic Structure<br />

As can be seen in Figure 3.6, there are two di erentinterfaces in the class Mail.<br />

These are the UserView <strong>and</strong> the SystemView. Some methods only apply for<br />

Users, <strong>and</strong> some other methods only apply for the MailH<strong>and</strong>ler of the system.<br />

There are also methods that have no restrictions. Wewant to divide the interface<br />

of class Mail as follows.<br />

To be able to implement this, we augment the de nition of class Mail.<br />

These changes have the following bases (See also Section 3.1.3).


3.2. C ++ Implementation 25<br />

Access Control We need to provide some means of access control to the methods<br />

we have de ned. We want to restrict the interface of class Mail to<br />

the class User in such away, that User objects have noway in calling<br />

the SystemView methods approve, setDelivered <strong>and</strong> setRoute in Table 3.1.<br />

Context Information We need a way of determining context information<br />

about a message. For example, if we want to prevent access from a User<br />

to the method setRoute, we need to know which object sent the message.<br />

Meta Information We need to determine the type of an object at runtime<br />

(such asaUser). In other words, we need some meta information about<br />

objects <strong>and</strong> classes.<br />

Implementation Consequences<br />

In C ++, we do not have the Context state space S c (Equation 3.3), so we cannot<br />

support views that depend on this information <strong>with</strong>out providing it by h<strong>and</strong>.<br />

We need this information, because we want to restrict access dependent onthe<br />

type of the sender, <strong>and</strong> the sender is part of S c.<br />

We can only provide context state space information by explicitly passing<br />

the sender of the messages to the receiving object. This is of course not<br />

fool-proof, <strong>and</strong> error-prone. Furthermore, it needs modi cation of the class interfaces,<br />

which breaks reusability of classes <strong>with</strong>out view implementations in<br />

classes <strong>with</strong> a view implementation. This means a lot of (unnecessary) recoding<br />

of methods when views are added to a class dictionary. This is seen in the example<br />

in Appendix A.2, where the User <strong>and</strong> the MailH<strong>and</strong>ler classes have<br />

to be rede ned only because the interface of Mail has changed.<br />

We also have a problem <strong>with</strong> the mapping between the methods M o <strong>and</strong> the<br />

views V o. There is no way ofintercepting an incoming message in a central place<br />

in an object, in order to test for the mapping relation. The only way of testing<br />

the mapping relation is in the method de nition itself. But in doing so, we are<br />

integrating the methods M o <strong>with</strong> the mappings, which is not what we want. To<br />

avoid this, we de ne the methods M o in a private section of the object, so the<br />

outside world cannot use it. These private methods implement the application<br />

semantics, while the public methods implement the method-view mappings.<br />

This approach has one drawback. The overview of the class interface is<br />

lost again (we wanted to approve this <strong>with</strong> views) because of the enormous<br />

amount of methods that appear. The UserSystemViewMail class from Appendix<br />

A.2 has a lot of methods (33!), while we wanted only the 15 of the<br />

non-view implementation from the Mail class from Appendix A.1.<br />

The origin of this problem lies in the N : M relation between methods<br />

M o <strong>and</strong> views V o. We can only intercept at the method entrance point. When<br />

we have one method that couples to more than one view, this is no problem.<br />

With views however, we often have a view, which is coupled to a number of<br />

methods. We can only implement this by repeating coupling information for


26 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

each method.<br />

The views V o are implemented using Boolean functions. This provides a central<br />

de nition of the views, so they can be reused in the rest of the class speci cation,<br />

<strong>and</strong> they can also be rede ned easily <strong>with</strong>out recoding other parts of the class<br />

speci cation.<br />

However, we need information we do not have. We need to deduce the<br />

type (class) of the sender object, in order to decide if access is allowed. This type<br />

of meta-information is not present inC ++, <strong>and</strong> must explicitly be implemented.<br />

The scheme that is used in many commercial class libraries does the job pretty<br />

well.<br />

The implementation in Appendix A.2 uses an internal Mail object in User-<br />

SystemViewMail. One could have expected an inheritance relation here. We<br />

have not done this, because the interface had to be rewritten completely, <strong>and</strong> it<br />

is impossible to completely hide the interface of the parent class <strong>with</strong>out losing<br />

the inheritance bene ts.<br />

The interface of Mail must be made invisible. If we don't do this, the<br />

application still can call the old versions of the methods (by omitting the sender<br />

parameter). So the Mail class must be made protected or private. But then<br />

we cannot pass the UserSystemViewMail objects to functions that expect<br />

Mail objects as a parameter. We can trick this by explicitly casting the parameter<br />

to be of class Mail, but then the called function can freely access the<br />

old de nitions of the functions. This will not bring us any further, so to avoid<br />

complications, we de ned the Mail object as an internal variable of User-<br />

SystemViewMail.<br />

In Figure 3.7, we see a piece of code de ning views in a C ++ class. This example<br />

is an extract of Appendix A.2, <strong>and</strong> has all the elements in it that we discussed in<br />

this section. All interface methods have the context parameter sender de ned.<br />

Also, the interfaces are separated from the implementation, which separates<br />

application semantics from method-view mappings. The views are de ned as<br />

Boolean functions, <strong>and</strong> the class must inherit from some generic class Object<br />

which provides runtime type information.<br />

3.2.3 View Partitioning: OriginatorReceiverView Mail System<br />

In the UserSystemView Mail System we saw a Mail System that separated the<br />

Mail interface in a part for the Users, <strong>and</strong> a part for the MailH<strong>and</strong>ler. In this<br />

section we re ne the UserView.<br />

Motivation<br />

In this section we are going to divide a view into several sub-views. With this, we<br />

show the (non-) exibility <strong>and</strong> composability of the implementations of views.


3.2. C ++ Implementation 27<br />

class UserSystemViewMail : public Object<br />

f<br />

public:<br />

virtual classTypes myClass(void)<br />

f return UserSystemViewMailClass; g<br />

virtual void setMailOriginator(Object ,MVUser );<br />

:::;<br />

protected:<br />

virtual int isUserView(Object );<br />

virtual int isSystemView(Object );<br />

private:<br />

virtual void pureSetMailOriginator(MVUser );<br />

:::;<br />

g;<br />

void<br />

UserSystemViewMail::setMailOriginator(Object sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender), this!pureSetMailOriginator(u));<br />

g<br />

int<br />

UserSystemViewMail::isUserView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return sender!isKindOf(MVUserClass);<br />

g<br />

void<br />

UserSystemViewMail::pureSetMailOriginator(MVUser u)<br />

f<br />

mail!setMailOriginator(u);<br />

g<br />

Figure 3.7: Adding <strong>Views</strong> in C ++


28 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

Semantic Structure<br />

setMailOriginator<br />

setMailContents<br />

getMailContents<br />

setMailReceiver<br />

send<br />

reply<br />

OriginatorView ReceiverView<br />

p<br />

p<br />

p p<br />

p<br />

p<br />

p<br />

Table 3.2: Separation of UserView methods<br />

In the UserSystemView Mail System, we saw the implementation of a mailing<br />

system which had two views. These views separated the interface of Mail into<br />

a part that was accessible to the Users, <strong>and</strong> one part for the MailH<strong>and</strong>ler.<br />

The UserView is too broad however. This view allows all Users inthesystem<br />

to manipulate all MailMessages in the system. In the OriginatorReceiverView<br />

Mail System, we are going to restrict this.<br />

Table 3.2 shows the separation of methods from the UserView in the<br />

UserSystemView Mail System into the two views OriginatorView <strong>and</strong> Receiver-<br />

View. Note that this is not a total partitioning. From all Users in the system,<br />

only the MailOriginator <strong>and</strong> the MailReceiver will have some access to the<br />

MailMessage. All other Users will have no access at all. Also note that methods<br />

<strong>with</strong>out any access restrictions are not listed here.<br />

We have to de ne the new views, <strong>and</strong> wehave to attach the methods from<br />

Table 3.2 to the views. Note that we donot rede ne any application semantics<br />

(from the original Mail class).<br />

Implementation Consequences<br />

Implementing this view partitioning in C ++ has the following consequences. The<br />

view set V o has changed, so we need a couple of extra functions to implement<br />

these views. Further, all method-views couplings that refer to the UserView<br />

have to be rewritten. Now the shortcomings of the C ++ solution mentioned in<br />

Section 3.2.2 becomes clear. All methods that de ne a method-view coupling<br />

<strong>and</strong> refer to the view UserView have to be rewritten. In Figure 3.8 we can see<br />

this. When we had been able to use a central place for this coupling, we could<br />

have avoided this situation.<br />

3.2.4 View Extension: Group Mail System<br />

The OriginatorReceiverView Mail System provided a secure access to the Mail-<br />

Message for only those users that were in any way related to the MailMessage.<br />

In this section we are going to extend the view semantics.


3.2. C ++ Implementation 29<br />

class OriginatorReceiverViewMail : public UserSystemViewMail<br />

f<br />

public:<br />

virtual void setMailOriginator(Object ,MVUser );<br />

virtual void setMailReceiver(Object ,MVUser );<br />

:::;<br />

protected:<br />

virtual int isOriginatorView(Object );<br />

virtual int isReceiverView(Object );<br />

g;<br />

void<br />

OriginatorReceiverViewMail::setMailOriginator(Object<br />

sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender),<br />

UserSystemViewMail::setMailOriginator(sender,u));<br />

g<br />

int<br />

OriginatorReceiverViewMail::isOriginatorView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return (this!getMailOriginator(this) (MVUser )0)<br />

jj sender this!getMailOriginator(this);<br />

g<br />

Figure 3.8: Partitioning <strong>Views</strong> in C ++


30 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

Motivation<br />

This section will show the implications of extending the view semantics.<br />

Semantic Structure<br />

The semantics of the OriginatorView is too restrictive for our purpose. When a<br />

User has created a MailMessage, he or she is the only one that can manipulate<br />

the MailMessage until it is sent to the MailReceiver.Wewant to be able to allow<br />

all members of the same group of Users to manipulate MailMessages. In this<br />

way it is possible that a person of some group creates the MailMessage, another<br />

group member reviews it, <strong>and</strong> nally the secretary archives the MailMessage<br />

<strong>and</strong> sends it to the MailReceiver.<br />

Implementation Consequences<br />

Because we separated view de nitions from the rest of the class speci cation,<br />

we only have to de ne a new method for the OriginatorView. In Appendix A.4<br />

this is made clear. The only extras implemented besides the view are some test<br />

functions.<br />

3.2.5 Dynamic Behaviour Extension: Secure Mail System<br />

The GroupMail System extended the view semantics. Now we will add some<br />

extra behaviour to the Mail System.<br />

Motivation<br />

This section will show the consequences of extending the behaviour of the Mail<br />

System. We will implement dynamic behaviour here, showing that views are<br />

not only used for access control.<br />

Semantic Structure<br />

The Mail class implemented direct storage <strong>and</strong> retrieval of the MailContents<br />

until now. In this section we implement a new feature. The contents of the<br />

MailMessage will be encrypted using the PGP protocol automatically, when<br />

the participating Users support this protocol.<br />

This requirement introduces something special: We now have two different<br />

implementations for the same method(s). The setMailContents method<br />

must eventually encode the MailContents, <strong>and</strong> the getMailContents eventually<br />

must decode the MailContents to make it readable again.<br />

To implement this, we introduce a new view, PGPUserView, which is<br />

active when the User supports the PGP protocol. If this is true, the new encoding<br />

<strong>and</strong> decoding versions of setMailContents <strong>and</strong> getMailContents will be used.<br />

Otherwise the system will use the \normal" versions.<br />

This has the impact that only Users that support the protocol will be<br />

able to read messages that are encoded. This re ects the real world situation,


3.2. C ++ Implementation 31<br />

where a person cannot read PGP encoded messages when he does not support<br />

the protocol.<br />

Implementation Consequences<br />

For the implementation, we introduce the new view, PGPUserView, <strong>and</strong> couple<br />

this view to the methods getMailContents <strong>and</strong> setMailContents. Figure 3.9 shows<br />

that the new getMailContents now chooses implementation dependent on some<br />

view de nition. There are no further consequences besides those wehave already<br />

seen.<br />

3.2.6 Static Meta Behaviour Extension: Warning2 Mail System<br />

In this section we will extent the behaviour semantics in another way. We reify<br />

the messages <strong>and</strong> alter our behaviour depending on the obtained information.<br />

Motivation<br />

We want to show how meta information about messages can be used to reason<br />

about these messages.<br />

Semantic Structure<br />

In this section we extent the semantics of the Mail class in such away, that it<br />

may output a warning when one of the methods setMailOriginator, setMailReceiver,<br />

setMailContents or send is called, depending on some conditions.<br />

It adds something new to the system. We had methods M o, views V o<br />

<strong>and</strong> method-view mappings. Which one is changed when we want to add the<br />

desired behaviour?<br />

We said before in Equation 3.4 that context information about the messages<br />

(S c)was part of the total state space, from which views were abstracted.<br />

We have omitted a precise de nition about this state space. A part of this space<br />

consists of all information about the message that is sent, including the selector<br />

that indicates which method should be executed. Because message information<br />

is part of the state space S c, we can de ne a view that covers this part of the<br />

state space S t.<br />

The implementation of the view will be a problem however, because we<br />

access meta information about the message, something we did not do before.<br />

Implementation Consequences<br />

In C ++, we do not have information about a sent message. In Appendix A.2<br />

we already were confronted <strong>with</strong> this fact, because we needed the sender of the<br />

message. In this case we want other information about the message, namely<br />

the selector. This information is implicitly available, because we can see this<br />

in the method body itself. But because we have to count the number of times<br />

the message is sent, we need this information explicitly. This is not part of the<br />

language, so we need to implement this ourselves. Figure 3.10 shows us how it


32 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

class SecureMail : public GroupMail<br />

f<br />

public:<br />

virtual char getMailContents(Object );<br />

:::;<br />

private:<br />

virtual char purePGPGetMailContents(Object );<br />

g;<br />

char<br />

SecureMail::getMailContents(Object sender)<br />

f<br />

char s (char )0;<br />

if (this!isPGPUserView(sender)) f<br />

s this!purePGPGetMailContents(sender);<br />

g else f<br />

s GroupMail::getMailContents(sender);<br />

g<br />

return s;<br />

g<br />

char<br />

SecureMail::purePGPGetMailContents(Object sender)<br />

f<br />

char l, s strdup(GroupMail::getMailContents(sender));<br />

cout "PGP decoding...nn";<br />

for (l s; l;l++) ( l)--;<br />

return s;<br />

g<br />

Figure 3.9: Dynamic Behaviour Extension in C ++


3.2. C ++ Implementation 33<br />

typedef enum f<br />

W2MailSetMailOriginatorSelector,<br />

:::<br />

lastWarning2MailSelector<br />

g Warning2MailSelector;<br />

class Warning2Mail : public SecureMail<br />

f<br />

public:<br />

virtual void setMailOriginator(Object , MVUser );<br />

:::;<br />

private:<br />

int selectorCount[ lastWarning2MailSelector];<br />

g;<br />

void<br />

Warning2Mail::setMailOriginator(Object sender, MVUser u)<br />

f<br />

if (this!isWarning2View(W2MailSetMailOriginatorSelector)) f<br />

cout "Warning, setMailOriginator sent twicenn";<br />

g<br />

selectorCount[W2MailSetMailOriginatorSelector]++;<br />

SecureMail::setMailOriginator(sender,u);<br />

g<br />

Figure 3.10: Static Meta Behaviour Extension in C ++


34 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

can be done in C ++. Appendix A.6 shows the complete solution. The solution is<br />

rather ad-hoc however, <strong>and</strong> again repeats the method-view coupling more often<br />

than we want.<br />

An alternative implementation can explicitly build a meta object of the<br />

message, <strong>and</strong> pass it as a parameter to another method which does the counting<br />

<strong>and</strong> registration of incoming messages. At this point, this alternative would be<br />

too distracting for the example now.<br />

3.2.7 View Composition: Protected Mail System<br />

We have made several enhancements to the Mail System. We even added some<br />

level of security by applying the PGP protocol. But protection using security<br />

levels is still missing from the scene.<br />

Motivation<br />

We add the protection functionality, because we want to test how easily we can<br />

combine di erent views into one object. The existing views of Mail will be<br />

combined <strong>with</strong> the views of a new class SecureDocument, which acts as the<br />

security wall for the MailMessages.<br />

Semantic Structure<br />

The next version of the Mail System, the Protected Mail System, combines<br />

the existing views of the Warning2 Mail System <strong>with</strong> views that exist in the<br />

SecureDocument class.<br />

SecureDocument implements a securityClearance view <strong>with</strong> a security<br />

level attached to it. The view is active when the security level of the calling<br />

object is su cient <strong>with</strong> respect to the security level of the document.<br />

The implementation of this SecureDocument must conform to the<br />

<strong>Multiple</strong> <strong>Views</strong> semantics, because we are going to combine the views on SecureDocument<br />

<strong>with</strong> those on Warning2Mail.<br />

Because the user who wants to set or read the message contents has<br />

to have security clearance, we need to de ne a new user class that adds this<br />

functionality to Mail users. The class is called ProtectedUser, <strong>and</strong> has<br />

methods for setting <strong>and</strong> retrieving the security level of the user.<br />

The semantics of the getMailContents <strong>and</strong> the setMailContents will be<br />

enhanced, because the view securityClearance must be checked.<br />

Two di erent implementation alternatives are possible here. The SecureDocument<br />

only implements a view. This functionality can be included<br />

in the new ProtectedMail class directly, sothe implementation uses single<br />

inheritance. Another, more illustrative solution uses multiple inheritance, <strong>and</strong><br />

de nes SecureDocument as a separate class.<br />

The ProtectedMail class is the combination of the Warning2Mail <strong>and</strong> the<br />

SecureDocument classes. The view set thus is also the combination of the


3.3. Conclusions 35<br />

class SecureDocument:public Object f<br />

:::;<br />

protected:<br />

int isSecurityClearance(Object );<br />

:::;<br />

g;<br />

class ProtectedMail : public Warning2Mail, public SecureDocument<br />

f<br />

public:<br />

virtual void setMailContents(Object ,char );<br />

:::;<br />

g;<br />

void<br />

ProtectedMail::setMailContents(Object sender, char s)<br />

f<br />

CFilter(this!isSecurityClearance(sender),<br />

Warning2Mail::setMailContents(sender,s));<br />

g<br />

inherited views:<br />

Implementation Consequences<br />

Figure 3.11: View Composition in C ++<br />

[<br />

VprotectedMail = Vwarning2Mail VsecureDocument<br />

(3.10)<br />

In C ++ we use multiple inheritance to combine the classes Warning2Mail <strong>and</strong><br />

SecureDocument. In Figure 3.11 we can see that we only have to rewrite<br />

the method-view coupling of getMailContents <strong>and</strong> setMailContents, where we<br />

directly refer to view de nitions from parent classes (in this case SecureDocument).<br />

3.3 Conclusions<br />

In this chapter we have de ned a model for <strong>Multiple</strong> <strong>Views</strong>. Also, we listed the<br />

possible adaptations to the model, <strong>and</strong> de ned a running example that showed<br />

us how <strong>Multiple</strong> <strong>Views</strong> can be implemented in a \conventional" object-oriented<br />

language like C ++.<br />

We have seen that using such a language has several drawbacks when we<br />

want to implement a semantic-rich concept like <strong>Multiple</strong> <strong>Views</strong>. It turns out<br />

that C ++ lacks the following properties:


36 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong><br />

Static meta information, such as the class of an object, or the methods a<br />

certain class has. In short, we cannot ask some class or object questions<br />

about its de nition.<br />

Dynamic meta information, such as the sender <strong>and</strong> the parameters of a<br />

message, or information about when the message was sent. We have seen<br />

that all this information was to be given by the programmer, something<br />

we could not check <strong>and</strong> control.<br />

A central entrance point for all incoming <strong>and</strong> outgoing messages for an<br />

object, where we can guard <strong>and</strong> control what is going on in the objects.<br />

This has the consequence that we cannot neatly separate the methods<br />

from the views, <strong>with</strong>out making strict coding conventions, which of<br />

course are error-prone. Further, as we have seen already too often, that<br />

a lot of recoding was necessary, which was the consequence of a missing<br />

central entry point.<br />

In short we can say that implementing <strong>Multiple</strong> <strong>Views</strong> in a language like C ++<br />

is possible, but that it results in code that is not maintainable very well. One<br />

has to realise that a lot of recoding must be carried out when adaptations to<br />

the software models must be made. Moreover, one has to stick <strong>with</strong> coding<br />

conventions, because otherwise the scheme will simply not work. This is a very<br />

undesirable situation, because errors can easily occur, <strong>and</strong> are very di cult to<br />

detect.<br />

A lot of the exposed problems are there, because we wanted the views<br />

to be composable. Ifwe had implemented view semantics in the methods themselves,<br />

we could not have adapted views or method semantics independent from<br />

each other. This means that using views in the wrong way would have broken<br />

the reusability property of object oriented problems, therefore making the<br />

introduction of views in a software model not composable <strong>with</strong> other future<br />

adaptations of the system.<br />

Smalltalk implementation<br />

We did not give the example code in Smalltalk, but we will give some hints<br />

about it here.<br />

Access control We can not prevent objects from calling any method that is<br />

de ned at the interface of another object. This is a problem, because we separated<br />

the methods from the method-view mappings in our C ++ implementation,<br />

<strong>and</strong> made the original methods invisible for the outside world. We cannot do<br />

this in Smalltalk.<br />

Context information In Smalltalk, context information is not explicitly available.<br />

There is a possibility however to extract the sender of a message from the


3.3. Conclusions 37<br />

execution context of a message. This is not trivial however, <strong>and</strong> requires inside<br />

knowledge of the Smalltalk implementation that is used.<br />

Meta information In Smalltalk, every object in the system has a corresponding<br />

class associated <strong>with</strong> it, which we can access <strong>and</strong> inspect at runtime. So, meta<br />

information is fully available in Smalltalk.<br />

Central entry point for method execution We also have no special central entry<br />

point for methods in Smalltalk. Just like inC ++, wehave to separate methods<br />

from method-view mappings by renaming the original methods to something<br />

like pure.... We can prevent heavy rede nition of methods like inC ++ however<br />

by taking advantage of the doesNotUnderst<strong>and</strong> mechanism. If we do not de ne<br />

explicit normal methods, the Smalltalk runtime system cannot nd the method,<br />

<strong>and</strong> will raise an exception <strong>and</strong> call the doesNotUnderst<strong>and</strong> method. Here we<br />

could de ne global mappings for the entire object.


38 Chapter 3. Modelling Issue: <strong>Multiple</strong> <strong>Views</strong>


Chapter 4<br />

Modelling Issue: <strong>Layering</strong><br />

When we use something that does not completely satisfy our needs, we adapt<br />

it conform our wishes. The best way of doing this, is leaving the original thing<br />

intact, so others can use the original, <strong>and</strong> you have a clear overview of your<br />

changes.<br />

In this chapter we will cover the domain of layering. When adaptations to things<br />

(objects) are incremental, i.e. <strong>with</strong>out tampering <strong>with</strong> the original, we will call<br />

this incremental change a layer. When we want yet another change, we create<br />

another layer. In this way, several layers can be built upon one object, re ecting<br />

several successive adaptations.<br />

In Section 4.1 we discuss our layering model. Section 4.2 then covers the<br />

C ++ implementation of the de ned scenario <strong>with</strong> a running example. Conclusions<br />

are summarised in Section 4.3.<br />

4.1 Modelling Layers<br />

In Section 4.1.1 we introduce layering as a modelling mechanism. A more formal<br />

model will be presented in Section 4.1.2. Here we de ne the model itself, <strong>and</strong><br />

which changes we expect to occur in the model. Just as in the previous chapter,<br />

we then de ne a scenario which covers the di erent changes in the model in<br />

Section 4.1.3.<br />

4.1.1 What is <strong>Layering</strong>?<br />

People have the urge to arrange things. This is also the case <strong>with</strong> software<br />

components, <strong>and</strong> also <strong>with</strong>in software components. We already have seen that<br />

object interfaces can be divided into several sections, called views, to achieve<br />

complexity reduction. We call this vertical object division. In this chapter we<br />

will discuss horizontal object division, called layering. 1 <strong>Layering</strong> emerges from<br />

two activities:<br />

1. Compare Figures 3.1 <strong>and</strong> 4.4.<br />

39


40 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Messages<br />

Object<br />

(a) Object <strong>with</strong>out layer<br />

Messages<br />

Object<br />

Layer<br />

(b) Object <strong>with</strong> layer<br />

Figure 4.1: Object Layers<br />

workHarder<br />

gotoSleep<br />

Person<br />

Employee<br />

Figure 4.2: Role playing modelled <strong>with</strong> a layer<br />

Messages<br />

Object+Layer<br />

(c) Layered Object seen<br />

from the outside world<br />

Extending happens when some object structure exists, <strong>and</strong> we need a (slightly<br />

modi ed) version of it. In that case, we take the existing structure as our<br />

starting point, <strong>and</strong> build our enhancements on top of it.<br />

Dividing happens when no object structure exists, <strong>and</strong> we are creating a new<br />

one. We want this new structure to be underst<strong>and</strong>able, maintainable <strong>and</strong><br />

reusable. Therefore we divide the structure into parts, <strong>and</strong> the individual<br />

objects into layers.<br />

In both ways, we go from the situation in Figure 4.1(a) where we just have an<br />

object, to the situation in Figure 4.1(b) where the object is wrapped in a layer.<br />

Note that the environment is not aware of the presence of the layer, it is<br />

as if one talks to one monolithic object (See Figure 4.1(c)).<br />

A lot of modelling issues can be represented by layers. Role playing for example<br />

can be extremely well modelled <strong>with</strong> a layered architecture. In Figure 4.2, we<br />

see a Person <strong>with</strong> a role Employee attached to it. When the role must be<br />

played (during working hours), the Employee layer will be activated. This can


4.1. Modelling Layers 41<br />

Hardware<br />

Drivers<br />

System functions<br />

Additional functions<br />

System utilities<br />

Figure 4.3: The Unix operating system divided into several layers<br />

be done using views.<br />

Layered architectures are found everywhere in software systems. The<br />

most well-known architecture is the OSI communication layered architecture<br />

described in Black (1991). This architecture divides the communication between<br />

software systems in seven di erent layers, each <strong>with</strong> its own tasks <strong>and</strong><br />

responsibilities. Each layer implements some communication protocol, using the<br />

underlying layer(s) as a communication medium.<br />

<strong>Layering</strong> in software systems is done for several reasons. One of the most important<br />

reasons for applying layering techniques is reduction of complexity. To<br />

achieve this, large software systems are divided into several layers, which can<br />

then be designed, built <strong>and</strong> maintained more or less independently of each other.<br />

Take for example the architecture of a traditional Unix system. In Figure 4.3<br />

we see that a clean division is made between the functionalities. This categorisation<br />

helps us to underst<strong>and</strong> the implementation of the system. Also in<br />

smaller-scale software systems, such as individual programs (or even program<br />

parts!), layering techniques can be used to reduce complexity.<br />

Another reason for using layering techniques, is separation of concerns.<br />

This separation also enables us to better underst<strong>and</strong> things. One often puts basic<br />

functionalities in the core, <strong>and</strong> then wraps around this core one or more layers<br />

<strong>with</strong> special functionalities. This improves the maintainability of the software<br />

system. In the next section we will introduce our model.


42 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Layer 2<br />

Layer 1<br />

Layer 0<br />

Object<br />

(a) Outside world view<br />

4.1.2 Conceptual <strong>Layering</strong> Model<br />

Figure 4.4: Layered Object<br />

Layer 2<br />

Layer 1<br />

Layer 0<br />

(b) Detail view<br />

Object<br />

Until now, we have seen a layered object only from above, like in Figure 4.1(b).<br />

In Figure 4.4(a) we see another way of showing layers inside an object. This<br />

sideview shows a horizontal division of the object. Note that we donot see from<br />

the outside (from the interface) that the object is divided into several layers.<br />

Figure 4.4(b) shows us the internal structure of the object. It appears to consist<br />

of three individual objects that are related to each other. This relation will be<br />

discussed later in this chapter.<br />

We will describe the model of layering from three di erent viewpoints.<br />

Functionality. Functionalities from the requirement speci cation can be<br />

mapped to object implementations in di erent ways;<br />

Level. Layers can represent direct object functionalities, or functionalities<br />

that lay on a higher (meta) level;<br />

Structure. Layers can be attached to objects in a static (compile-time)<br />

or a dynamic (run-time) way.<br />

These are not independent of each other. We will discuss the viewpoints independently<br />

from each other rst. Thereafter their inter-relationship will be<br />

discussed.


4.1. Modelling Layers 43<br />

Func1<br />

Func3<br />

Func4<br />

Func2<br />

Func5<br />

Requirements<br />

Functionality Mapping<br />

T(F1)<br />

T(F3)<br />

T(F2)<br />

T(F4)<br />

T(F5)<br />

MethodA<br />

MethodB<br />

MethodC<br />

MethodD<br />

Object<br />

Figure 4.5: Conceptual Model of <strong>Layering</strong><br />

Object functionalities that are present in the requirements must one way or<br />

the other be represented in the object model. This can be done by mapping<br />

the functionalities to parts of the object model. This divides the layering model<br />

into three di erent parts:<br />

Functionalities<br />

Transformations<br />

Methods<br />

As can be seen in Figure 4.5, these transformations can manifest themselves in<br />

several ways. It is possible that<br />

1. One functionality transforms to one method (T F1 );<br />

2. A functionality transforms to a couple of methods (T F2 );<br />

3. Some functionalities transform to one <strong>and</strong> the same method (T F3 <strong>and</strong> T F4 );<br />

4. A functionality does not transform to a method, but instead has some<br />

e ect on the object as a whole (T F5 ).<br />

Here, TF1 is the simplest transformation. It directly maps a functionality<br />

to an object method. Note that functionalities <strong>and</strong> methods can exist in any<br />

granularity. Therefore, transformation TF2 can occur, where some coarse grained<br />

functionality maps to several ne grained methods. These two cases are the same<br />

for us, so we will use either one.<br />

When two (or more) functionalities map to the same object method, we<br />

have transformations TF3 <strong>and</strong> TF4 . If this is the case, we cannot use functionality<br />

F3 <strong>and</strong> F4 independently from each other. Nonetheless, they are (probably)<br />

independent functionalities. In this situation, often one of the two functionalities<br />

maps directly to the method, as in TF1 , while the other maps indirectly to the<br />

method, thus in fact being a side e ect of the normal functionality.


44 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Object versus Meta Level <strong>Layering</strong><br />

Functionality can be object level or meta level functionality. We de ne functionality<br />

as object level, when all information necessary for the functionality<br />

is present at the object level. Besides this, the functionality must directly be<br />

mapped to a method representing exactly that functionality, instead of being<br />

some side-e ect of another method representing some functionality. All other<br />

functionalities are de ned to be at the meta level.<br />

Object Level <strong>Layering</strong> Object level layering is the most commonly used way of<br />

layering. The existing functionality of objects is modi ed or extended by adding<br />

layers to the objects. Object level layering comes in two avours.<br />

Inheritance Normally, when class libraries are designed, the top level<br />

classes are the most abstract, <strong>and</strong> de ne layers <strong>with</strong> most of the basic functionality.<br />

The leaf classes of a class tree are very speci c, <strong>and</strong> de ne operations that<br />

make use of the basic functionalities of the \root" classes. When a class must be<br />

adapted or extended for a certain reason, a subclass is created which overrides<br />

or extends the default behaviour. In layer terms, an extra layer is added to the<br />

objects which implements the wanted behaviour.<br />

Delegation A less-known version of object level layering is delegation.<br />

With delegation, the classes are not connected by sub-superclass relations. An<br />

object encapsulates an internal object, to which some functionalities are delegated.<br />

With this mechanism it is also possible to hide some or all the functionalities<br />

of the encapsulated object. In this case, delegation resembles a part-of<br />

relationship.<br />

Lieberman (1986) evaluates <strong>and</strong> compares both implementations of object<br />

level layering, <strong>and</strong> concludes that delegation is a richer mechanism. This<br />

conclusion is based on the fact that inheritance can be simulated <strong>with</strong> delegation,<br />

while it is impossible to simulate delegation <strong>with</strong> inheritance.<br />

Meta Level <strong>Layering</strong> With meta level layering, layers are constructed by reifying<br />

elements of object systems. Object systems are constructed <strong>with</strong> objects <strong>and</strong><br />

messages. Theoretically, both elements can be rei ed, which means that information<br />

about the element itself is made available as a rst class object.<br />

Re ection-based layering, as meta level layering can also be called, is<br />

discussed in detail by Ferber (1989). He identi es three re ection mechanisms.<br />

Class-Based Re ection All objects of a certain class have the common<br />

meta-object, which is the class, attached to it. This meta-object implements<br />

the method dispatch function dependent on the desired behaviour. All objects<br />

of some class have the same behaviour then.


4.1. Modelling Layers 45<br />

Object-Based Re ection In object-based re ection, all objects have a<br />

potential meta-object attached to it. This meta-object is not the class of the<br />

object, neither do objects share meta-objects.<br />

Re ection of the Communication Process When the messages that are<br />

sent in the system are all instances of class Message, we have an explicit<br />

re ection of the communication process. When speci c behaviour is desired<br />

then, a subclass of Message can be de ned, which implements this behaviour.<br />

Static versus Dynamic <strong>Layering</strong><br />

Until now, we only discussed layers as being chunks of object speci cations that<br />

can be attached to objects. We did not discuss how they can be attached to<br />

objects.<br />

Static <strong>Layering</strong> With static layering, one or more layers are bound to classes<br />

at compile time. This means that, after the program is build, it is impossible<br />

to change the layering of the objects in the system.<br />

This is a big problem in software engineering. When a system evolves, the<br />

number of functionalities that objects must support grows steadily. Often, large<br />

parts of objects are only necessary for a short period of time, or are only used<br />

by speci c parts of the system. This is especially the case <strong>with</strong> role playing. It<br />

is impossible to foresee all future roles for all individual objects. Also, we get a<br />

lot of classes that only exist because of the combination of roles <strong>and</strong>/or features<br />

of objects. Consider for example a class Person <strong>and</strong> the roles Employee <strong>and</strong><br />

Manager. We must de ne the classes Person, Employee, Manager <strong>and</strong><br />

EmployeeAndManager to support all possible combinations.<br />

Now suppose we also de ne a property called Barking, which de nes<br />

that a barking sound is produced <strong>with</strong> every method invocation. The we must<br />

de ne four new classes: BarkingPerson, BarkingEmployee, Barking-<br />

Manager <strong>and</strong> BarkingEmployeeAndManager. One can see that this gets<br />

worse <strong>with</strong> every new role or property we add.<br />

Figure 4.6 shows the described situation. To create a Person who is at the<br />

same time Employee <strong>and</strong> Manager, <strong>and</strong> who also must bark, we must create<br />

the appropriate class BarkingEmployeeAndManager which incorporates<br />

all wanted properties.<br />

There is another drawback <strong>with</strong> this construction. It is not possible to<br />

switch from one role to the other <strong>with</strong>out losing object identity. Note that,<br />

independent of the current role of a Person, he or she will always remain a<br />

Person (Wieringa <strong>and</strong> Jonge 1991a, Wieringa <strong>and</strong> Jonge 1991b). With our<br />

example, it is not possible to remove the Barking property, or to replace the<br />

Manager property <strong>with</strong> something like Director.


46 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Person<br />

Barking<br />

Employee Manager BarkingPerson<br />

EmployeeAndManager<br />

BarkingEmployeeAndManager<br />

aBarkingEmployeeAndManager<br />

Figure 4.6: Static layering generates complex class structures<br />

Dynamic <strong>Layering</strong> The problems <strong>with</strong> static layering disappear when we use<br />

dynamic layering. In this case, we de ne the layers more or less independent<br />

from each other, <strong>and</strong> attach the appropriate layers to the objects at runtime.<br />

So in our example, we de ne an object class Person, <strong>and</strong> three individual<br />

classes Employee, Manager <strong>and</strong> Barking. Now, when we have a Person<br />

who becomes a Manager, we attach a Manager layer to the Person object. If<br />

we then want this Manager to start barking, we attach aBarking layer to it.<br />

In Figure 4.7, we see the same situation as in Figure 4.6, but now <strong>with</strong><br />

dynamic layering. We can see that the class structure is much simpler now.<br />

Moreover, it is very easy to extend the class structure <strong>with</strong> additional roles <strong>and</strong><br />

properties. This mechanism closely re ects Object Composition.<br />

What Can We Do <strong>with</strong> Dynamic <strong>Layering</strong>? Dynamic layering enables us to<br />

manipulate object behaviour <strong>and</strong> structures at runtime. With this technique,<br />

we can do interesting things.<br />

Dynamic Role Playing We can explicitly distinguish between objects<br />

<strong>and</strong> the roles they must play. When carefully designed, it is very easy to congure<br />

an object <strong>with</strong> certain roles, <strong>and</strong> add others later. It is also possible to<br />

de ne new roles at a later stage, <strong>with</strong>out rede ning other object speci cations.


4.1. Modelling Layers 47<br />

Person EmployeeRole BarkingProperty<br />

ManagerRole<br />

aPerson<br />

anEmployeeRole<br />

aManagerRole<br />

aBarkingProperty<br />

Figure 4.7: Dynamic layering keeps class structures simple<br />

Behaviour Injection We can add new behaviour to, or recon gure existing<br />

behaviour of any object. We can de ne subsystem-speci c behaviour separately<br />

from the original object, clearly distinguishing between the intrinsic<br />

features of an object that is stored in the class itself, <strong>and</strong> the extrinsic features<br />

of an object that is stored in the layers (Minsky <strong>and</strong> Pal 1995).<br />

Protocol Injection <strong>and</strong> Conformance When two or more objects must<br />

communicate, they must conform to some protocol. Normally, when these objects<br />

are not designed that way, their speci cations must be rewritten or extended,<br />

introducing a lot of problems <strong>and</strong> sources for problems. With dynamic<br />

layering, we can let objects \explain" their own protocol to communication c<strong>and</strong>idates<br />

by injecting their own protocol into these c<strong>and</strong>idate objects. This way,<br />

we prevent enormous object speci cations consisting of many protocols. All protocol<br />

speci cations are de ned separately, which makes using <strong>and</strong> maintaining<br />

these protocols much easier.<br />

Separate Behaviour from Control Often, a layer can be divided into behaviour<br />

<strong>and</strong> control of that behaviour. Think for example of a layer that records<br />

history information. Next to the actual recording <strong>and</strong> displaying of history information,<br />

it is possible to provide control functions like starting, stopping <strong>and</strong><br />

clearing of history information. Because we represent layers as rst-class objects<br />

<strong>with</strong> dynamic layering, it is possible to record history information from one object,<br />

while we control history recording from another object, like in Figure 4.8.


48 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Obj1 Obj2<br />

HistoryRecorder HistoryRecorder<br />

Operator<br />

HistoryControls<br />

Figure 4.8: Separate Behaviour from Control: History recording of objects Obj1<br />

<strong>and</strong> Obj2 is controlled by anOperator<br />

Coordinated Behaviour Until now we assumed that the dynamic layer<br />

resided somewhere inside the target object. The layer can reside somewhere outside<br />

the object too however. We have already seen this in Figure 4.8. In (Aksit<br />

et al. 1993), this phenomenon is discussed in more detail, although dynamic<br />

attachment is not addressed.<br />

The paper gives an example of coordinated behaviour using a de ned<br />

ReferencePoint class. <strong>Objects</strong> of this class are constrained by some Figure<br />

object, which ensures that ReferencePoints do not extend the gure's boundaries.<br />

The constraint is hard-coded in the de nition of the ReferencePoint<br />

however, which prevents the class from being reused when other or none of such<br />

constraints apply. In fact the constraint is only valid in the context of a Figure<br />

object. With dynamic layering, we can model this more precisely, resulting in<br />

models that are more exible.<br />

Single Public versus <strong>Multiple</strong> Private Properties Object properties often<br />

apply to the object in general, which means that the property more or less<br />

is visible to all potential client objects. Sometimes however, object properties<br />

purely exist because client objects assign these properties to the server object.<br />

In the real world, this happens all the time.<br />

A good example are sweet names. When person A assigns a sweet name<br />

to person D, the sweet name belongs to person D, but is only visible to person<br />

A. The sweet name is a property private to person A. Maybe some person C<br />

also has assigned a (di erent) sweet name to person D. This can <strong>and</strong> may not<br />

a ect the sweet name of person A. Now (lucky guy) person D has two properties<br />

SweetName. Figure 4.9 shows this situation, where Person A <strong>and</strong> C have private<br />

sweet names for person D, <strong>and</strong> person B has no sweet name at all for person D.<br />

We can use this feature in software models, where objects often have<br />

some properties especially for some subsystem. With dynamic layering, we can


4.1. Modelling Layers 49<br />

Person A<br />

SweetName<br />

Person B<br />

Person D<br />

SweetName<br />

Person C<br />

Figure 4.9: <strong>Multiple</strong> Private Properties assigned to one single object<br />

model this simply, <strong>with</strong>out polluting the software model <strong>with</strong> elements that are<br />

almost never used.<br />

Interrelationship between the Viewpoints of the Model<br />

How do the di erent viewpoints of the model relate to each other? The functionality<br />

view focuses on the semantics of the real world. This results in objectlevel<br />

or meta-level layering, which expresses semantics of the object model. This<br />

model can be implemented in a static or a dynamic way.<br />

In the next section, we will describe a scenario, where functionality changes will<br />

result in object- <strong>and</strong>/or meta level layers.<br />

4.1.3 Scenario of Changes<br />

In this section, we will focus on the impact of the various transformations on<br />

the software model that represent the requirements. This scenario is based on<br />

the functionality mapping viewpoint. We will see that some functionalities are<br />

at the object level, while others transform to meta level layers.<br />

When manipulating functionalities, the following changes are possible,<br />

where the transformations refer to Figure 4.5:<br />

Add methods (T F1 <strong>and</strong> T F2 );<br />

Rede ne methods (also T F1 <strong>and</strong> T F2 );<br />

Extend methods (one of T F3 <strong>and</strong> T F4 );<br />

Add object-orthogonal behaviour (T F1 ).<br />

These operations can occur inside every layer. We can also de ne operations on<br />

layers themselves:<br />

Add Layer;<br />

Remove Layer;<br />

Compose object <strong>with</strong> several layers.<br />

These operations are only meaningful when we use dynamic layering. First, this<br />

section only focuses on static layering. After that, we repeat the scenario in one<br />

step using dynamic layering.


50 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

Add Methods<br />

When we want to add methods to an object using a layer, we are adding functionality<br />

to the object using transformation TF1 of Figure 4.5. It is also possible<br />

that we complete already existing functionality by providing appropriate definitions<br />

of abstract methods, or de ne new abstract functionalities by de ning<br />

\incomplete" methods (For example Pree's (1994) template <strong>and</strong> hook methods).<br />

Rede ne Methods<br />

Often, the addition of a functionality required changes to the de nitions of other<br />

functionalities. This means that the appropriate methods have to be rewritten.<br />

This can be done in two di erent ways:<br />

1. rede nition;<br />

2. extension.<br />

Rede nition of the method means that the original de nition is not being used<br />

anymore. This is often seen as an encapsulation violation, because complete<br />

rede nition requires detailed knowledge of the target object.<br />

When the original de nition is used, we in fact extend the original de -<br />

nition. We will see an example of this in the next section. Note that this form of<br />

method extension is not called this way any further, because we de ne method<br />

extension as described next.<br />

Extend Methods<br />

When we add functionalities, but attach them to already existing methods, we<br />

call this method extension. We refer to transformation TF3 <strong>and</strong> TF4 of Figure 4.5.<br />

One of these functionalities represents the already existing method. The other<br />

one will be added in a new layer. Because this new functionality will be a<br />

side e ect of the method, we discuss this separately from the extended method<br />

rede nition mentioned above.<br />

Add Object-Orthogonal Behaviour<br />

If the functionality that we want to add is not speci c for the target object, we<br />

follow transformation TF5 of Figure 4.5. The functionality will in principle be a<br />

side e ect of all methods of the target object.<br />

Dynamic <strong>Layering</strong><br />

We mentioned three operations on layers at the beginning of this section:<br />

Add Layer;<br />

Remove Layer;<br />

Compose object <strong>with</strong> several layers.<br />

Because removing a layer is in fact the reverse of adding <strong>and</strong> composing layers,<br />

there is nothing special <strong>with</strong> it, besides the possibility of invalidating other<br />

layers that depend on the removed layer. We will not discuss the removal of<br />

layers here.


4.2. C ++ implementation 51<br />

Object<br />

Legend<br />

User Mail MailH<strong>and</strong>ler<br />

HUser HeadingMail<br />

AUser AttachmentMail<br />

MVUser UserSystemViewMail<br />

RNUser ReadNotificationMail<br />

HisUser<br />

Normal class<br />

Normal class (<strong>with</strong> overhead)<br />

Overhead class<br />

HistoryMail<br />

Figure 4.10: <strong>Layering</strong> Scenario<br />

MVMailH<strong>and</strong>ler<br />

Add Methods<br />

Redefine Methods<br />

Prepare for Extend Methods<br />

Extend Methods<br />

Add Object-Orthogonal Behaviour<br />

The best way of showing how layers can be added to a target object,<br />

<strong>and</strong> composed through dynamic layering, is de ning the same layers as in the<br />

previous sections, <strong>and</strong> attach them to the target object at runtime.<br />

4.2 C++ implementation<br />

In this section, we will discuss the C ++ implementation of the scenario discussed<br />

in Section 4.1.3. We will start <strong>with</strong> a Simple Mail System, as described in<br />

Section 3.2.1. The rest of the scenario is depicted in Figure 4.10.<br />

4.2.1 Add Methods: Heading Mail System<br />

In this section, we extend the MailMessage <strong>with</strong> a heading. We will use this<br />

heading for textual representation of information about the MailMessage itself,<br />

apart from the body of course.<br />

Scenario direction


52 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

char<br />

HeadingMail::getMailAsText(void)<br />

f<br />

:::;<br />

c this!getMailContents();<br />

h this!getMailHeading();<br />

:::;<br />

return r;<br />

g<br />

Motivation<br />

Figure 4.11: Never access \lower level" structures directly<br />

MailMessages are presented to the User <strong>with</strong> special mail readers. These readers<br />

normally construct a header containing certain information about the MailMessage<br />

itself, like the MailOriginator <strong>and</strong> the MailReceiver. In this section, we discuss<br />

the implementation of a HeadingMail, which is capable of constructing<br />

such a header.<br />

Semantic Structure<br />

The functionality that this layer provides is, at least in the static implementation,<br />

2 very simple. The transformation of this functionality isoftype T F1 .<br />

We must be prepared to future adaptations however, <strong>and</strong> never manipulate<br />

nor access internal structures of the target object directly. Ifwe do this,<br />

we can never adapt the \behaviour" of the internal structures in another layer<br />

later. We will show that it is important to use a certain coding convention in<br />

order to achieve maximum exibility.<br />

Implementation Consequences<br />

In the implementation, we have to con rm to certain coding principles to avoid<br />

breaking reusability. Johnson <strong>and</strong> Foote (1988) give us several guidelines to<br />

create class structures that are reusable. Later, Lieberherr <strong>and</strong> Holl<strong>and</strong> (1989)<br />

describe the Law of Demeter, which goes further <strong>and</strong> dictates some independence<br />

rules by law.<br />

To decouple the classes Mail <strong>and</strong> HeadingMail as much as possible,<br />

all references to the instance variables is implemented by sending messages to<br />

this, which inC ++ st<strong>and</strong>s for the receiver of the message (See Figure 4.11).<br />

In HeadingMail two methods are de ned, called getMailHeading <strong>and</strong><br />

getMailAsText. getMailHeading returns a textual presententation of the heading<br />

information, while getMailAsText returns a complete textual representation of<br />

the MailMessage, in fact combining the header <strong>with</strong> the contents. Appendix C.1<br />

2. See Section 4.2.5 for a discussion about the dynamic implementation


4.2. C ++ implementation 53<br />

lists the complete C ++ implementation. Note the this reference calls in the<br />

methods as in Figure 4.11.<br />

4.2.2 Rede ne Methods: Attachment Mail System<br />

In this section, we extend the mail system by allowing the User to attach les<br />

to the MailMessage.<br />

Motivation<br />

Sometimes, a textual MailMessage should be accompanied by extra documents,<br />

like enclosures <strong>with</strong> a letter. These are called attachments, <strong>and</strong> in this section<br />

we are going to de ne class AttachmentMail, which is capable of storing <strong>and</strong><br />

sending Attachments accompanied <strong>with</strong> a MailMessage.<br />

Semantic Structure<br />

By adding this functionality, we have to rede ne the heading de nition provided<br />

in HeadingMail. If there is an Attachment present, we must include<br />

information about it in the mail header. Note that the existing header should<br />

not be touched, we only want toadd something to it.<br />

Implementation Consequences<br />

In this scenario step, we add the functionality of attachments to the Mail-<br />

Message. Therefore we de ne a separate Attachment class to hold the actual<br />

attachment. Besides this, the Attachment must be placed into the MailMessage.<br />

We de ne methods setMailAttachment <strong>and</strong> getMailAttachment for this task.<br />

For the rede nition of the mail header, we override the getMailHeading<br />

method. It calls the original getMailHeading, <strong>and</strong> adds a line about the attachment<br />

to it, like in Figure 4.12. Note that if there is no attachment present, the<br />

extra functionality is skipped, as if the method did not exist. We will show a<br />

much neater implementation using dynamic layering in Section 4.2.5. In this dynamic<br />

implementation, the attachment functionality <strong>and</strong> the rede ned header<br />

are de ned in the separate attachment-layer, which can be connected to the<br />

Mail object at runtime, causing no overhead at all when no attachments are<br />

used.<br />

4.2.3 Extend Methods: ReadNoti cation Mail System<br />

In this section we implement a scheme for transparent noti cation of a Mail-<br />

Message read to the MailOriginator.<br />

Motivation<br />

If important or time-critical MailMessages are sent by mail, the MailOriginator<br />

wants to know when the MailReceiver has read the message. This of course has<br />

to be transparent to the MailReceiver.


54 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

char<br />

AttachmentMail::getMailHeading(void)<br />

f<br />

:::;<br />

h HeadingMail::getMailHeading();<br />

if ( attachment NULL) f<br />

== Use original de nition<br />

s h;<br />

g else f<br />

== Extend heading <strong>with</strong> attachment ref<br />

s h+:::;<br />

g<br />

return s;<br />

g<br />

Figure 4.12: Rede ned methods basically extending functionality must call the<br />

original method, <strong>and</strong> often are conditional in their extension<br />

Semantic Structure<br />

This functionality has the important property that it is transparent to the user.<br />

This means that it also must not be re ected in the interface of the object. This<br />

functionality should be implemented in such away that the calling environment<br />

does not have to be adapted to enable read noti cation.<br />

This means that the functionality must be implemented in the getMail-<br />

Contents method, which is the only place where we can detect that a MailMessage<br />

is being read. Now we have situation TF3 =TF4 from Figure 4.5, where we<br />

have two functionalities, namely read mail <strong>and</strong> automatic read noti cation,<br />

combined into one method, namely getMailContents.<br />

In order to make the program adaptable, we must one way or the other<br />

separate the two functionalities in the implementation. Only then will it be<br />

possible to rede ne the two functionalities independently of each other.<br />

Implementation Consequences<br />

In fact, we do not only want the functionality to be invisible in the interface,<br />

we also want ittobeinvisible in the (normal) implementation of the object.<br />

This causes the functionality to result into a meta layer. It \st<strong>and</strong>s<br />

above" the normal execution of the program, more or less extending method<br />

execution semantics for one particular method. This is done by pre xing the<br />

actual method execution by generating a reply containing a read noti cation to<br />

the MailOriginator.<br />

We can only detect the invocation of getMailContents inside the method<br />

itself. We therefore separate invocation <strong>and</strong> execution into two methods get-<br />

MailContents <strong>and</strong> pureGetMailContents, using the same mechanism as we did


4.2. C ++ implementation 55<br />

char<br />

ReadNoti cationMail::getMailContents(Object sender)<br />

f<br />

if (this!senderIsReceiverAndMustNotify(sender))<br />

this!notify();<br />

return UserSystemViewMail::getMailContents(sender);<br />

g<br />

Figure 4.13: Separate Mail Read <strong>and</strong> Send ReadNoti cation functionalities<br />

for implementing multiple views. This way, we separate the two functionalities<br />

into two methods (pureGetMailContents <strong>and</strong> sendReadNoti cation), <strong>and</strong> couple<br />

them in the message invocation method getMailContents (See Figure 4.13 for a<br />

coding extract of Appendix C.3). We can see in Figure 4.10, that we reused the<br />

coding scheme we introduced in Section 3.2.2. Therefore we did not de ne the<br />

pureGetMailContents method, <strong>and</strong> also did not call it from the getMailContents<br />

method from Figure 4.8. If we had done this, we had ignored other method<br />

entry semantics (like the views of UserSystemViewMail.).<br />

4.2.4 Add Object-Orthogonal Behaviour: History Mail System<br />

We now add the recording of historical information about message sends to our<br />

mail system.<br />

Motivation<br />

We want to keep track of what objects sent what methods to which target<br />

objects at what time. Wewant this for debugging our ReadNotificationMail<br />

implementation for example.<br />

Semantic Structure<br />

This scenario step corresponds <strong>with</strong> transformation TF5 of Figure 4.5. We add<br />

functionality that has an e ect on the complete object. Of course we do not<br />

want to record history information in the methods themselves, because adding<br />

or rede ning methods in subclasses would require new explicit history recording<br />

code. Further, history recording is st<strong>and</strong>ing \above" normal method execution,<br />

resulting in a meta layer, just as <strong>with</strong> the ReadNotificationMail class.<br />

We also want meta-information in our history report, namely the name<br />

of the methods that are invoked. If the computational model does not provide<br />

this information, we must work around this problem.<br />

Implementation Consequences<br />

To implement this functionality in a composable way, wehave to use the same<br />

implementation scheme as in the ReadNotificationMail class. There is one


56 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

void<br />

HistoryMail::setMailReceiver(Object sender,MVUser user)<br />

f<br />

this!doMeta("setMailReceiver",sender);<br />

ReadNoti cationMail::setMailReceiver(sender,user);<br />

g<br />

Figure 4.14: Every method has to be rede ned to implement history information<br />

recording<br />

big di erence however. In HistoryMail, we must adapt the behaviour of all<br />

methods, instead of just one. Therefore, we must rede ne all interface methods<br />

of the mail class, <strong>and</strong> add history information recording code to it.<br />

In Figure 4.14 we can see one of all methods that had to be (re-)de ned<br />

to implement HistoryMail. The problem here is essentially the same as the introduction<br />

of Warning2Mail in Section 3.2.6. There we also had to de ne the<br />

same functionality for a set of methods (although the functionality inWarning2Mail<br />

was limited to four methods). If in some subclass a new method is<br />

introduced, the history recording code must explicitly be de ned for the new<br />

method then.<br />

We can see another analogy between Warning2Mail <strong>and</strong> History-<br />

Mail. Both need to know which method is currently active. This information<br />

is not explicitly available, <strong>and</strong> thus we must provide this information ourselves.<br />

4.2.5 Dynamic <strong>Layering</strong>: Dynamic Mail System<br />

We repeat two scenario steps from the previous sections using dynamic layering<br />

now.<br />

Motivation<br />

Until now, we have enhanced the mail system <strong>with</strong> several functionalities. The<br />

problem is, that all these enhancements have to be known <strong>and</strong> speci ed prior<br />

to using the mail system. Therefore, we want to implement a DynamicMail<br />

system, which is capable of including any possible enhancement which we can<br />

think of in the future.<br />

Semantic Structure<br />

The semantic structure of the dynamic mail system is completely di erent from<br />

those we have already seen. The structure must be capable of h<strong>and</strong>ling all<br />

possible transformations from Figure 4.5.<br />

This can be done by de ning a generic layer that can be added to the<br />

target object at runtime. Di erent layers <strong>with</strong> di erent functionalities can be<br />

implemented upon this generic layer, <strong>and</strong> then be tted to the target object<br />

when appropriate.


4.3. Conclusions 57<br />

Implementation Consequences<br />

The GoF book (Gamma et al. 1995) identi es this structure as the Decorator<br />

pattern. By using this pattern it is possible to add behaviour to an object at<br />

run-time. The pattern has several drawbacks however. The book itself mentions<br />

(amongst others) the object-identity problem. The decorated object has not<br />

the same object-identity as the original object. Of course this is an undesired<br />

situation.<br />

A drawback of using this pattern which is not mentioned in the book<br />

is the following. In the implementation of the DynamicMail, we have the<br />

same problem as in HistoryMail, as we have no way of uniformly modify<br />

the behaviour of all methods. This means, that we have to re-implement all<br />

methods again for meta-level layers.<br />

The interface conformance requirement has important drawbacks on the<br />

exibility of the pattern. For example, meta-level layers can only operate on<br />

the small interface de ned by the abstract Component class. Also, layers are<br />

incapable of adding functionalities to the object, when they need to add methods<br />

to the class for it (which would require us to rewrite class speci cations, which<br />

violates the reusability requirement of an object model).<br />

The Decorator pattern requires us to write a lot of overhead code.<br />

Look for example at Figure 4.15. We can see that one simple function takes<br />

three declarations to work. Also, for each meta-level layer, we have to specify<br />

all methods again. Another drawback here is, that the MailHistory is not<br />

reusable as a generic HistoryReporter.<br />

4.3 Conclusions<br />

In this chapter we de ned a model for object layering. We also showed how<br />

several aspects in this model could change, <strong>and</strong> how this could be implemented<br />

in a language like C ++.<br />

It appears that static object-level layering is very straightforward in C ++.<br />

Meta-level layering is much more problematic, mainly because this cannot be<br />

done orthogonally. The problem base is the same as <strong>Multiple</strong> <strong>Views</strong>. In Section<br />

3.3 we also identi ed problems because of the lack of static as well as<br />

dynamic meta information, <strong>and</strong> the absence of a single message entry point in<br />

objects, which prevents us to model orthogonal behaviour like inHistoryMail<br />

in a proper way.<br />

Dynamic layering is also very problematic. The Decorator pattern<br />

can be used sometimes, but this pattern has important drawbacks, like identity<br />

problem <strong>and</strong> interface conformance, which prevents a decorator participant from<br />

being reused.


58 Chapter 4. Modelling Issue: <strong>Layering</strong><br />

class MailComponent f<br />

:::;<br />

virtual void send();<br />

:::;<br />

g<br />

class DynamicMail : public MailComponent f<br />

:::;<br />

virtual void send() f printf("The actual method here..."); g<br />

:::;<br />

g<br />

class MailDecorator : public MailComponent f<br />

MailDecoratorfMailComponent pg fcomponent p; g<br />

:::;<br />

virtual void send() f component!send(); g<br />

:::;<br />

private:<br />

MailComponent component;<br />

g<br />

class MailHistory : public MailDecorator f<br />

:::;<br />

virtual void send() f printf("Do some meta work");<br />

MailDecorator::send(); g<br />

:::;<br />

g<br />

Figure 4.15: C ++ example of one simple function in a Decorator pattern


4.3. Conclusions 59<br />

Smalltalk implementation<br />

We did not give the example code in Smalltalk, but we will give some hints<br />

about it here.<br />

For meta-level layering, the same remarks apply here as we have given<br />

for <strong>Multiple</strong> <strong>Views</strong>. For dynamic layering, we can address the following issues,<br />

based on the Decorator pattern.<br />

Identity problem Smalltalk has a method called become:, which at runtime<br />

shifts an object to another class. With this mechanism, the identity problem<br />

could be eliminated.<br />

Interface conformance In Smalltalk, we can use the doesNotUnderst<strong>and</strong> mechanism<br />

to automatically forward incoming methods to next layers (<strong>and</strong> eventually<br />

to the target object).


60 Chapter 4. Modelling Issue: <strong>Layering</strong>


Chapter 5<br />

Composition Filters Solutions for the Modelling<br />

Issues<br />

In this chapter we will describe the solutions for the examples from Chapters 3<br />

<strong>and</strong> 4 in the Composition Filters Object Model. In Section 1.1, we mentioned<br />

the language Sina that supports this model. In Section 2.1 we already discussed<br />

the model. Because we use Sina in this chapter for implementing the examples,<br />

we will rst brie y introduce some features <strong>and</strong> caveats of the language in<br />

Section 5.1. Then, in Sections 5.2 <strong>and</strong> 5.3 we discuss the Sina implementation<br />

of <strong>Multiple</strong> <strong>Views</strong> <strong>and</strong> <strong>Layering</strong> respectively. The corresponding full-text code<br />

listings are in Appendices B <strong>and</strong> D.<br />

5.1 The Sina Language<br />

This section is based on Koopmans (1996).<br />

In this section, we will brie y discuss the Sina language, <strong>with</strong> respect to the<br />

Composition Filters Object Model. This chapter implements techniques for<br />

<strong>Multiple</strong> <strong>Views</strong> <strong>and</strong> Object <strong>Layering</strong> in the Composition Filters Object Model,<br />

using the Sina language. We will discuss some problems <strong>with</strong> the language in<br />

this section.<br />

Sina is implemented in a multi-threaded environment. This means that a program<br />

can have more than one active object at some point in time. To prevent<br />

problems <strong>with</strong> this, the Sina compiler defaults to st<strong>and</strong>ard single-threaded objects,<br />

which in turn means that <strong>with</strong>in one single object, there will only be<br />

one thread active. When a method is executed in an object, all other incoming<br />

messages are blocked until the executing method has nished. We will see<br />

some problems <strong>with</strong> this feature, because objects can ask information from each<br />

other, resulting in deadlock situations as in Figure 5.1 on page 63, which will<br />

be explained in the next section.<br />

Another problem is that Sina does not implement a meta object model,<br />

like Smalltalk does. There is some rudimentary implementation available, but<br />

61


62 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

this is not very usefull now. This is related to some problems <strong>with</strong> the Composition<br />

Filters Object Model however, because we do not know when to identify<br />

two object as members of the same \class" yet (mainly because objects can<br />

change dramatically during their lifetime, see dynamic layering for example).<br />

5.2 <strong>Multiple</strong> <strong>Views</strong><br />

In this section, we will show the Composition Filters solution of the <strong>Multiple</strong><br />

<strong>Views</strong> problem. We will follow the same scenario we used in Chapter 3, <strong>and</strong><br />

compare the Composition Filters solution <strong>with</strong> the C ++ solution from Chapter 3.<br />

5.2.1 Simple Mail System<br />

In the implementation of the MailH<strong>and</strong>ler class, there is a di erence <strong>with</strong><br />

the C ++ implementation. Although we did not mention it in Chapter 3, the C ++<br />

class MailH<strong>and</strong>ler was constructed according to the Singleton pattern. 1<br />

In short, this pattern is used to enforce that only one instance of some class<br />

exists. Because the Composition Filters Object Model lacks an interface to<br />

instance creation primitives, it is not possible to control these primitives <strong>with</strong>,<br />

for example, views. So, in Sina we cannot implement the Singleton pattern.<br />

There is another problem <strong>with</strong> the MailH<strong>and</strong>ler class. Note the early<br />

return in the body of send. The default behaviour of a method prevents multiple<br />

execution threads in an object. This statement prevents a deadlock in the<br />

MailH<strong>and</strong>ler, because the MailMessage will print the name of the MailH<strong>and</strong>ler<br />

through the getName method, which will be delayed until the send message<br />

has terminated. See Figure 5.1 how the deadlock situation emerges. The Sina<br />

reference manual (Koopmans 1996, Chapter 10) warns for this situation. The<br />

warning dictates not to send any messages to self or server from a condition.<br />

In this Mail System there is a similar situation, where the MailMessage asks<br />

the MailH<strong>and</strong>ler to deliver it to the MailReceiver.<br />

In the User class, we introduce an early return statement in the receive method<br />

too, for the same reason as mentioned above. Because the Singleton pattern<br />

cannot be implemented in Sina, we access the global MailH<strong>and</strong>ler object in the<br />

Mail class through an external variable.<br />

The rest of the implementation is rather trivial. It closely resembles the<br />

implementation of the C ++ solution.<br />

5.2.2 Add <strong>Views</strong>: UserSystemView Mail System<br />

In this section we discuss the implementation of views in Sina. We can see how<br />

easy it is to support view semantics in this language, because the properties that<br />

we need to support views are part of the language model. Note that only the<br />

1. The Singleton pattern is discussed in (Gamma et al. 1995)


5.2. <strong>Multiple</strong> <strong>Views</strong> 63<br />

MailH<strong>and</strong>ler MailReceiver<br />

receive<br />

DEADLOCK<br />

getName<br />

send receive<br />

Figure 5.1: Deadlock ofsend message in the MailH<strong>and</strong>ler<br />

Mail class needs to be updated to support views. The User class is subclassed<br />

only to implement another test method that uses the new UserSystemView-<br />

Mail class.<br />

The UserSystemViewMail class declares the two views userView <strong>and</strong><br />

systemView, <strong>and</strong> couples the views to the methods <strong>with</strong> lter expressions. These<br />

lter expressions accept incoming messages when the condition (view) is true<br />

<strong>and</strong> the method selector matches. When the method selector matches, but the<br />

view is not active, an error is raised (because of the Error lter that is used).<br />

The match between the view model from Section 3.1.2 <strong>and</strong> the Composition<br />

Filters Object Model is as follows. The method set M o is not changed in the<br />

view model. In this section we only add views, so the method set in the Sina<br />

implementation is not changed either. We can see this in the implementation of<br />

UserSystemViewMail, where we inherit from the Mail class, <strong>and</strong> therefore<br />

do not have to rede ne any features from the class Mail. We do have to de ne<br />

the views <strong>and</strong> the method-view mappings here.<br />

View De nitions<br />

Normally, view de nitions are rather trivial. We will see this in the next sections,<br />

where we will de ne some easy-to-implement views. The views userView <strong>and</strong><br />

systemView however are not easy to implement, because we want to restrict<br />

access to objects of the classes User <strong>and</strong> MailH<strong>and</strong>ler <strong>and</strong> their subclasses<br />

respectively. The Sina language does not support a meta-object or classes as<br />

objects. Therefore it is not simply possible to ask a Sina object for its type. It


64 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

View Method OK<br />

View Method p<br />

:View Method<br />

View :Method p<br />

:View :Method p<br />

Table 5.1: Possible mappings between methods <strong>and</strong> views<br />

is even more di cult to determine any type-subtype relations, because of the<br />

dynamic behaviour of Sina class interfaces. In our implementation we used the<br />

isKindOf method, a method which in fact is not available.<br />

Method-View Mapping Semantics<br />

For a better underst<strong>and</strong>ing on how a view is implemented <strong>with</strong> a lter expression,<br />

we will rst elaborate on what lters do <strong>with</strong> messages.<br />

For simplicity, we restrict to the situation where we need the mapping<br />

between one view <strong>and</strong> one method. In Table 5.1, we see the four possible actual<br />

situations for a message. The rst means that the view is active, <strong>and</strong> that the<br />

listed method is called. In Table 5.1 we also see that this is OK, which means<br />

that the method is allowed to be executed. When the method is called, but the<br />

view is not active, we want to raise an error. For the other two situations, we<br />

see that when another method is called, we are not interested in this situation,<br />

so we accept this.<br />

The lter expression that implements this behaviour, thus has to exclude<br />

the \bad" situations from Table 5.1. All other situations have to be accepted.<br />

Because of the semantics of a lter expression, we have to construct a<br />

lter expression that shows what is allowed in a message pattern instead of what<br />

is not allowed. 2 Bergmans (1994) also recognises this problem. So in order to<br />

realise the values from Table 5.1, we list the three OK values from this table.<br />

The remaining situation(s) will not match the lter expression <strong>and</strong> thus will<br />

raise an error in the error lter. See Figure 5.2 for an example listing of a class<br />

<strong>with</strong> one view-method coupling.<br />

5.2.3 View Partitioning: OriginatorReceiverView Mail System<br />

In the OriginatorReceiverViewMail class, we re ne the userView of the<br />

UserSystemView Mail System. Therefore we de ne two new views originatorView<br />

<strong>and</strong> receiverView. Note that both these views have smaller result sets<br />

than the original userView. This is an obliged property, because of the <strong>and</strong>composition<br />

of views on the same method(s) through subclasses. The mappings<br />

2. When a runtime message matches a lter element, the message is allowed to continue.<br />

When it has passed all lter elements, <strong>and</strong> thus is still not accepted, the lter acts according<br />

to its type (the error lter will raise an exception, for example)


5.2. <strong>Multiple</strong> <strong>Views</strong> 65<br />

class UserSystemViewMail interface<br />

:::;<br />

internals<br />

mail : Mail; == Subclass from Mail<br />

conditions<br />

userView;<br />

systemView;<br />

input lters<br />

mv1 : Error = f userView ) setMailOriginator,<br />

true ; setMailOriginator g;<br />

:::;<br />

end;<br />

class UserSystemViewMail implementation<br />

conditions<br />

userView<br />

begin<br />

return message.sender.isKindOf:(User)<br />

end;<br />

:::;<br />

end;<br />

Figure 5.2: Implementation of method-view coupling in Sina


66 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

View<br />

ViewA<br />

ViewA<br />

:ViewA<br />

^<br />

^<br />

^<br />

ViewB<br />

:ViewB<br />

ViewB<br />

Method<br />

Method<br />

Method<br />

Method<br />

^OK<br />

p<br />

_OK<br />

p<br />

p<br />

p<br />

:ViewA<br />

ViewA<br />

ViewA<br />

:ViewA<br />

:ViewA<br />

^<br />

^<br />

^<br />

^<br />

^<br />

:ViewB<br />

ViewB<br />

:ViewB<br />

ViewB<br />

:ViewB<br />

Method<br />

:Method<br />

:Method<br />

:Method<br />

:Method<br />

p<br />

p<br />

p<br />

p<br />

p<br />

p<br />

p<br />

p<br />

Table 5.2: Possible mappings between methods <strong>and</strong> multiple views<br />

from the userView to the methods also have to be rede ned to use the new<br />

views.<br />

Again only the Mail class has to be extended. The VPUser subclass<br />

only de nes a test function that uses the OriginatorReceiverViewMail<br />

class. This class shows how view mappings can be composed.<br />

Composing View Mappings<br />

When we want to place one method under more views, we can do this in two<br />

di erent ways:<br />

And-composition This means that the method can only be accepted if both<br />

views are active.<br />

Or-composition This means that the method must be accepted if at least one<br />

view is active.<br />

Which composition is used in a class declaration is totally dependent on the<br />

situation, <strong>and</strong> the developer has to choose the right one. Both versions can<br />

be expressed <strong>with</strong> lters. The <strong>and</strong>-composition is expressed <strong>with</strong> two di erent<br />

lters, <strong>and</strong> the or-composition is expressed <strong>with</strong> one lter. Table 5.2 depicts the<br />

possible situations, <strong>and</strong> whether the situation is OK or not for AND- as well as<br />

OR-composition. See Figure 5.3 for an implementation of both compositions.<br />

Filter mv1 uses AND-composition, while lter mv4 uses OR-composition.<br />

This mechanism has the property that subclassing of a class <strong>with</strong> views<br />

only permits <strong>and</strong>-composition for more views on the same method. This is a<br />

point of discussion in the TRESE group, but intuitively this is OK, because<br />

otherwise you can break integrity rules of superclasses by bypassing existing<br />

view restrictions.<br />

The implementation of class OriginatorReceiverView shows ANDcomposition<br />

through subclassing. Amongst others, the method setMailReceiver<br />

is restricted by both views userView from the parent class <strong>and</strong> the originatorView<br />

from the owner class. Of course this has no e ect, because<br />

V userView<br />

V originatorView


5.2. <strong>Multiple</strong> <strong>Views</strong> 67<br />

class OriginatorReceiverViewMail interface<br />

:::;<br />

internals<br />

mail : UserSystemViewMail; == Inherit<br />

conditions<br />

originatorView;<br />

receiverView;<br />

input lters<br />

mv1 : Error = f originatorView ) setMailOriginator,<br />

true ; setMailOriginator g;<br />

:::;<br />

mv4 : Error = f originatorView ) getMailContents,<br />

receiverView ) getMailContents,<br />

true ; getMailContents g;<br />

:::;<br />

end<br />

Figure 5.3: Method View Composition<br />

class GroupMail interface<br />

:::;<br />

conditions<br />

originatorView; == Rede ned view<br />

:::;<br />

end<br />

Figure 5.4: View Extension only rede nes the view<br />

But this does depend completely on the de nitions of the views that are involved.<br />

The implementation also shows OR-composition. The method getMail-<br />

Contents can be called by both the mailOriginator <strong>and</strong> the mailReceiver ( lter<br />

mv4 in Figure 5.3).<br />

5.2.4 View Extension: Group Mail System<br />

In the GroupMail class we extend the de nition of the originatorView. We<br />

check if the \real" originator <strong>and</strong> the sender of the message belong to the same<br />

group. Note that only the view de nition has changed, directly re ecting the<br />

change of the speci cation (Figure 5.4).<br />

To be able to test group membership of a User, we extend the de nition<br />

of the User class. A GroupUser has a groupNumber attribute, so we can<br />

check if groupNumbers of two di erent users match.


68 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

class SecureMail interface<br />

:::;<br />

conditions<br />

pgpView;<br />

input lters<br />

dis : Dispatch =f<br />

pgpView->[getMailContents]getPGPMailContents,<br />

pgpView->[setMailContents]setPGPMailContents,<br />

inner. , mail. g;<br />

end<br />

Figure 5.5: Conditionally redirect messages to specialized versions<br />

5.2.5 Dynamic Behaviour Extension: Secure Mail System<br />

For the Secure Mail System, we de ne a new view pgpView on the SecureMail<br />

class. This view is active when the sender of the message supports the PGP protocol.<br />

When the PGP protocol is supported, the new get- <strong>and</strong> setMailContents<br />

methods that support PGP encoding <strong>and</strong> decoding are used. Otherwise the<br />

\normal" methods are used.<br />

Therefore we only have to declare the view pgpView, <strong>and</strong> lter expressions<br />

that modify the get- <strong>and</strong> the setMailContents to their PGP-aware counterparts.<br />

Figure 5.5 shows how the lter expression redirects the incoming messages,<br />

depending on the view.<br />

The User class has to be extended <strong>with</strong> PGP semantics, otherwise the<br />

SecureMail class is not able to determine if the User supports the protocol,<br />

<strong>and</strong> to get en- <strong>and</strong> decoding keys from the User for coding of the mailContents.<br />

5.2.6 Static Meta Behaviour Extension: Warning2 Mail System<br />

In the Warning2Mail class, we introduce nothing else but a counter object<br />

that counts the incoming messages. When a message was sent before, a warning<br />

is issued. Otherwise the message is counted, <strong>and</strong> execution continues normally.<br />

The counting is done in a separate object MCount. Note that this object<br />

does not know the structure of the Warning2Mail class, or even what methods<br />

it should count. The object structure <strong>and</strong> the counting (<strong>and</strong> warning) behaviour<br />

are neatly separated in the classes Warning2Mail <strong>and</strong> MCount. See<br />

Figure 5.6 how the counting property is added to the appropriate methods.<br />

The Warning2User class only implements a new test routine.<br />

5.2.7 View Composition: Protected Mail System<br />

For the protected mail system, we rst introduce the class SecureDocument.<br />

This class de nes a securityLevel, <strong>and</strong> a view which checks whether the sending<br />

user has security clearance. This means that the securityLevel of the sending<br />

user has to match at least the securityLevel of the SecureDocument.


5.3. <strong>Layering</strong> 69<br />

class Warning2Mail interface<br />

internals<br />

mail : SecureMail; == Inherit<br />

messageCounter : MCount; == Counter<br />

input lters<br />

count : Meta = f [setMailContents,setMailOriginator,<br />

setMailReceiver,send]<br />

messageCounter.warning2Message g;<br />

dis : Dispatch =f inner. , mail. g;<br />

end<br />

Figure 5.6: Coupling meta behaviour to an object<br />

class ProtectedMail interface<br />

internals<br />

mail : Warning2Mail; == Inherit<br />

secdoc : SecureDocument; == Inherit<br />

input lters<br />

err : Error = f securityClearance -><br />

fgetMailContents, setMailContentsg,<br />

true ;fgetMailContents, setMailContentsg g;<br />

dis : Dispatch =f inner. , mail. , secdoc. g;<br />

end<br />

Figure 5.7: Composing views is extremely simple using Composition Filters<br />

For this example, we also need to de ne a SecureUser, which implements<br />

the securityLevel attribute. This SecureUser also implements a new<br />

test method.<br />

The SecureMail class, which is the composition of Mail <strong>and</strong> Secure-<br />

Document, is extremely simple. As we can see in Figure 5.7, we only declare<br />

the inheritance of the proper classes, <strong>and</strong> de ne the necessary method-view<br />

mappings for the securityClearance of the Get/Set contents methods.<br />

5.3 <strong>Layering</strong><br />

In this section, we will give the Sina solution for the implementation of di erent<br />

perceptions of layering, as discussed in Chapter 4.<br />

Just as <strong>with</strong> the C ++ solution, the Sina implementation also is based on<br />

the Simple Mail System, so we will start from there.


70 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

5.3.1 Add Methods: Heading Mail System<br />

In the User class, we constructed a header for textual representation of the<br />

MailMessage by h<strong>and</strong>. In the HeadingMail, we provide a function that constructs<br />

the header for us. MailMessages <strong>with</strong> more enhancements then can include<br />

these enhancements in the header automatically.<br />

We de ne the new functionality in the HeadingMail class by de ning<br />

the getMailHeading method. We use this method in the getMailAsText method.<br />

To use the new functionality, we de ne a HUser class, which uses this new<br />

header. This class also de nes a new test function.<br />

Note that all \self" references are denoted as server calls. This is because<br />

Sina is a delegation-based language, where this refers to the implementor of the<br />

current method, instead of the original receiver.<br />

5.3.2 Rede ne Methods: Attachment Mail System<br />

In the AttachmentMail, we will enable the user to attach a document tothe<br />

MailMessage. For this, we de ne (like in the C ++ implementation) a separate<br />

Attachment class, which we will use in the class AttachmentMail.<br />

The AUser class only de nes a new test method.<br />

When an attachment is added to the MailMessage, we want that the<br />

mail header updates accordingly. For this, we only have to rede ne the getMail-<br />

Heading method.<br />

There is one signi cant di erence <strong>with</strong> the C ++ implementation. In C ++,<br />

there was a conditional statement (if. . . then. . . else), to decide whether or<br />

not the attachment information was to be added to the mail header. There are<br />

three issues involved here:<br />

1. The method;<br />

2. The object state<br />

3. How these are related to each other.<br />

These issues correspond to the method getMailHeading, the condition<br />

noAttachment <strong>and</strong> the skipMe lter of Figure 5.8. The lter section exactly<br />

states that normally the inner methods are preferable (as in normal inheritance),<br />

but that this must be skipped as long there is no Attachment present.<br />

Note that these issues are the same as in Section 3.1.2. In that section is<br />

explained why separation of these issues is so important.<br />

5.3.3 Extend Methods: ReadNoti cation Mail System<br />

The functionality that we will add in the ReadNotificationMail class is<br />

orthogonal to the \normal" object behaviour, as we have already stated in<br />

Section 4.2.3. Therefore, we de ne the semantics for the noti cation mechanism<br />

in a separate class Notifier.<br />

The new mail class ReadNotificationMail itself is very simple now.<br />

Because we isolated the noti cation semantics, the new ReadNotification-<br />

Mail class only has to attach these semantics to the Mail class, which is done


5.3. <strong>Layering</strong> 71<br />

class AttachmentMail interface<br />

internals<br />

mail : HeadingMail;<br />

conditions<br />

noAttachment;<br />

methods<br />

:::;<br />

getMailHeading;<br />

input nters<br />

skipMe : Dispatch =f<br />

noAttachment)[getMailHeading]mail.getMailHeading; g<br />

disp : Dispatch =f inner. , mail. g<br />

end<br />

Figure 5.8: Code example of conditional method skipping<br />

class HistoryMail interface<br />

internals<br />

mail : ReadNoti cationMail;<br />

history : HistoryReporter;<br />

input lters<br />

meta : Meta = f [ ]history.saveHistory g;<br />

disp : Dispatch =f history.historyReport, mail. g;<br />

end<br />

Figure 5.9: Orthogonal behaviour is very simple to add to an existing class<br />

in the meta lter. It focuses on when to alarm the noti er, <strong>with</strong> respect to the<br />

Mail object itself. It is up to the Noti er to provide means for enabling <strong>and</strong><br />

disabling noti cation, <strong>and</strong> to prevent double noti cation sends.<br />

5.3.4 Add Object-Orthogonal Behaviour: History Mail System<br />

Like in the ReadNoti cation Mail System, the History Mail System de nes<br />

a class which de nes behaviour orthogonal to that of the normal object. The<br />

HistoryMail class records all incoming messages <strong>and</strong> provides a way to display<br />

these recordings.<br />

While the impact of the implementation of this semantics in C ++ was<br />

very big (all existing methods had to be rede ned), the Sina implementation<br />

is simple <strong>and</strong> straightforward. It resembles the ReadNotificationMail implementation,<br />

because they both implement orthogonal behaviour. The class<br />

interface is shown in Figure 5.9.


72 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

incoming message<br />

4<br />

1<br />

new meta...<br />

new object...<br />

2<br />

dynamicLayer<br />

basicObject<br />

5<br />

metaLayer<br />

6<br />

objectLayer<br />

Figure 5.10: Structure of an object <strong>with</strong> dynamic layering property<br />

5.3.5 Dynamic <strong>Layering</strong>: Dynamic Mail System<br />

All functionalities have been implemented statically so far, which means that<br />

their functionalities are always present, whether they are used or not. We have<br />

seen that implementing dynamic layering in C ++ is rather di cult, introducing<br />

more problems than bene ts. In this section we show how dynamic layering can<br />

be implemented using the Composition Filters approach.<br />

The idea is as follows: we start <strong>with</strong> a default object implementation, <strong>and</strong> adapt<br />

it to enable dynamic layering on the object. This way, we will be able to get the<br />

run-time situation of Figure 4.7. We do this by de ning the structure depicted<br />

in Figure 5.10. In this gure, all incoming messages will be routed through all<br />

present meta-level layers, <strong>and</strong> after that through all object-level layers. After<br />

that, the message will be directed to the object itself as usual. New layers will be<br />

tted in front of the appropriate layer-chain. This way, newly added layers can<br />

use <strong>and</strong>/or override present functionality, like in normal inheritance situations.<br />

The basics are de ned in class BasicDL, which implements the dynamic<br />

layering principles for both the layered object as well as the layers. 3<br />

In Figure 5.11, we can see that the HistoryProperty combines the<br />

dynamic layering feature from BasicDL <strong>and</strong> the history recording from our<br />

earlier de ned HistoryReporter just by declaring them as appropriate.<br />

5.4 Conclusions<br />

Apart from some minor problems, we can conclude that views as well as object<br />

layers can very easily be expressed <strong>with</strong> Composition Filters. We have seen<br />

that we did not have to make adaptions to the Mail class when we introduced<br />

3. See Appendix D.5, where both HistoryProperty <strong>and</strong> DynamicMail \inherit" from<br />

basicDL<br />

3


5.4. Conclusions 73<br />

class HistoryProperty interface<br />

internals<br />

basics : BasicDL;<br />

oldReporter : HistoryReporter;<br />

methods<br />

process(aMessage : SinaMessage) returns nil;<br />

input lters<br />

disp : Dispatch =f<br />

inner. ,<br />

oldReporter.historyReport,<br />

basics. g;<br />

end<br />

Figure 5.11: Composing functionalities goes rather well using Composition Filters<br />

views. We only de ned the needed views, <strong>and</strong> coupled them to the appropriate<br />

methods <strong>with</strong> lter expressions. Also the changes we made to the Mail classes<br />

following the scenario tted directly into our model.<br />

We are not the rst who address views in object oriented software models. Some<br />

other people also have tried to make models that explicitly modelled the views.<br />

Surrogates<br />

Minsky <strong>and</strong> Pal (1995) address a technique called \surrogates" for implementing<br />

di erent views over objects. For every view, a special surrogate object is created,<br />

which enables or disables speci c features of the original object by the use of<br />

so-called surrogate rules. With this mechanism it is possible to de ne simple<br />

access control over classes or even individual objects, but our model goes much<br />

further.<br />

Surrogates cannot provide access dependent on the actual state of the object,<br />

the message or its context. Therefore the classes GroupMail, SecureMail,<br />

Warning2Mail <strong>and</strong> ProtectedMail cannot be realised<br />

<strong>with</strong> surrogates.<br />

It is not possible to de ne views that are composed from other views,<br />

or provide access based on more views than just one. If we had sent a<br />

MailMessage from some User to herself, this User would be the Mail-<br />

Originator as well as the MailReceiver. This cannot be expressed neatly<br />

<strong>with</strong> surrogates, because this person then has to have two references to<br />

the same MailMessage.<br />

Clients of surrogates are aware of the existence of the views, <strong>and</strong> must<br />

reference them by name. As a result, the OriginatorReceiverView<br />

example is possible, but it would have triggered a rewrite of the rest of<br />

the code at all places to reference the correct Mail surrogate.


74 Chapter 5. Composition Filters Solutions for the Modelling Issues<br />

Layers normally are referred to as layers from the OSI reference model (Black<br />

1991), where one layer is implemented in terms of another layer.<br />

We have shown layers in another perspective, <strong>and</strong> also have shown that<br />

implementing these in a traditional language is not that simple. Implementing<br />

layers in a language like Sina is straightforward however. Even dynamic layering<br />

is possible, opening a new world of modelling possibilities for us.


Chapter 6<br />

<strong>Composable</strong> Models Presented as Design Patterns<br />

Chapter 5 presents adequate solutions for implementing <strong>Multiple</strong> <strong>Views</strong> on,<br />

<strong>and</strong> <strong>Layering</strong> of objects. However, the solutions are not presented in a way<br />

suitable for knowledge distribution. In this chapter, we will provide the models<br />

for <strong>Multiple</strong> <strong>Views</strong> <strong>and</strong> Dynamic <strong>Layering</strong> in a more accessible format, using<br />

Design Pattern presentation style.<br />

In Section 2.2, we introduced Design Patterns as a knowledge presentation<br />

<strong>and</strong> distribution medium. Section 6.1 will evaluate pattern denotations<br />

in more detail, <strong>and</strong> presents an adapted denotation for Design Patterns, which<br />

is capable of presenting composable models for design problems. Sections 6.2<br />

<strong>and</strong> 6.3 then present the modelling issues as design patterns.<br />

6.1 Enabling Design Patterns to Present <strong>Composable</strong> Models<br />

The notations in which patterns appear nowadays are not adequate for the<br />

problems we have solved. The reason for this is the rich semantics of Composition<br />

Filters, which is not present in \st<strong>and</strong>ard" models, <strong>and</strong> thus is not covered<br />

by the well-known pattern denotations.<br />

The Composition Filters Object Model is capable of adapting message<br />

passing semantics in a very exible way. It is possible to \inspect" several<br />

attributes of a message at runtime because these attributes, like the sender of<br />

the message, are made explicit in the model. It is also possible to change these<br />

message attributes, or let the object react in a speci c way to the message by<br />

choosing the appropriate lter type. It is even possible to reify the message as<br />

a rst class object, <strong>and</strong> pass it to another object for further processing, in fact<br />

enabling us to implement new lter types on the y.<br />

When we want to express Composition Filters Object Model solutions in<br />

a pattern format, we must be able to express all these semantics in a suitable<br />

way. It is possible to give Sina code listings for solutions. This would not be<br />

adequate however, because we then bind the solution to a speci c language. A<br />

Design Pattern should present a solution that is more or less language independent.<br />

75


76 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

The patterns de ned by Gamma et al. (1995) are clearly focusing on<br />

the traditional object model as discussed in 2.1.1. Instead, we want topresent<br />

modelling problems using the Composition Filters Object Model. The graphical<br />

models identi ed <strong>and</strong> used by Gamma et al. (1995) are not rich enough for this.<br />

They use the following three graphical notations:<br />

1. Class Diagrams. These are used to model class structures, which depict<br />

static structural relations.<br />

2. Object Diagrams. These are used to model object structures, which depict<br />

dynamic structural relations.<br />

3. Interaction Diagrams. These are used to model object interactions <strong>and</strong><br />

the order in which they occur.<br />

We will now add a graphical notation to the vocabularies of a Design Pattern,<br />

called a Message Diagram.<br />

Message Diagrams<br />

The model that we provide is focusing almost completely on the messages that<br />

are sent between objects. It is however not important in what order messages<br />

are sent, like in interaction diagrams. It is important what happens when a<br />

message is sent to an object. The focus lies on one (or a group) of messages as<br />

one entity, <strong>and</strong> not on the relation between these messages, like their execution<br />

order.<br />

We will introduce a model that we need for expressing our solutions.<br />

The diagram we need is called a Message Diagram. Its elements match, not<br />

surprisingly, the Composition Filters Object Model elements.<br />

Initial graphical notation<br />

In Figure 6.1, we see both a normal <strong>and</strong> a ltered message being sent from the<br />

sending object to the receiving object. The normal message is supposed to look<br />

familiar. With the ltered message, we see that the message's lifetime is divided<br />

by (one or more) lter(s) into a pre- ltered, a being- ltered <strong>and</strong> a post- ltered<br />

part. With an input lter, this lter is an integral part of the receiving object.<br />

In this case, the nal target of the message is the part of the receiving object<br />

that comes after the lter, <strong>and</strong> is called the server of the message in Sina.<br />

Elements of a Filter Speci cation<br />

We can identify three di erent elements of a lter speci cation: a condition,<br />

a matching <strong>and</strong> a substitution part. The condition is optional, <strong>and</strong> defaults to<br />

True. The substitution part is also optional, <strong>and</strong> defaults to the matching part,<br />

which isnot optional.<br />

A message is said to be accepted by a lter, if the condition evaluates to<br />

True, <strong>and</strong> if the message selector equals the matching part of the lter speci -<br />

cation. If a substitution part is speci ed, the message selector <strong>and</strong>/or it's target<br />

are replaced <strong>with</strong> the speci ed values.


6.1. Enabling Design Patterns to Present <strong>Composable</strong> Models 77<br />

anObject<br />

aMessage<br />

(a) Normal message<br />

aTarget<br />

filter<br />

anObject<br />

prefiltered postfiltered<br />

aTarget<br />

aMessage<br />

(b) Filtered message<br />

Figure 6.1: Graphical message notations from the message's viewpoint. A message<br />

is either not ltered at all, or passes one or more lters which inspect<br />

<strong>and</strong>/or manipulate its runtime behaviour.<br />

We can express this by labelling the pre- ltered message <strong>with</strong> the matching<br />

part (which can be a wildcard), <strong>and</strong> the post- ltered message <strong>with</strong> the<br />

condition <strong>and</strong>, if present, the substitution part.<br />

If the message is not accepted by the lter, it is said to be rejected. It<br />

depends on the lter type what will happen in that case. It depends on the<br />

situation whether it is illustrative to explicitly denote this case or not.<br />

Semantics of a Filter<br />

So far, the lter only accepts or rejects messages. The lter type dictates what<br />

happens when a message is accepted or rejected by this lter. Until now, six<br />

lter types have been de ned:<br />

1. Error lter. An error is raised when no matching succeeds.<br />

2. Wait lter. Execution will be deferred until the message falls through the<br />

lter.<br />

3. Meta lter. Execution will proceed at a meta-level after the message has<br />

been rei ed into a rst-class object. There the message can be inspected<br />

<strong>and</strong> even manipulated. After meta-processing, the message will continue<br />

executing back at the object-level.<br />

4. Dispatch lter. Execution is either dispatched to the implementation<br />

which is present in the inner object, or to the rst lter of the object to<br />

which the message is delegated.<br />

5. Send lter. Execution is transferred to the object to which the message<br />

is sent (to its set of input lters).<br />

6. Realtime lter. Execution is assigned realtime constraints such as maximum<br />

execution time.


78 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

Wait Error Meta Dispatch Send RealTime<br />

Figure 6.2: Filter Types<br />

We visualise these types by using speci c drawings for the di erent lter<br />

types, as depicted in Figure 6.2. Note that both the Dispatch <strong>and</strong> the Send lter<br />

are very simple. They are the placeholders for the dispatch <strong>and</strong> send mechanisms<br />

of the traditional object model (<strong>with</strong> the additional features of the Composition<br />

Filters Object Model of course). Often it is not necessary to depict these lters<br />

explicitly, sowe omit them in our Message Diagrams to keep them as simple as<br />

possible.<br />

Message States<br />

When a message is sent from aClient to aServer, it passes several stages. We<br />

already mentioned that a lter in most cases is some kind of wrapper around the<br />

original (core) object. The message then can be between two di erent objects,<br />

or between the core object <strong>and</strong> the lters (i.e. it has passed the lters). To<br />

make this di erence visible, we denote the message <strong>with</strong> a normal line when<br />

it resides between the objects, <strong>and</strong> <strong>with</strong> a thicker line when it is between the<br />

lters <strong>and</strong> the receiving object. When the diagram depicts an output lter, the<br />

line between the sending object <strong>and</strong> the lter will be the thicker line, because in<br />

such a diagram, the sending object is the core object the diagram is all about.<br />

Normal, unimportant <strong>and</strong> Core <strong>Objects</strong><br />

<strong>Objects</strong> or classes of objects can play di erent roles in a message diagram. To<br />

make this clear, we use di erent displaycharacteristics for di erent object roles.<br />

We identify three kinds of object roles:<br />

Unimportant object An object is called unimportant, if it is present in the<br />

object interaction, but is irrelevant to the communication characteristics.<br />

It is used mostly to identify the context of a communication channel. We<br />

will display an unimportant object grayed. Gamma et al. (1995) uses the<br />

same denotation.<br />

Normal object A normal object is an environmental object which plays a key<br />

role in the communication characteristics. We display normal objects in<br />

black.<br />

Core object The core object is the target of the message. It is displayed in<br />

thick black.<br />

Filter interdependencies<br />

Usually, an object has more than one lter element de ned, in one or more<br />

lters. When the evaluation order of lter elements is important, we must show


6.1. Enabling Design Patterns to Present <strong>Composable</strong> Models 79<br />

this in our message diagrams. When more than one communication line comes<br />

out of a lter, they must be read top-down. The implementation of the dynamic<br />

mail system from Chapter 4 gives a nice example of this situation. Figure 6.10<br />

on page 87 shows (a part of) the message diagram.


80 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

aMailH<strong>and</strong>ler<br />

getContents getMailReceiver<br />

aUser<br />

getContents<br />

sendMail<br />

getMailReceiver<br />

aMail<br />

Figure 6.3: An example mail system<br />

6.2 Design Pattern: <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong><br />

Intent<br />

The pattern makes it possible to explicitly model dynamic interface <strong>and</strong> behaviour<br />

change, dependent onthe runtime message context, like the sender of<br />

a message.<br />

Also Known As<br />

<strong>Multiple</strong> Interfaces<br />

When we want to model di erent behaviour or interfaces dependent on the state<br />

of the object itself instead of the sender of a message.<br />

State<br />

The State pattern provides an alternative solution for more or less the same<br />

problem. Further discussion in the Related Patterns section.<br />

Motivation<br />

Consider a mailing system. This system has the participants Mail, User <strong>and</strong><br />

MailH<strong>and</strong>ler (see Figure 6.3). When we look at the interface of Mail, we<br />

see two parts there. These are<br />

User part This part provides the interface to the User objects. Typical examples<br />

are getContents <strong>and</strong> sendMail.<br />

System part This part provides the interface to the MailH<strong>and</strong>ler.Atypical<br />

example is getMailReceiver.<br />

These two parts provide di erent functionalities of the Mail object, which are<br />

more or less independent of each other.<br />

In the implementation of this system, we want to prevent that the Mail objects<br />

receive inappropriate messages from other objects. We want to prevent for<br />

example that Mail receives the getContents method from the MailH<strong>and</strong>ler,<br />

because it violates the rules of the system as a whole. This is seen in Figure 6.3,


6.2. Design Pattern: <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong> 81<br />

aClient<br />

*<br />

anotherMessage<br />

aView -> aMessage<br />

aServer<br />

Figure 6.4: The structure of the <strong>Multiple</strong> <strong>Views</strong> pattern<br />

where the message getContents is blocked when it is sent by the MailH<strong>and</strong>ler,<br />

while it is passed through when it is sent byaUser.<br />

Further, we want to explicitly divide the interface in multiple sections,<br />

more or less explaining the di erent roles Mail can play in di erent activities.<br />

This way the implementation of Mail will be better understood.<br />

In intuitive implementations of the above requirements, the accessibility code<br />

will be mixed <strong>with</strong> the application code. For example, in the implementation of<br />

getContents, we will check whether the sender of the message is a User object.<br />

The disadvantage is twofold:<br />

1. Adapting access restrictions in subclasses will result in rewriting all restricting<br />

application methods.<br />

2. Adapting application semantics will force you to rewrite all access restriction<br />

code.<br />

The above problem arises from the fact that access control <strong>and</strong> application<br />

semantics are orthogonal properties, which are combined as application<br />

semantics in the implementation. Our solution will prevent this undesired situation.<br />

Applicability<br />

Apply <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong> when:<br />

The interface of a class is complex <strong>and</strong> consists of several `sub-interfaces',<br />

each for a di erent system functionality.<br />

Object misuse must be prevented, <strong>and</strong> several parts of the interface<br />

should be protected from some clients (message callers).<br />

Application semantics or object access control must be adapted through<br />

subclassing.<br />

Implementation of methods must be adapted dynamically (depending on<br />

message sender or internal object state).<br />

Structure<br />

The structure of the pattern is as depicted in Figure 6.4. Here we showaClient<br />

object, which sends aMessage to the Server, which is accepted under condition<br />

aView. This picture also shows the message anotherMessage, which is blocked<br />

by the server.


82 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

Participants<br />

Server<br />

The Server is responsible for implementing aView, aMessage <strong>and</strong> the dependency<br />

between these two.<br />

Collaborations<br />

The Server receives aMessage, inspects whether aView is active, <strong>and</strong><br />

then processes or rejects the message.<br />

Consequences<br />

Using this pattern has the following bene ts:<br />

Separation of concerns The model consists of two di erent elements (application<br />

<strong>and</strong> view). We separate these concerns explicitly.<br />

Polymorphic The solution is polymorphic; i.e. it is possible to implement only<br />

di erent application or view semantics in subclasses.<br />

Using this pattern has the following drawback:<br />

Encapsulation The Composition Filters Object Model de nes lters always<br />

at the interface level. In this example this is all-right, because we want to<br />

inform the user (client) about the views <strong>and</strong> their restrictions. When we<br />

want to adapt behaviour under certain circumstances (see the Gamma<br />

State pattern), we do not want to show this at the interface of the<br />

object. This is not possible <strong>with</strong> the Composition Filters Object Model.<br />

Implementation<br />

The Server class has three concepts: the method, the view <strong>and</strong> the connection<br />

between these two elements. This results in the solution template in Figure 6.5<br />

for the <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong> pattern.<br />

This template shows a view aView. This aView restricts access to aMessage,<br />

while access to method yetAnotherMessage is not restricted. Here can also<br />

be seen that addition of more views is possible, by de ning an additional view<br />

in a subclass, <strong>and</strong> connecting it to methods using an additional lter expression.<br />

Sample Code<br />

The solution we propose uses the concepts that are built-in in the Composition<br />

Filters Object Model. The view userView is represented by a condition. The<br />

connection between the view <strong>and</strong> the application semantics is represented by a<br />

message lter. This results in the class de nition shown in Figure 6.6. An extract<br />

from the implementation, in order to show how the userView is implemented<br />

using Composition Filters Object Model primitives, is shown in Figure 6.7.<br />

Known Uses<br />

None.


6.2. Design Pattern: <strong>Composable</strong> <strong>Multiple</strong> Object <strong>Views</strong> 83<br />

class Server interface<br />

conditions<br />

aView;<br />

methods<br />

aMessage;<br />

yetAnotherMessage;<br />

inputFilters<br />

mv: Error = faView ) aMessage, true ; aMessageg;<br />

dis: Dispatch =finner. g;<br />

end<br />

Figure 6.5: Code template for the <strong>Multiple</strong> <strong>Views</strong> Pattern<br />

class Mail interface<br />

comment<br />

This class implements the <strong>Multiple</strong> <strong>Views</strong> design pattern<br />

internals<br />

contents: Text; == Contains the mail message<br />

conditions<br />

userView; == Implements the view<br />

methods<br />

== Implements the application functionality<br />

getContents returns Text;<br />

inputFilters<br />

== Connect the view <strong>with</strong> the application semantics<br />

mv: Error = fuserView ) getContents, true ; getContentsg;<br />

dis: Dispatch =finner. g;<br />

end<br />

Figure 6.6: Interface de nition of the Mail class


84 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

class Mail implementation<br />

:::<br />

conditions<br />

userView<br />

begin<br />

return sender.isKindOf(User)<br />

end<br />

:::<br />

end<br />

Related Patterns<br />

Figure 6.7: Implementation extract of the Mail class<br />

State Partitioning This problem is also known as the View Partitioning<br />

Problem. It's basis lies in the fact that it is normally not possible to<br />

divide a view in two distinct subviews, <strong>with</strong>out breaking the inheritance<br />

principle <strong>and</strong> rewriting parts of the class speci cation.<br />

State The Gamma catalogue provides the State pattern for implementing dynamically<br />

changeable behaviour. This pattern has a big disadvantage:<br />

the pattern is not extensible, <strong>and</strong> thus implementations of the pattern<br />

are not reusable.<br />

This statement is based on the fact that the State hierarchy <strong>and</strong> the<br />

Context are not orthogonal (same problem as stated before). This<br />

means that extending the Context is not possible <strong>with</strong>out rewriting at<br />

least a part of the State hierarchy. Furthermore, when a subset of the<br />

Context implementation is valid for more that one particular State,<br />

this results in replication of implementation code. This, of course, is undesirable,<br />

<strong>and</strong> undoes a part of the positive e ects of using the State<br />

pattern.


6.3. Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong> 85<br />

getContents<br />

aMailH<strong>and</strong>ler<br />

getMailReceiver<br />

aUser<br />

getContents<br />

sendMail<br />

aHistory-<br />

Recorder<br />

recordHistory<br />

aMail<br />

Figure 6.8: An example mail system <strong>with</strong> history recording<br />

6.3 Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong><br />

Intent<br />

Attach additional behaviour to an object dynamically. <strong>Composable</strong> Dynamic<br />

Object Layers pattern is used to compose an object's behaviour <strong>with</strong> highly<br />

reusable components, <strong>with</strong>out losing the features of object oriented modelling.<br />

Also Known As<br />

None.<br />

Motivation<br />

In sophisticated software frameworks, some important objects incorporate many<br />

di erent features. These features however are almost never used together. Normally,<br />

only some of these features are used in speci c situations. The di erent<br />

features then can be turned on or o using some calls (like enableFeatureThisOrThat).<br />

The implementation of these objects often becomes heavy loaded <strong>with</strong><br />

administrative code for enabling <strong>and</strong> disabling of features, <strong>and</strong> checking if features<br />

are enabled. Also, the di erent code sections of di erent features are often<br />

mixed together. This leads to complex, badly readable <strong>and</strong> non reusable code.<br />

It is also not possible to tailor the di erent features <strong>with</strong>out rewriting other<br />

code parts.<br />

Consider a Mail System, like in Figure 6.8. It resembles the mail system of<br />

Figure 6.3, <strong>with</strong> the di erence that all incoming messages are recorded in a<br />

HistoryRecorder. Often this functionality is not required, so it should be possible<br />

to enable <strong>and</strong> disable the history recording service. The disadvantage of this<br />

static structure is twofold:<br />

1. All Mail objects not requiring the history recording service are loaded<br />

<strong>with</strong> its (disabled) code, which results in unnecessary resource occupation.<br />

2. It is not possible to tailor the history recorder, because it is encapsulated<br />

in the Mail class.


86 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

getContents<br />

aMailH<strong>and</strong>ler<br />

getMailReceiver<br />

aUser<br />

getContents<br />

sendMail<br />

process<br />

aMessage-<br />

Decoder<br />

aHistory-<br />

Recorder<br />

aMail<br />

process<br />

Figure 6.9: Mail system <strong>with</strong> a history recorder <strong>and</strong> a message decoder<br />

3. When other services are designed, the Mail class has to be extended<br />

to use this service. When lots of these services are involved, this implies<br />

heavy impact on the implementation of the Mail class, while the intrinsic<br />

implementation of the class does not change at all.<br />

Using the <strong>Composable</strong> Dynamic Object Layers pattern, we get a more<br />

exible implementation. See for example Figure 6.9, where besides the HistoryRecorder<br />

also a MessageDecoder is active. Both services are activated transparently,<br />

when a message is sent totheMail object.<br />

Applicability<br />

Apply the <strong>Composable</strong> Dynamic Object Layers when:<br />

Class de nitions consist of many di erent services, which almost never<br />

are used all at the same time.<br />

It must be possible to dynamically add services to an object.<br />

It can not be foreseen which services are necessary in an object. This is<br />

only the case <strong>with</strong> so-called orthogonal services (like the HistoryReporter<br />

mentioned before).<br />

Many of the de ned services can be combined. When inheritance is used<br />

in this situation, many class de nitions are the result, because all di erent<br />

combinations must be de ned explicitly.<br />

Structure<br />

We divide the structure of the <strong>Composable</strong> Dynamic Object Layers pattern<br />

in two parts. The rst part is the Basic Dynamic Layer, which is depicted in<br />

Figure 6.10. The second part is the usage of this Basic Dynamic layer in an<br />

object that needs dynamic layering. It is shown in Figure 6.11<br />

Participants<br />

BasicDL The Basic Dynamic Layer implements the protocols for the layered<br />

object <strong>and</strong> both the object-level <strong>and</strong> the meta-level layers.


6.3. Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong> 87<br />

×<br />

addOL<br />

aClient aBasicDL<br />

addML<br />

(cascaded)<br />

(meta)<br />

process<br />

object_layer<br />

meta_layer<br />

Figure 6.10: Message Diagram of the Basic Dynamic Layer<br />

anObject<br />

*<br />

process<br />

*<br />

*<br />

aBasicDL<br />

aDLObject<br />

Figure 6.11: Message Diagram of the <strong>Composable</strong> Object Layer Pattern


88 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

ObjectLayer De nes the BasicDL protocol by inheriting from it, <strong>and</strong> additional<br />

functionality that must be added to the DLObject object at the<br />

object level.<br />

MetaLayer De nes the BasicDL protocol by inheriting from it, <strong>and</strong> additional<br />

functionality that must be added to the DLObject object at the<br />

meta level.<br />

DLObject De nes the BasicDL protocol by inheriting from it, <strong>and</strong> the normal<br />

functionality that the object must provide.<br />

Collaborations<br />

The BasicDL de nes a protocol for adding new layers to the DLObject<br />

to which it is attached. The newly added layers are chained in such a<br />

way, that newly added layers are processed rst. In this way, newly added<br />

layers can use functionality present in an earlier added layer.<br />

The BasicDL object also delegates all unknown methods to its internal<br />

object-level <strong>and</strong> meta-level layer chains.<br />

The ObjectLevel processes requests which it implements, <strong>and</strong> delegates<br />

all other requests to its BasicDL ancestor.<br />

The MetaLevel implements the process method, <strong>and</strong> forwards the call<br />

to its BasicDL ancestor afterwards. It can also implement object-level<br />

functionality in appropriate methods. All unknown messages should be<br />

delegated to its BasicDL ancestor.<br />

The DLObject object sends all incoming messages to the meta-level process<br />

method. After that, appropriate messages should be delegated to the<br />

BasicDL ancestor. Finally, messages should be dispatched to the inner<br />

object.<br />

Consequences<br />

The <strong>Composable</strong> Dynamic Object Layers pattern has several bene ts:<br />

Flexible property composition All possible combinations of properties can<br />

be constructed at run-time. This avoids class trees which de ne a class for<br />

each possible combination of features. Note that when class de nitions<br />

are used, it is not possible to add features to an object during its lifetime<br />

<strong>with</strong>out losing its object identity.<br />

Avoids feature-loaded classes high up in the hierarchy Because the layers<br />

are attached at run-time, the classes do not have to de ne all features<br />

in advance, resulting in large objects from which only parts will be used.<br />

Layers can be reused It is very simple to reuse layer speci cations in other<br />

classes (especially when they are de ned at the meta-level. The HistoryRecorder<br />

we mentioned before can be plugged into any DLObject<br />

class <strong>with</strong>out modi cations. This way, it is also possible to design a hierarchy<br />

oflayers, separate from the layered objects which will use them.<br />

It will make a design very exible <strong>and</strong> extendible.


6.3. Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong> 89<br />

Implementation<br />

The implementation of the <strong>Composable</strong> Dynamic Object Layers pattern involves<br />

several issues. These include:<br />

The pattern can only be implemented using a language that implements<br />

the Composition Filters Object Model. We have tried to implement it<br />

in a traditional language (C ++, see Appendix C.5), which turned out to<br />

produce more problems than solve them.<br />

The pattern introduces overhead by introducing the BasicDL class.<br />

Don't overuse this pattern, because the implementation overhead we try<br />

to solve <strong>with</strong> this pattern can be less than the overhead the pattern<br />

introduces.<br />

When de ning dynamic layered objects, consider building them on top<br />

of \normal" objects (like the DynamicMail in Appendix D.5). Consider<br />

this also for orthogonal layers (like the HistoryReporter in Appendix<br />

D.5). This way, it is always possible to use the non-dynamic<br />

version when appropriate.<br />

Sample Code<br />

We show the implementation of a dynamic mail object, using a dynamic layer<br />

for history reporting. We assume there is a class Mail which implements normal<br />

mail functionality. Further, there is the BasicDL class which implements<br />

the default dynamic layering protocol. Finally, we assume there is a history<br />

reporting class called HistoryReporter.<br />

First, we show how the HistoryReporter class is made dynamic. The dynamic<br />

version is called HistoryProperty. The code is in Figure 6.12. The<br />

HistoryProperty forwards the process method to the appropriate method in<br />

the HistoryReporter.<br />

The code in Figure 6.13 shows how to make the normal class Mail<br />

dynamic by \inheriting" from BasicDL. Note the di erence <strong>with</strong> Figure 6.12;<br />

the order of the lter elements is di erent. The incoming message is diverted to<br />

the process method rst, for meta-level layering. Then the message is delegated<br />

to the object-level layers, if appropriate. Otherwise, the message is dispatched<br />

to the inner object as usual.<br />

Figure 6.14 shows how to use a dynamic layered object.<br />

Known Uses<br />

None.<br />

Related Patterns<br />

Decorator<br />

The Decorator pattern is the Conventional Object Model counterpart of <strong>Composable</strong><br />

Dynamic Object Layers. It is a di erent pattern, because the structure


90 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

class HistoryProperty interface<br />

internals<br />

basics : BasicDL;<br />

oldReporter : HistoryReporter;<br />

methods<br />

process(aMessage : SinaMessage) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. ,<br />

oldReporter.historyReport,<br />

basics. g;<br />

end;<br />

class HistoryProperty implementation<br />

instvars<br />

methods<br />

process(aMessage : SinaMessage)<br />

begin<br />

oldReporter.saveHistory(aMessage);<br />

basics.process(aMessage);<br />

end;<br />

end;<br />

Figure 6.12: How tomake a generic property a dynamic layer<br />

class DynamicMail interface<br />

internals<br />

layers : BasicDL;<br />

mail : Mail;<br />

input lters<br />

meta : Meta = f [ ]layers.process g;<br />

dis : Dispatch =f layers. , mail. g;<br />

end;<br />

class DynamicMail implementation<br />

end;<br />

Figure 6.13: How tomake a normal class a dynamic layered class


6.3. Design Pattern: <strong>Composable</strong> Object <strong>Layering</strong> 91<br />

main<br />

temps<br />

aMailMessage : DynamicMail;<br />

aHistory : HistoryProperty;<br />

begin<br />

aMailMessage.addML(aHistory);<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Dynamic Mail Message');<br />

aMailMessage.send;<br />

aMailMessage.historyReport;<br />

end<br />

Figure 6.14: How to use a dynamic layered object<br />

is very di erent. The goals are the same however. In our solution, we have addressed<br />

some problems that the Decorator pattern introduced. Amongst them<br />

is the problem of losing object identity when a decorator is added to an object.<br />

Dynamic Slots<br />

Schmidt (n.d.) describes an implementation of dynamic slots in the BETA system.<br />

1 Dynamic slots are de ned as dynamically insertable attributes of arbitrary<br />

objects. The di erence between dynamic slots <strong>and</strong> dynamic layering is:<br />

Dynamic slots can only be used to insert attributes, while <strong>with</strong> dynamic<br />

layers, one can insert arbitrary behaviour into any object.<br />

The reference to dynamic slots is not transparant to the user or caller of<br />

the object. One must access these slots in a special way, while dynamic<br />

layers transparantly de ne interface extensions to the object, which can<br />

be accessed as all normal interface elements.<br />

In BETA, dynamic slots are enabled in the root object class, which means<br />

that all objects in the system are dynamic-slot-ready. With dynamic<br />

layering, all objects must explicitly enable this feature before it can be<br />

used. This is the result of enabling the insertion of meta-level layers, <strong>and</strong><br />

the de nition of additional object behaviour on top of already existing<br />

behaviour. If only simple attributes were to be added, 2 one could de ne<br />

one simple superclass which enabled dynamic layering, just as in the<br />

dynamic slot implementation.<br />

1. BETA isawell-known Object-Oriented programming environment.<br />

2. Which is not possible in Sina, but we can de ne simple get <strong>and</strong> put operations which<br />

manipulate some attribute.


92 Chapter 6. <strong>Composable</strong> Models Presented as Design Patterns<br />

6.4 Conclusions<br />

In this chapter we have transformed our design issues from Chapters 3 <strong>and</strong> 4<br />

into Design patterns. We conformed to the format of the GoF book (Gamma<br />

et al. 1995), but we had to make some extension to visualize the semantics of<br />

lters. It is made clear that the GoF format is also suitable for our category of<br />

problem solutions, although we used another object model.<br />

The Message Diagrams we introduced in this chapter are capable of<br />

showing the intensions of some lter set in an intuitive way. In Figure 6.9 for<br />

example, it is immediately clear that users can invoke all Mail methods, that<br />

mail h<strong>and</strong>lers are not supposed to read the mail contents, <strong>and</strong> that all incoming<br />

method calls are processed through a message decoder <strong>and</strong> a history recorder<br />

at a meta level. This overview picture is much harder to underst<strong>and</strong> when read<br />

directly from the lter speci cations.


Chapter 7<br />

Conclusions <strong>and</strong> Future Work<br />

We nalise this thesis by summarising the conclusions. We also give some directions<br />

for further research.<br />

7.1 Comparison of the C++ <strong>and</strong> the Sina implementations<br />

In this thesis we have shown the implementations of two models in two di erent<br />

languages. In this section, we will discuss the results.<br />

7.1.1 <strong>Multiple</strong> <strong>Views</strong><br />

In Table 7.1, we can see the amount ofwork that is necessary to implement the<br />

actions that we have identi ed in the <strong>Multiple</strong> <strong>Views</strong> Model (See Section 3.1.3).<br />

It is obvious that the initial number of methods is the same, because both<br />

implementations must provide the same Mail semantics.<br />

When wewant to add views however, it is clear that an enormous amount<br />

of work has to be done in the C ++ implementation. There are two methods that<br />

implement the views (the same two methods that are necessary for the Sina<br />

implementaton) <strong>and</strong> two times all original interface functions (one time for the<br />

Actions C++ Sina<br />

Initial 14 ? 14 ?<br />

Add <strong>Views</strong> 30 ? 2<br />

View Partitioning 8 ? 2<br />

View Extension 1 1<br />

Dynamic Behaviour Extension 5 ? 1<br />

Static Meta Behaviour Extension 5 ? 0<br />

View Composition 2 ? 0<br />

Table 7.1: Methods added or changed in . . . Mail class to change View aspects.<br />

Numbers marked <strong>with</strong> ? are dependent on the number of a ected methods,<br />

which means that increasing the number of a ected methods will increase the<br />

number in the table.<br />

93


94 Chapter 7. Conclusions <strong>and</strong> Future Work<br />

Actions C++ Sina<br />

Add Methods 2 ? 2 ?<br />

Rede ne Methods 3 ? 4 ?<br />

Extend Methods 5 ? 1<br />

Add Object Orthogonal Behaviour 15 ? 0<br />

Dynamic <strong>Layering</strong> 63 ? 0<br />

Table 7.2: Methods added or changed in . . . Mail class to change Layer aspects<br />

coupling between the view <strong>and</strong> the method, <strong>and</strong> one time for passing the method<br />

to the internal Mail implementation). In Sina, we only provide a simple lter<br />

speci cation.<br />

In all other situations (<strong>with</strong> View Extension as an exception), we have<br />

to do more work in the C ++ implementation than in the Sina implementation.<br />

This is because all a ected methods have to be rewritten in C ++, while in Sina<br />

only lter speci cations have to be adjusted.<br />

7.1.2 <strong>Layering</strong><br />

In Table 7.2, the C ++ implementation is not so bad in the beginning (see Section<br />

4.1.3 for the Layers scenario). When we rede ne methods, the Sina implementation<br />

even has one method more de ned than the C ++ implementation.<br />

This is however because the presence of an attachment is made explicit as a<br />

view in Sina, while in C ++ this is implicitly coded as a NULL check.<br />

When methods are extended, we must de ne ve functions in C ++. These<br />

functions are for the noti cation interface <strong>and</strong> the rede nition of the a ected<br />

Mail functions <strong>and</strong> method-view mappings. In Sina, only the view speci cation<br />

has to be written, accompanied by its method-view mappings.<br />

The addition of meta-functionality is clearly a lot of work in C ++. Adding<br />

othogonal behaviour requires us to rewrite all interface methods, while in Sina<br />

zero functions have to be written. When we de ne dynamically extensible models,<br />

the C ++ implementation follows the Decorator patterns of the Gof book<br />

(Gamma et al. 1995), <strong>and</strong> requires us to write each interface function four(!!)<br />

times: one interface replication for the Mail Component (the Component of the<br />

pattern); one for the DynamicMail interface (the ConcreteComponent of the<br />

pattern); one for the MailDecorator (the Decorator of the pattern); one replication<br />

for the MailHistory (which is a ConcreteDecorator) <strong>and</strong> nally a couple<br />

of methods for the MailReadNoti er (which is also a ConcreteDecorator). As<br />

can be seen, the interface conformance problem that occurs <strong>with</strong> this pattern<br />

is a serious problem. In the Sina implementation this is not a problem at all:<br />

the code of the DynamicMail class contain no methods at all!


7.2. Conclusions 95<br />

7.2 Conclusions<br />

In this thesis we have explicitly focused on the two modelling issues <strong>Multiple</strong><br />

Object <strong>Views</strong> <strong>and</strong> Object <strong>Layering</strong>. Software models often do not explicitly<br />

express views <strong>and</strong> layers, therefore these issues are often bypassed during the<br />

object design.<br />

This leads to software which is hard to reuse <strong>and</strong> maintain, while this<br />

was the reason for using object-oriented modelling techniques in the rst place!<br />

It turns out to be impossible to implement new features <strong>with</strong>out touching or<br />

recoding existing code.<br />

The traditional object-oriented language model lacks some properties,<br />

which are invaluable for expressing modelling issues like those discussed in this<br />

thesis. Amongst them are:<br />

Open message passing semantics.<br />

Meta models for messages.<br />

A delegation mechanism.<br />

We have shown this by implementing a case scenario in C ++, where we<br />

have tried to vary in di erent aspects of the modelling issues.<br />

These properties themselves are not su cient however: Delegation alone<br />

does not solve our problems, because we need to be able to de ne conditions on<br />

the delegation (for <strong>Multiple</strong> <strong>Views</strong> for example). We have tried to implement<br />

our <strong>Multiple</strong> <strong>Views</strong> model in Smalltalk, which is a delegation-based language.<br />

In this implementation we have seen a lot of problems similar to those in C ++<br />

(see Section 3.3 for a more detailed discussion).<br />

It is possible to implement some issue characteristics by replicating interface<br />

speci cations, <strong>and</strong> write \call-through" methods (we have seen that in our C ++<br />

implementations), but this has some drawbacks in general:<br />

Interface conformance. Interfaces needed deeply in a hierarchy must be<br />

declared in upper levels, resulting in a lot of code overhead <strong>and</strong> loss of<br />

overview. See for example our Dynamic <strong>Layering</strong> pattern compared to<br />

the Decorater pattern of Gamma et al. (1995).<br />

Call-throughs are not optimizable. With Composition Filter speci cations,<br />

we write interface declarations. These declarations eventually can<br />

be optimized into executable code by the compilers. When we write callthroughs,<br />

we write interface implementations, which will be executed in<br />

the way we have de ned them, <strong>and</strong> thus they are not optimized. This<br />

will lead to slower execution.<br />

We also have shown that the Composition Filters Object Model is capable of<br />

expressing the modelling issues in a natural way, while the normal properties of<br />

object-oriented models are preserved. New issues or features are gracefully integrated<br />

in existing software models, making it easy to compose software models


96 Chapter 7. Conclusions <strong>and</strong> Future Work<br />

instead of programming them. Take for example Figure 5.9, where history logging<br />

features were added to an existing class in two lter expressions, <strong>with</strong>out<br />

looking at the original class or the history logging class.<br />

Finally, wehave designed a graphical notation, in whichwe can express message<br />

passing semantics in an intuitive way. This notation, called message diagrams,<br />

is added to the pattern notations de ned by Gamma et al. (1995), so we have<br />

away toshow our modelling issues to the world.<br />

7.3 Future Work<br />

During the writing of this thesis, many thoughts have crossed the mind. It is<br />

impossible to work them all out in one thesis. We would like tomention them<br />

here, so others can elaborate on them.<br />

Pattern Implementation<br />

When implementing (applying) Software Design Patterns, we discover the following<br />

problems (Bosch 1995).<br />

Tracability The implementation does not show us explicitly that a pattern has<br />

been applied. We can see this in Appendix A.1, where we implemented<br />

the MailH<strong>and</strong>ler class as a Singleton pattern. In this implementation<br />

there is no trace of this pattern at all; only the documentation refers to<br />

it. The problem gets worse when objects participate in several patterns.<br />

The object implementation gets loaded <strong>with</strong> di erent sections belonging<br />

to di erent patterns.<br />

Implementation overhead In this same implementation we see a lot of code<br />

for just one pattern. The MailH<strong>and</strong>ler class implements several methods<br />

<strong>and</strong> de nes a class variable for the pattern. This means that every<br />

time the Singleton pattern is used, these or very similar methods will<br />

have to be written over <strong>and</strong> over.<br />

The Composition Filters Object Model can probably solve at least a part of<br />

this problem, by de ning patters <strong>and</strong> pattern roles as st<strong>and</strong>-alone software<br />

components, which can be attached to objects when appropriate. This might<br />

even be done dynamically using the Dynamic <strong>Layering</strong> Design Pattern from<br />

Section 6.3.<br />

Another way of pattern implementation has been de ned by Florijn,<br />

Meijers <strong>and</strong> van Winsen (1997). They de ne a tool which solves (a part of) the<br />

implementation overehead.<br />

Integration of Composition Filters in Java<br />

Java is becoming a very popular programming language. Unfortunately, it is<br />

based on the traditional object model, <strong>and</strong> thus has (from our point of view)<br />

the same problems as C ++.


7.3. Future Work 97<br />

It would be interesting when the Java language was extended <strong>with</strong> Composition<br />

Filters. The biggest problem for this is that Java is de ned as a very<br />

type-safe language. The use of Composition Filters introduces delegation, which<br />

intrinsically is not type-safe. It should be investigated how Composition Filters<br />

can be integrated into the Java language <strong>with</strong>out losing (too much) of its typesafety.<br />

An entry point for this can be the use of Java's interface speci cations,<br />

which in fact is an implementation of Contracts (as de ned by Helm, Holl<strong>and</strong><br />

<strong>and</strong> Gangopadhyay (1990)).<br />

Design \Improved" Versions of Existing Patterns<br />

Some of the design patterns presented by Gamma et al. (1995) can be improved<br />

by using Composition Filters. We have shown an example in this thesis<br />

already. Itwould bene t our knowledge <strong>and</strong> insights in object-oriented software<br />

modelling when other design patterns are also discussed in a similar way.<br />

Deployment of <strong>Composable</strong> Patterns<br />

A pattern is no pattern, unless it has proven itself (Gamma et al. 1995). So<br />

the patterns we have supplied in this thesis are in fact no patterns at all. They<br />

must be deployed rst. When Composition Filters are integrated in a popular<br />

development language, this will eventually happen.


98 Chapter 7. Conclusions <strong>and</strong> Future Work


Appendix A<br />

C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

A.1 Simple Mail System<br />

De nitions<br />

#ifndef MAIL H<br />

#define MAIL H<br />

class MailH<strong>and</strong>ler;<br />

class User;<br />

class Mail;<br />

class MailH<strong>and</strong>ler<br />

f<br />

public:<br />

static MailH<strong>and</strong>ler Instance(void);<br />

virtual int send(Mail );<br />

virtual char getName(void) f return name; g<br />

virtual void setName(char s) f name s; g<br />

protected:<br />

MailH<strong>and</strong>ler() fg<br />

virtual MailH<strong>and</strong>ler() fg<br />

char name;<br />

static MailH<strong>and</strong>ler instance;<br />

g;<br />

MailH<strong>and</strong>ler MailH<strong>and</strong>ler:: instance (MailH<strong>and</strong>ler )0;<br />

class User<br />

f<br />

public:<br />

virtual void setName(char s) f name s; g<br />

virtual char getName(void) f return name; g<br />

virtual void receive(Mail );<br />

(mail.hpp)<br />

99


100 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

virtual void sendSimpleMailTo(User );<br />

private:<br />

char name;<br />

g;<br />

class Mail<br />

f<br />

public:<br />

Mail();<br />

virtual void setMailOriginator(User );<br />

virtual User getMailOriginator(void);<br />

virtual void setMailReceiver(User );<br />

virtual User getMailReceiver(void);<br />

virtual void setMailContents(char );<br />

virtual char getMailContents(void);<br />

virtual void send(void);<br />

virtual void reply(void);<br />

virtual void approve(void);<br />

virtual int isApproved(void);<br />

virtual void setDelivered(void);<br />

virtual int isDelivered(void);<br />

virtual void setRoute(MailH<strong>and</strong>ler );<br />

virtual MailH<strong>and</strong>ler getRoute(void);<br />

private:<br />

User mailOriginator;<br />

User mailReceiver;<br />

char mailContents;<br />

int approved;<br />

int delivered;<br />

MailH<strong>and</strong>ler route;<br />

g;<br />

#endif<br />

Implementation<br />

#ifndef MAIN DEFINED<br />

#define MAIN DEFINED<br />

int main(void)<br />

f<br />

CALL TEST FUNCTION<br />

g<br />

#endif<br />

(main.inc)


A.1. Simple Mail System 101<br />

#undef CALL TEST FUNCTION<br />

#include <br />

#include "mail.hpp"<br />

MailH<strong>and</strong>ler<br />

MailH<strong>and</strong>ler::Instance(void)<br />

f<br />

if ( instance (MailH<strong>and</strong>ler )0) f<br />

instance new MailH<strong>and</strong>ler();<br />

instance!setName("The Only MailH<strong>and</strong>ler");<br />

g<br />

return instance;<br />

g<br />

int<br />

MailH<strong>and</strong>ler::send(Mail m)<br />

f<br />

if (m!getMailReceiver() 6= (User )0) f<br />

m!approve();<br />

g<br />

cout "=======>>>>>MailH<strong>and</strong>ler is peeking "<br />

"into the MailMessagenn"<br />

"=======>>>>>" m!getMailContents()<br />

"nn";<br />

if (m!isApproved()) f<br />

m!setRoute(this);<br />

m!setDelivered();<br />

m!getMailReceiver()!receive(m);<br />

return 0;<br />

g else f<br />

return -1;<br />

g<br />

g<br />

void<br />

User::receive(Mail m)<br />

f<br />

cout "User " this!getName()<br />

" received mail from "<br />

m!getMailOriginator()!getName()<br />

"nnRoute:ntnt" m!getRoute()!getName()<br />

"nnApproved:nt" (m!isApproved()?"Yes":"No")<br />

(mail.cc)


102 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

"nnDelivered:nt" (m!isDelivered()?"Yes":"No")<br />

"nnContents:nn----------nn"<br />

m!getMailContents()<br />

"nn----------nn";<br />

void<br />

User::sendSimpleMailTo(User u)<br />

f<br />

Mail mailMessage new Mail();<br />

mailMessage!setMailOriginator(this);<br />

mailMessage!setMailReceiver(u);<br />

mailMessage!setMailContents(<br />

"Contents of a simple mail message");<br />

mailMessage!send();<br />

g<br />

Mail::Mail()<br />

f<br />

mailOriginator (User )0;<br />

mailReceiver (User )0;<br />

mailContents (char )0;<br />

approved 0;<br />

delivered 0;<br />

route (MailH<strong>and</strong>ler )0;<br />

g<br />

void<br />

Mail::setMailOriginator(User u)<br />

f<br />

mailOriginator u;<br />

g<br />

User<br />

Mail::getMailOriginator(void)<br />

f<br />

return mailOriginator;<br />

g<br />

void<br />

Mail::setMailReceiver(User u)<br />

f<br />

mailReceiver u;<br />

g


A.1. Simple Mail System 103<br />

User<br />

Mail::getMailReceiver(void)<br />

f<br />

return mailReceiver;<br />

g<br />

void<br />

Mail::setMailContents(char s)<br />

f<br />

mailContents s;<br />

g<br />

char<br />

Mail::getMailContents(void)<br />

f<br />

return mailContents;<br />

g<br />

void<br />

Mail::send(void)<br />

f<br />

MailH<strong>and</strong>ler::Instance()!send(this);<br />

g<br />

void<br />

Mail::reply(void)<br />

f<br />

g<br />

void<br />

Mail::approve(void)<br />

f<br />

approved 1;<br />

g<br />

int<br />

Mail::isApproved(void)<br />

f<br />

return approved;<br />

g<br />

void<br />

Mail::setDelivered(void)


104 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

f<br />

g<br />

delivered 1;<br />

int<br />

Mail::isDelivered(void)<br />

f<br />

return delivered;<br />

g<br />

void<br />

Mail::setRoute(MailH<strong>and</strong>ler mh)<br />

f<br />

route mh;<br />

g<br />

MailH<strong>and</strong>ler<br />

Mail::getRoute(void)<br />

f<br />

return route;<br />

g<br />

#define CALL TEST FUNCTION test simple mail();<br />

void test simple mail(void)<br />

f<br />

cout "SimpleMail testnn";<br />

User u1 new User();<br />

u1!setName("MailOriginator");<br />

User u2 new User();<br />

u2!setName("MailReceiver");<br />

u1!sendSimpleMailTo(u2);<br />

g<br />

#include "main.inc"<br />

A.2 UserSystemView Mail System<br />

De nitions<br />

#ifndef USVMAIL H<br />

#define USVMAIL H<br />

#include "mail.hpp"<br />

(usvmail.hpp)


A.2. UserSystemView Mail System 105<br />

class MVUser;<br />

class MVMailH<strong>and</strong>ler;<br />

class UserSystemViewMail;<br />

#define CFilter(A,B) if (A)fB;gelsefcout "Filter error";g<br />

typedef enum f<br />

ObjectClass,<br />

MVMailH<strong>and</strong>lerClass,<br />

MVUserClass,<br />

GroupUserClass,<br />

PGPUserClass,<br />

ProtectedUserClass,<br />

UserSystemViewMailClass,<br />

OriginatorReceiverViewMailClass,<br />

GroupMailClass,<br />

SecureMailClass,<br />

Warning2MailClass,<br />

ProtectedMailClass,<br />

lastClass<br />

g classTypes;<br />

class Object<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return ObjectClass; g<br />

virtual int isKindOf(classTypes ct) f return this!myClass() ct; g<br />

virtual char asString(void) f return this!className(); g<br />

virtual char className(void) f return "Object"; g<br />

g;<br />

class MVMailH<strong>and</strong>ler : public MailH<strong>and</strong>ler, public Object<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return MVMailH<strong>and</strong>lerClass; g<br />

virtual int send(UserSystemViewMail );<br />

static MVMailH<strong>and</strong>ler Instance(void);<br />

virtual char className(void) f return "MVMailH<strong>and</strong>ler"; g<br />

protected:<br />

MVMailH<strong>and</strong>ler() fg<br />

virtual MVMailH<strong>and</strong>ler() fg<br />

static MVMailH<strong>and</strong>ler instance;<br />

g;


106 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

MVMailH<strong>and</strong>ler MVMailH<strong>and</strong>ler:: instance (MVMailH<strong>and</strong>ler )0;<br />

class MVUser : public User, public Object<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return MVUserClass; g<br />

virtual void receive(UserSystemViewMail );<br />

virtual void sendUserSystemViewMailTo(MVUser u);<br />

virtual char className(void) f return "MVUser"; g<br />

g;<br />

class UserSystemViewMail : public Object f<br />

public:<br />

UserSystemViewMail();<br />

virtual UserSystemViewMail();<br />

virtual classTypes myClass(void) f return UserSystemViewMailClass;<br />

g<br />

virtual void setMailOriginator(Object ,MVUser );<br />

virtual MVUser getMailOriginator(Object );<br />

virtual void setMailReceiver(Object ,MVUser );<br />

virtual MVUser getMailReceiver(Object );<br />

virtual void setMailContents(Object ,char );<br />

virtual char getMailContents(Object );<br />

virtual void send(Object );<br />

virtual void reply(Object );<br />

virtual void approve(Object );<br />

virtual int isApproved(Object );<br />

virtual void setDelivered(Object );<br />

virtual int isDelivered(Object );<br />

virtual void setRoute(Object ,MVMailH<strong>and</strong>ler );<br />

virtual MVMailH<strong>and</strong>ler getRoute(Object );<br />

virtual char className(void) f return "UserSystemViewMail"; g<br />

protected:<br />

virtual int isUserView(Object );<br />

virtual int isSystemView(Object );<br />

private:<br />

Mail mail;<br />

virtual void pureSetMailOriginator(MVUser );<br />

virtual MVUser pureGetMailOriginator(void);<br />

virtual void pureSetMailReceiver(MVUser );<br />

virtual MVUser pureGetMailReceiver(void);<br />

virtual void pureSetMailContents(char );<br />

virtual char pureGetMailContents(void);<br />

virtual void pureSend(void);


A.2. UserSystemView Mail System 107<br />

g;<br />

#endif<br />

virtual void pureReply(void);<br />

virtual void pureApprove(void);<br />

virtual int pureIsApproved(void);<br />

virtual void pureSetDelivered(void);<br />

virtual int pureIsDelivered(void);<br />

virtual void pureSetRoute(MVMailH<strong>and</strong>ler );<br />

virtual MVMailH<strong>and</strong>ler pureGetRoute(void);<br />

Implementation<br />

#include <br />

#include <br />

#include "usvmail.hpp"<br />

MVMailH<strong>and</strong>ler<br />

MVMailH<strong>and</strong>ler::Instance(void)<br />

f<br />

if ( instance (MVMailH<strong>and</strong>ler )0) f<br />

instance new MVMailH<strong>and</strong>ler();<br />

instance!setName("The Only MVMailH<strong>and</strong>ler");<br />

g<br />

return (MVMailH<strong>and</strong>ler ) instance;<br />

g<br />

int<br />

MVMailH<strong>and</strong>ler::send(UserSystemViewMail m)<br />

f<br />

if (m!getMailReceiver(this) 6= (MVUser )0) f<br />

m!approve(this);<br />

g<br />

cout "=======>>>>>MVMailH<strong>and</strong>ler is peeking "<br />

"into the MailMessagenn"<br />

"=======>>>>>" m!getMailContents(this)<br />

"nn";<br />

if (m!isApproved(this)) f<br />

m!setRoute(this,this);<br />

m!setDelivered(this);<br />

m!getMailReceiver(this)!receive(m);<br />

return 0;<br />

g else f<br />

(usvmail.cc)


108 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

g<br />

return -1;<br />

void<br />

MVUser::receive(UserSystemViewMail m)<br />

f<br />

cout "User " this!getName()<br />

" received mail from "<br />

m!getMailOriginator(this)!getName()<br />

"nnRoute:ntnt" m!getRoute(this)!getName()<br />

"nnApproved:nt" (m!isApproved(this)?"Yes":"No")<br />

"nnDelivered:nt"<br />

(m!isDelivered(this)?"Yes":"No")<br />

"nnContents:nn----------nn"<br />

m!getMailContents(this)<br />

"nn----------nn";<br />

g<br />

void<br />

MVUser::sendUserSystemViewMailTo(MVUser u)<br />

f<br />

UserSystemViewMail mailMessage new UserSystemViewMail();<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"Contents of a UserSystemView mail message");<br />

mailMessage!send(this);<br />

g<br />

UserSystemViewMail::UserSystemViewMail()<br />

f<br />

mail new Mail();<br />

assert( mail 6= (Mail )0);<br />

g<br />

UserSystemViewMail:: UserSystemViewMail()<br />

f<br />

delete mail;<br />

g<br />

void<br />

UserSystemViewMail::pureSetMailOriginator(MVUser u)<br />

f


A.2. UserSystemView Mail System 109<br />

g<br />

mail!setMailOriginator(u);<br />

MVUser<br />

UserSystemViewMail::pureGetMailOriginator(void)<br />

f<br />

return (MVUser ) mail!getMailOriginator();<br />

g<br />

void<br />

UserSystemViewMail::pureSetMailReceiver(MVUser u)<br />

f<br />

mail!setMailReceiver(u);<br />

g<br />

MVUser<br />

UserSystemViewMail::pureGetMailReceiver(void)<br />

f<br />

return (MVUser ) mail!getMailReceiver();<br />

g<br />

void<br />

UserSystemViewMail::pureSetMailContents(char s)<br />

f<br />

mail!setMailContents(s);<br />

g<br />

char<br />

UserSystemViewMail::pureGetMailContents(void)<br />

f<br />

return mail!getMailContents();<br />

g<br />

void<br />

UserSystemViewMail::pureSend(void)<br />

f<br />

MVMailH<strong>and</strong>ler::Instance()!send(this);<br />

g<br />

void<br />

UserSystemViewMail::pureReply(void)<br />

f<br />

mail!reply();<br />

g


110 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

void<br />

UserSystemViewMail::pureApprove(void)<br />

f<br />

mail!approve();<br />

g<br />

int<br />

UserSystemViewMail::pureIsApproved(void)<br />

f<br />

return mail!isApproved();<br />

g<br />

void<br />

UserSystemViewMail::pureSetDelivered(void)<br />

f<br />

mail!setDelivered();<br />

g<br />

int<br />

UserSystemViewMail::pureIsDelivered(void)<br />

f<br />

return mail!isDelivered();<br />

g<br />

void<br />

UserSystemViewMail::pureSetRoute(MVMailH<strong>and</strong>ler mh)<br />

f<br />

mail!setRoute(mh);<br />

g<br />

MVMailH<strong>and</strong>ler<br />

UserSystemViewMail::pureGetRoute(void)<br />

f<br />

return (MVMailH<strong>and</strong>ler ) mail!getRoute();<br />

g<br />

int<br />

UserSystemViewMail::isUserView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return sender!isKindOf(MVUserClass);<br />

g


A.2. UserSystemView Mail System 111<br />

int<br />

UserSystemViewMail::isSystemView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return sender!isKindOf(MVMailH<strong>and</strong>lerClass);<br />

g<br />

void<br />

UserSystemViewMail::setMailOriginator(Object sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),this!pureSetMailOriginator(u));<br />

g<br />

MVUser<br />

UserSystemViewMail::getMailOriginator(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return pureGetMailOriginator();<br />

g<br />

void<br />

UserSystemViewMail::setMailReceiver(Object sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),this!pureSetMailReceiver(u));<br />

g<br />

MVUser<br />

UserSystemViewMail::getMailReceiver(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return pureGetMailReceiver();<br />

g<br />

void<br />

UserSystemViewMail::setMailContents(Object sender,char s)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),this!pureSetMailContents(s));<br />

g<br />

char<br />

UserSystemViewMail::getMailContents(Object sender)


112 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

f<br />

g<br />

char s (char )0;<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),s this!pureGetMailContents());<br />

return s;<br />

void<br />

UserSystemViewMail::send(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),this!pureSend());<br />

g<br />

void<br />

UserSystemViewMail::reply(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isUserView(sender),this!pureReply());<br />

g<br />

void<br />

UserSystemViewMail::approve(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isSystemView(sender),this!pureApprove());<br />

g<br />

int<br />

UserSystemViewMail::isApproved(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return this!pureIsApproved();<br />

g<br />

void<br />

UserSystemViewMail::setDelivered(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isSystemView(sender),this!pureSetDelivered());<br />

g<br />

int<br />

UserSystemViewMail::isDelivered(Object sender)


A.3. OriginatorReceiverView Mail System 113<br />

f<br />

g<br />

assert(sender6=(Object )0);<br />

return this!pureIsDelivered();<br />

void<br />

UserSystemViewMail::setRoute(Object sender,MVMailH<strong>and</strong>ler mh)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isSystemView(sender),this!pureSetRoute(mh));<br />

g<br />

MVMailH<strong>and</strong>ler<br />

UserSystemViewMail::getRoute(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return this!pureGetRoute();<br />

g<br />

#define CALL TEST FUNCTION test usersystemview mail();<br />

void test usersystemview mail(void)<br />

f<br />

cout "UserSystemViewMail testnn";<br />

MVUser u1 new MVUser();<br />

u1!setName("MailOriginator");<br />

MVUser u2 new MVUser();<br />

u2!setName("MailReceiver");<br />

u1!sendUserSystemViewMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "mail.cc"<br />

A.3 OriginatorReceiverView Mail System<br />

De nitions<br />

#ifndef ORVMAIL H<br />

#define ORVMAIL H<br />

#include "usvmail.hpp"<br />

(orvmail.hpp)


114 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

class VPUser : public MVUser<br />

f<br />

public:<br />

virtual void sendOriginatorReceiverViewMailTo(MVUser );<br />

g;<br />

class OriginatorReceiverViewMail : public UserSystemViewMail<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return<br />

OriginatorReceiverViewMailClass; g<br />

virtual void setMailOriginator(Object ,MVUser );<br />

virtual void setMailReceiver(Object ,MVUser );<br />

virtual void setMailContents(Object ,char );<br />

virtual char getMailContents(Object );<br />

virtual void send(Object );<br />

virtual void reply(Object );<br />

protected:<br />

virtual int isOriginatorView(Object );<br />

virtual int isReceiverView(Object );<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include <br />

#include "orvmail.hpp"<br />

(orvmail.cc)<br />

void<br />

VPUser::sendOriginatorReceiverViewMailTo(MVUser u)<br />

f<br />

OriginatorReceiverViewMail mailMessage new<br />

OriginatorReceiverViewMail();<br />

VPUser sneakUser new VPUser();<br />

sneakUser!setName("Sneaky User");<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"Contents of a OriginatorReceiverView Mail Message");<br />

mailMessage!send(this);<br />

sneakUser!receive(mailMessage);


A.3. OriginatorReceiverView Mail System 115<br />

g<br />

int<br />

OriginatorReceiverViewMail::isOriginatorView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return (this!getMailOriginator(this) (MVUser )0)<br />

jj sender this!getMailOriginator(this);<br />

g<br />

int<br />

OriginatorReceiverViewMail::isReceiverView(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

return sender this!getMailReceiver(this);<br />

g<br />

void<br />

OriginatorReceiverViewMail::setMailOriginator(Object sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender),<br />

UserSystemViewMail::setMailOriginator(sender,u));<br />

g<br />

void<br />

OriginatorReceiverViewMail::setMailReceiver(Object sender,MVUser u)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender),<br />

UserSystemViewMail::setMailReceiver(sender,u));<br />

g<br />

void<br />

OriginatorReceiverViewMail::setMailContents(Object sender,char s)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender),<br />

UserSystemViewMail::setMailContents(sender,s));<br />

g<br />

char<br />

OriginatorReceiverViewMail::getMailContents(Object sender)<br />

f


116 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

char s (char )0;<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender)<br />

jj this!isReceiverView(sender),<br />

s UserSystemViewMail::getMailContents(sender));<br />

return s;<br />

void<br />

OriginatorReceiverViewMail::send(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isOriginatorView(sender),<br />

UserSystemViewMail::send(sender));<br />

g<br />

void<br />

OriginatorReceiverViewMail::reply(Object sender)<br />

f<br />

assert(sender6=(Object )0);<br />

CFilter(this!isReceiverView(sender),<br />

UserSystemViewMail::reply(sender));<br />

g<br />

#define CALL TEST FUNCTION test originatorreceiverview mail();<br />

void test originatorreceiverview mail(void)<br />

f<br />

cout "OriginatorReceiverViewMail testnn";<br />

VPUser u1 new VPUser();<br />

u1!setName("MailOriginator");<br />

VPUser u2 new VPUser();<br />

u2!setName("MailReceiver");<br />

u1!sendOriginatorReceiverViewMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "usvmail.cc"<br />

A.4 Group Mail System<br />

De nitions<br />

(gmail.hpp)


A.4. Group Mail System 117<br />

#ifndef GMAIL H<br />

#define GMAIL H<br />

#include "orvmail.hpp"<br />

class GroupUser: public VPUser<br />

f<br />

public:<br />

GroupUser() f groupNumber 0; g<br />

virtual classTypes myClass(void) f return GroupUserClass; g<br />

virtual void sendGroupMailTo(MVUser );<br />

virtual void setGroup(int i) f groupNumber i; g<br />

virtual int getGroup(void) f return groupNumber; g<br />

virtual int isKindOf(classTypes ct) f return ((ct MVUserClass) jj<br />

VPUser::isKindOf(ct)); g<br />

protected:<br />

int groupNumber;<br />

g;<br />

class GroupMail : public OriginatorReceiverViewMail<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return GroupMailClass; g<br />

protected:<br />

virtual int isOriginatorView(Object );<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include <br />

#include "gmail.hpp"<br />

void<br />

GroupUser::sendGroupMailTo(MVUser u)<br />

f<br />

GroupMail mailMessage new GroupMail();<br />

GroupUser groupMember new GroupUser();<br />

groupMember!setName("GroupMember of MailOriginator");<br />

groupMember!setGroup(100);<br />

this!setGroup(100);<br />

(gmail.cc)


118 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"Contents of a Group Mail Message");<br />

mailMessage!send(this);<br />

groupMember!receive(mailMessage);<br />

int<br />

GroupMail::isOriginatorView(Object sender)<br />

f<br />

MVUser orig this!getMailOriginator(this);<br />

assert(sender6=(Object )0);<br />

return (orig (MVUser )0)<br />

jj sender orig<br />

jj (sender!isKindOf(GroupUserClass) &&<br />

orig!isKindOf(GroupUserClass)<br />

&& ((GroupUser )sender)!getGroup()<br />

((GroupUser )orig)!getGroup());<br />

g<br />

#define CALL TEST FUNCTION test group mail();<br />

void test group mail(void)<br />

f<br />

cout "Group Mail testnn";<br />

GroupUser u1 new GroupUser();<br />

u1!setName("MailOriginator");<br />

GroupUser u2 new GroupUser();<br />

u2!setName("MailReceiver");<br />

u1!sendGroupMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "orvmail.cc"<br />

A.5 Secure Mail System<br />

De nitions<br />

#ifndef SMAIL H<br />

#define SMAIL H<br />

(smail.hpp)


A.5. Secure Mail System 119<br />

#include "gmail.hpp"<br />

class PGPUser : public GroupUser<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return PGPUserClass; g<br />

virtual int isKindOf(classTypes ct) f return (ct GroupUserClass jj<br />

GroupUser::isKindOf(ct)); g<br />

virtual void setPGPPubKey(int i) f publicKey i; g<br />

virtual int getPGPPubKey(void) f return publicKey; g<br />

virtual void setPGPPrivKey(int i) f privateKey i; g<br />

virtual int getPGPPrivKey(void) f return privateKey; g<br />

virtual void sendSecureMailTo(MVUser );<br />

private:<br />

int publicKey;<br />

int privateKey;<br />

g;<br />

class SecureMail : public GroupMail<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return SecureMailClass; g<br />

virtual char getMailContents(Object );<br />

virtual void setMailContents(Object , char );<br />

protected:<br />

virtual int isPGPUserView(Object );<br />

private:<br />

virtual char purePGPGetMailContents(Object );<br />

virtual void purePGPSetMailContents(Object , char );<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include <br />

#include "smail.hpp"<br />

void<br />

PGPUser::sendSecureMailTo(MVUser u)<br />

f<br />

SecureMail mailMessage new SecureMail();<br />

(smail.cc)


120 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

GroupUser nonPGPUser new GroupUser();<br />

nonPGPUser!setName("NON PGP USER");<br />

nonPGPUser!setGroup(100);<br />

this!setGroup(100);<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"Contents of a Secure Mail Message");<br />

mailMessage!send(this);<br />

nonPGPUser!receive(mailMessage);<br />

int<br />

SecureMail::isPGPUserView(Object sender)<br />

f<br />

return sender!isKindOf(PGPUserClass);<br />

g<br />

char<br />

SecureMail::getMailContents(Object sender)<br />

f<br />

char s (char )0;<br />

if (this!isPGPUserView(sender)) f<br />

s this!purePGPGetMailContents(sender);<br />

g else f<br />

s GroupMail::getMailContents(sender);<br />

g<br />

return s;<br />

g<br />

void<br />

SecureMail::setMailContents(Object sender,char s)<br />

f<br />

if (this!isPGPUserView(sender)) f<br />

this!purePGPSetMailContents(sender,s);<br />

g else f<br />

GroupMail::setMailContents(sender,s);<br />

g<br />

g<br />

char<br />

SecureMail::purePGPGetMailContents(Object sender)<br />

f<br />

char l, s strdup(GroupMail::getMailContents(sender));


A.6. Warning2 Mail System 121<br />

g<br />

cout "PGP decoding...nn";<br />

for (l s; l;l++) ( l)--;<br />

return s;<br />

void<br />

SecureMail::purePGPSetMailContents(Object sender, char s)<br />

f<br />

char l, c strdup(s);<br />

cout "PGP encoding...nn";<br />

for (l c; l;l++) ( l)++;<br />

GroupMail::setMailContents(sender,c);<br />

g<br />

#define CALL TEST FUNCTION test secure mail();<br />

void test secure mail(void)<br />

f<br />

cout "Secure Mail testnn";<br />

PGPUser u1 new PGPUser();<br />

u1!setName("MailOriginator");<br />

PGPUser u2 new PGPUser();<br />

u2!setName("MailReceiver");<br />

u1!sendSecureMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "gmail.cc"<br />

A.6 Warning2 Mail System<br />

De nitions<br />

#ifndef W2MAIL H<br />

#define W2MAIL H<br />

#include "smail.hpp"<br />

typedef enum f<br />

W2MailSetMailContentsSelector,<br />

W2MailSetMailOriginatorSelector,<br />

W2MailSetMailReceiverSelector,<br />

W2MailSendSelector,<br />

(w2mail.hpp)


122 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

lastWarning2MailSelector<br />

g Warning2MailSelector;<br />

class Warning2User : public PGPUser<br />

f<br />

public:<br />

virtual void sendWarning2MailTo(MVUser );<br />

g;<br />

class Warning2Mail : public SecureMail<br />

f<br />

public:<br />

Warning2Mail();<br />

virtual classTypes myClass(void) f return Warning2MailClass; g<br />

virtual void setMailContents(Object ,char );<br />

virtual void setMailOriginator(Object , MVUser );<br />

virtual void setMailReceiver(Object , MVUser );<br />

virtual void send(Object );<br />

protected:<br />

virtual int isWarning2View(Warning2MailSelector);<br />

private:<br />

int selectorCount[ lastWarning2MailSelector];<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include "w2mail.hpp"<br />

void<br />

Warning2User::sendWarning2MailTo(MVUser u)<br />

f<br />

Warning2Mail mailMessage new Warning2Mail();<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"First contents of a Warning2 Mail Message");<br />

mailMessage!setMailContents(this,<br />

"Second contents of a Warning2 Mail Message");<br />

(w2mail.cc)


A.6. Warning2 Mail System 123<br />

g<br />

mailMessage!send(this);<br />

Warning2Mail::Warning2Mail()<br />

f<br />

int i;<br />

for (i 0;i< lastWarning2MailSelector;i++)<br />

selectorCount[i] 0;<br />

g<br />

int<br />

Warning2Mail::isWarning2View(Warning2MailSelector sel)<br />

f<br />

return selectorCount[sel] > 0;<br />

g<br />

void<br />

Warning2Mail::setMailContents(Object sender, char s)<br />

f<br />

if (this!isWarning2View(W2MailSetMailContentsSelector)) f<br />

cout "Warning, setMailContents sent twicenn";<br />

g<br />

selectorCount[W2MailSetMailContentsSelector]++;<br />

SecureMail::setMailContents(sender,s);<br />

g<br />

void<br />

Warning2Mail::setMailOriginator(Object sender, MVUser u)<br />

f<br />

if (this!isWarning2View(W2MailSetMailOriginatorSelector)) f<br />

cout "Warning, setMailOriginator sent twicenn";<br />

g<br />

selectorCount[W2MailSetMailOriginatorSelector]++;<br />

SecureMail::setMailOriginator(sender,u);<br />

g<br />

void<br />

Warning2Mail::setMailReceiver(Object sender, MVUser u)<br />

f<br />

if (this!isWarning2View(W2MailSetMailReceiverSelector)) f<br />

cout "Warning, setMailReceiver sent twicenn";<br />

g<br />

selectorCount[W2MailSetMailReceiverSelector]++;<br />

SecureMail::setMailReceiver(sender,u);


124 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

void<br />

Warning2Mail::send(Object sender)<br />

f<br />

if (this!isWarning2View(W2MailSendSelector)) f<br />

cout "Warning, send sent twicenn";<br />

g<br />

selectorCount[W2MailSendSelector]++;<br />

SecureMail::send(sender);<br />

g<br />

#define CALL TEST FUNCTION test w2 mail();<br />

void test w2 mail(void)<br />

f<br />

cout "w2 Mail testnn";<br />

Warning2User u1 new Warning2User();<br />

u1!setName("MailOriginator");<br />

Warning2User u2 new Warning2User();<br />

u2!setName("MailReceiver");<br />

u1!sendWarning2MailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "smail.cc"<br />

A.7 Protected Mail System<br />

De nitions<br />

#ifndef PMAIL H<br />

#define PMAIL H<br />

#include "w2mail.hpp"<br />

class SecureDocument:public Object f<br />

public:<br />

virtual void setSecurityLevel(int);<br />

virtual int getSecurityLevel(void);<br />

protected:<br />

int isSecurityClearance(Object );<br />

private:<br />

(pmail.hpp)


A.7. Protected Mail System 125<br />

g;<br />

int securityLevel;<br />

class ProtectedUser : public Warning2User<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return ProtectedUserClass; g<br />

virtual int getSecurityLevel(void);<br />

virtual void setSecurityLevel(int);<br />

virtual void sendProtectedMailTo(MVUser );<br />

virtual int isKindOf(classTypes ct) f return ((ct PGPUserClass) jj<br />

Warning2User::isKindOf(ct)); g<br />

private:<br />

int securityLevel;<br />

g;<br />

class ProtectedMail : public Warning2Mail, public SecureDocument<br />

f<br />

public:<br />

virtual classTypes myClass(void) f return ProtectedMailClass; g<br />

virtual void setMailContents(Object ,char );<br />

virtual char getMailContents(Object );<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include "pmail.hpp"<br />

void<br />

SecureDocument::setSecurityLevel(int i) f<br />

securityLevel i;<br />

g<br />

int<br />

SecureDocument::getSecurityLevel(void) f<br />

return securityLevel;<br />

g<br />

int<br />

SecureDocument::isSecurityClearance(Object sender) f<br />

(pmail.cc)


126 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

g<br />

return (sender!isKindOf(ProtectedUserClass)) &&<br />

(((ProtectedUser )sender)!getSecurityLevel()<br />

this!getSecurityLevel());<br />

void<br />

ProtectedUser::setSecurityLevel(int i) f<br />

securityLevel i;<br />

g<br />

int<br />

ProtectedUser::getSecurityLevel(void) f<br />

return securityLevel;<br />

g<br />

void<br />

ProtectedUser::sendProtectedMailTo(MVUser u)<br />

f<br />

ProtectedMail mailMessage new ProtectedMail();<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setSecurityLevel(3);<br />

mailMessage!setMailContents(this,<br />

"Contents of a Protected Mail Message");<br />

mailMessage!send(this);<br />

mailMessage!setSecurityLevel(1);<br />

mailMessage!send(this);<br />

g<br />

void<br />

ProtectedMail::setMailContents(Object sender, char s)<br />

f<br />

CFilter(this!isSecurityClearance(sender),<br />

Warning2Mail::setMailContents(sender,s));<br />

g<br />

char<br />

ProtectedMail::getMailContents(Object sender)<br />

f<br />

char s (char )0;<br />

CFilter(this!isSecurityClearance(sender),s<br />

Warning2Mail::getMailContents(sender));<br />

return s;<br />

g


A.7. Protected Mail System 127<br />

#define CALL TEST FUNCTION test protected mail();<br />

void test protected mail(void)<br />

f<br />

cout "Protected Mail testnn";<br />

ProtectedUser u1 new ProtectedUser();<br />

u1!setName("MailOriginator");<br />

u1!setSecurityLevel(4);<br />

ProtectedUser u2 new ProtectedUser();<br />

u2!setName("MailReceiver");<br />

u2!setSecurityLevel(2);<br />

u1!sendProtectedMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "w2mail.cc"


128 Appendix A. C ++ Implementation of <strong>Multiple</strong> <strong>Views</strong>


Appendix B<br />

Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

B.1 Simple Mail System<br />

#NoDefSyncFilter;<br />

class MailH<strong>and</strong>ler interface<br />

methods<br />

send (aMailMessage : Mail) returns nil;<br />

getName returns String;<br />

setName (aName : String) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. g;<br />

end;<br />

class MailH<strong>and</strong>ler implementation<br />

instvars<br />

name : String;<br />

initial<br />

begin<br />

name 'NoName'<br />

end;<br />

methods<br />

send (aMailMessage : Mail)<br />

begin<br />

return;<br />

if aMailMessage.getMailReceiver 6= nil<br />

then<br />

aMailMessage.approve<br />

end;<br />

server.printLine('Peeking into the MailMessage');<br />

server.printLine(aMailMessage.getMailContents);<br />

if aMailMessage.isApproved<br />

then<br />

(MailH<strong>and</strong>ler.sina)<br />

129


130 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

aMailMessage.setRoute(server);<br />

aMailMessage.setDelivered;<br />

aMailMessage.getMailReceiver.receive(aMailMessage)<br />

end<br />

end;<br />

getName<br />

begin<br />

return name<br />

end;<br />

setName (aName : String)<br />

begin<br />

name aName<br />

end;<br />

end;<br />

class User interface<br />

methods<br />

setName (aName : String) returns nil;<br />

getName returns String;<br />

receive (aMailMessage : Mail) returns nil;<br />

sendSimpleMailTo (aUser : User) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. g;<br />

end;<br />

class User implementation<br />

instvars<br />

name : String;<br />

initial<br />

begin<br />

name 'NoName'<br />

end;<br />

methods<br />

setName (aName : String)<br />

begin<br />

name aName<br />

end;<br />

getName<br />

begin<br />

return name<br />

end;<br />

receive (aMailMessage : Mail)<br />

begin<br />

(User.sina)


B.1. Simple Mail System 131<br />

return;<br />

server.print('User ');<br />

server.print(server.getName);<br />

server.print(' received mail from ');<br />

server.printLine(aMailMessage.getMailOriginator.getName);<br />

server.print('Route: ');<br />

server.printLine(aMailMessage.getRoute.getName);<br />

server.print('Approved: ');<br />

server.printLine(aMailMessage.isApproved);<br />

server.print('Delivered: ');<br />

server.printLine(aMailMessage.isDelivered);<br />

server.print('Contents:');<br />

server.printLine(aMailMessage.getMailContents);<br />

end;<br />

sendSimpleMailTo (aUser : User)<br />

temps<br />

aMailMessage : Mail;<br />

begin<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a simple mail message');<br />

aMailMessage.send<br />

end;<br />

end;<br />

class Mail interface<br />

externals<br />

MH : MailH<strong>and</strong>ler;<br />

methods<br />

setMailOriginator (aUser : User) returns nil;<br />

getMailOriginator returns User;<br />

setMailReceiver (aUser : User) returns nil;<br />

getMailReceiver returns User;<br />

setMailContents (aString : String) returns nil;<br />

getMailContents returns String;<br />

send returns nil;<br />

reply returns nil;<br />

approve returns nil;<br />

isApproved returns Boolean;<br />

setDelivered returns nil;<br />

isDelivered returns Boolean;<br />

setRoute (aMH : MailH<strong>and</strong>ler) returns nil;<br />

(Mail.sina)


132 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

getRoute returns MailH<strong>and</strong>ler;<br />

input lters<br />

dis : Dispatch =f inner. g;<br />

end;<br />

class Mail implementation<br />

instvars<br />

mailOriginator : User;<br />

mailReceiver : User;<br />

mailContents : String;<br />

approved : Boolean;<br />

delivered : Boolean;<br />

route : MailH<strong>and</strong>ler;<br />

initial<br />

begin<br />

mailOriginator nil;<br />

mailReceiver nil;<br />

mailContents '';<br />

approved false;<br />

delivered false;<br />

route nil<br />

end;<br />

methods<br />

setMailOriginator (aUser : User)<br />

begin<br />

mailOriginator aUser<br />

end;<br />

getMailOriginator<br />

begin<br />

return mailOriginator<br />

end;<br />

setMailReceiver (aUser : User)<br />

begin<br />

mailReceiver aUser<br />

end;<br />

getMailReceiver<br />

begin<br />

return mailReceiver<br />

end;<br />

setMailContents (aString : String)<br />

begin<br />

mailContents aString<br />

end;<br />

getMailContents


B.1. Simple Mail System 133<br />

begin<br />

return mailContents<br />

end;<br />

send<br />

begin<br />

MH.send(server)<br />

end;<br />

reply<br />

begin<br />

server.print('Not implemented')<br />

end;<br />

approve<br />

begin<br />

approved true<br />

end;<br />

isApproved<br />

begin<br />

return approved<br />

end;<br />

setDelivered<br />

begin<br />

delivered true<br />

end;<br />

isDelivered<br />

begin<br />

return delivered<br />

end;<br />

setRoute (aMH : MailH<strong>and</strong>ler)<br />

begin<br />

route aMH<br />

end;<br />

getRoute<br />

begin<br />

return route<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : User;<br />

u2 : User;<br />

begin<br />

u1.setName('MailOriginator');<br />

(MailMain.sina)


134 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

end<br />

u2.setName('MailReceiver');<br />

u1.sendSimpleMailTo(u2);<br />

B.2 UserSystemView Mail System<br />

(UserSystemViewMail.sina)<br />

class UserSystemViewMail interface<br />

externals<br />

User : Class;<br />

MailH<strong>and</strong>ler : Class;<br />

internals<br />

mail : Mail;<br />

conditions<br />

userView;<br />

systemView;<br />

input lters<br />

mv1 : Error = f userView ) setMailOriginator,<br />

true ; setMailOriginator g;<br />

mv2 : Error = f userView ) setMailReceiver, true ; setMailReceiver g;<br />

mv3 : Error = f userView ) setMailContents,<br />

true ; setMailContents g;<br />

mv4 : Error = f userView ) getMailContents,<br />

true ; getMailContents g;<br />

mv5 : Error = f userView ) send, true ; send g;<br />

mv6 : Error = f userView ) reply, true ; reply g;<br />

mv7 : Error = f systemView ) approve, true ; approve g;<br />

mv8 : Error = f systemView ) setDelivered, true ; setDelivered g;<br />

mv9 : Error = f systemView ) setRoute, true ; setRoute g;<br />

disp : Dispatch =f inner. , mail. g;<br />

end;<br />

class UserSystemViewMail implementation<br />

conditions<br />

userView<br />

begin<br />

return message.sender.isKindOf:(User)<br />

end;<br />

systemView<br />

begin<br />

return message.sender.isKindOf:(MailH<strong>and</strong>ler)<br />

end;<br />

end;


B.3. OriginatorReceiverView Mail System 135<br />

class MVUser interface<br />

internals<br />

user : User;<br />

methods<br />

sendUserSystemViewMailTo (aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class MVUser implementation<br />

methods<br />

sendUserSystemViewMailTo (aUser : User)<br />

temps<br />

aMailMessage : UserSystemViewMail;<br />

begin<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a UserSystem Mail Message');<br />

aMailMessage.send<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : MVUser;<br />

u2 : MVUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendUserSystemViewMailTo(u2);<br />

end<br />

B.3 OriginatorReceiverView Mail System<br />

class OriginatorReceiverViewMail interface<br />

externals<br />

User : Class;<br />

MailH<strong>and</strong>ler : Class;<br />

internals<br />

(MVUser.sina)<br />

(UserSystemViewMailMain.sina)<br />

(OriginatorReceiverViewMail.sina)


136 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

mail : UserSystemViewMail;<br />

conditions<br />

originatorView;<br />

receiverView;<br />

input lters<br />

mv1 : Error = f originatorView ) setMailOriginator,<br />

true ; setMailOriginator g;<br />

mv2 : Error = f originatorView ) setMailReceiver,<br />

true ; setMailReceiver g;<br />

mv3 : Error = f originatorView ) setMailContents<br />

true ; setMailContents g;<br />

mv4 : Error = f originatorView ) getMailContents,<br />

receiverView ) getMailContents,<br />

true ; getMailContents g;<br />

mv5 : Error = f originatorView ) send, true ; send g;<br />

mv6 : Error = f receiverView ) reply, true ; reply g;<br />

disp : Dispatch =f inner. , mail. g;<br />

end;<br />

class OriginatorReceiverViewMail implementation<br />

conditions<br />

originatorView<br />

begin<br />

return (mail.getMailOriginator nil)<br />

jj (mail.getMailOriginator message.sender);<br />

end;<br />

receiverView<br />

begin<br />

return mail.getMailReceiver message.sender<br />

end;<br />

end;<br />

class VPUser interface<br />

internals<br />

user : MVUser;<br />

methods<br />

sendOriginatorReceiverViewMailTo (aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class VPUser implementation<br />

methods<br />

(VPUser.sina)


B.4. Group Mail System 137<br />

sendOriginatorReceiverViewMailTo (aUser : User)<br />

temps<br />

aMailMessage : OriginatorReceiverViewMail;<br />

sneakUser : User;<br />

begin<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a OriginatorReceiver Mail Message');<br />

aMailMessage.send;<br />

sneakUser.receive(aMailMessage)<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : VPUser;<br />

u2 : VPUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendOriginatorReceiverViewMailTo(u2);<br />

end<br />

B.4 Group Mail System<br />

class GroupMail interface<br />

externals<br />

GroupUser : Class;<br />

internals<br />

mail : OriginatorReceiverViewMail;<br />

conditions<br />

originatorView;<br />

input lters<br />

dis : Dispatch =f inner. , mail. g;<br />

end;<br />

class GroupMail implementation<br />

conditions<br />

originatorView<br />

temps<br />

orig : User;<br />

(OriginatorReceiverViewMailMain.sina)<br />

(GroupMail.sina)


138 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

begin<br />

orig mail.getMailOriginator;<br />

return (orig nil)<br />

jj (orig message.sender)<br />

jj ( orig.isKindOf(GroupUser)<br />

message.sender.isKindOf(GroupUser)<br />

orig.getGroup message.sender.getGroup )<br />

end<br />

end;<br />

class GroupUser interface<br />

internals<br />

user : VPUser;<br />

groupNumber : Integer;<br />

methods<br />

getGroup returns Integer;<br />

setGroup (num:Integer) returns nil;<br />

sendGroupMailTo(aUser : User) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. , user. g;<br />

end;<br />

(GroupUser.sina)<br />

class GroupUser implementation<br />

initial<br />

begin<br />

groupNumber 0;<br />

end<br />

methods<br />

getGroup<br />

begin<br />

return groupNumber;<br />

end<br />

setGroup (num:Integer)<br />

begin<br />

groupNumber num;<br />

end<br />

sendGroupMailTo(aUser : User)<br />

temps<br />

aMailMessage : GroupMail;<br />

groupMember : GroupUser;<br />

begin<br />

groupMember.setName('GroupMember of MailOriginator');<br />

groupMember.setGroup(100);


B.5. Secure Mail System 139<br />

self.setGroup(100);<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Group Mail Message');<br />

aMailMessage.send;<br />

groupMember.receive(aMailMessage);<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : GroupUser;<br />

u2 : GroupUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendGroupMailTo(u2);<br />

end<br />

B.5 Secure Mail System<br />

(GroupMailMain.sina)<br />

(SecureMail.sina)<br />

class SecureMail interface<br />

externals<br />

PGPUser : Class;<br />

internals<br />

mail : GroupMail;<br />

conditions<br />

pgpView;<br />

input lters<br />

dis : Dispatch =f pgpView->[getMailContents]getPGPMailContents,<br />

pgpView->[setMailContents]setPGPMailContents,<br />

inner. , mail. g;<br />

end;<br />

class SecureMail implementation<br />

conditions<br />

pgpView<br />

begin<br />

return message.sender.isKindOf(PGPUSer);<br />

end<br />

methods


140 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

getPGPMailContents returns String<br />

begin<br />

self.printLine('PGP decoding...');<br />

return self.getMailContents<br />

end;<br />

setPGPMailContents(s:String) returns nil<br />

begin<br />

self.printLine('PGP encoding...');<br />

self.setMailContents(s);<br />

end;<br />

end;<br />

class PGPUser interface<br />

internals<br />

user : GroupUser;<br />

publicKey : Integer;<br />

privateKey : Integer;<br />

methods<br />

setPGPPubKey(i:Integer) returns nil;<br />

getPGPPubKey returns Integer;<br />

setPGPPrivKey(i:Integer) returns nil;<br />

getPGPPrivKey returns Integer;<br />

sendSecureMailTo(aUser : User) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. , user. g;<br />

end;<br />

class PGPUser implementation<br />

initial<br />

begin<br />

publicKey 0;<br />

privateKey 0;<br />

end<br />

methods<br />

setPGPPubKey(i:Integer)<br />

begin<br />

publicKey i;<br />

end<br />

getPGPPubKey<br />

begin<br />

return publicKey;<br />

end<br />

setPGPPrivKey(i:Integer)<br />

(PGPUser.sina)


B.6. Warning2 Mail System 141<br />

begin<br />

privateKey i;<br />

end<br />

getPGPPrivKey<br />

begin<br />

return privateKey;<br />

end<br />

sendSecureMailTo(aUser : User)<br />

temps<br />

aMailMessage : SecureMail;<br />

nonPGPUser : GroupUser;<br />

begin<br />

nonPGPUser.setName('Non PGP User');<br />

nonPGPUser.setGroup(100);<br />

self.setGroup(100);<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Secure Mail Message');<br />

aMailMessage.send;<br />

nonPGPUser.receive(aMailMessage);<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : PGPUser;<br />

u2 : PGPUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendSecureMailTo(u2);<br />

end<br />

B.6 Warning2 Mail System<br />

class Warning2Mail interface<br />

internals<br />

mail : SecureMail;<br />

messageCounter : MCount;<br />

input lters<br />

(SecureMailMain.sina)<br />

(Warning2Mail.sina)


142 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

count : Meta = f<br />

[setMailContents,setMailOriginator,setMailReceiver,send]<br />

messageCounter.warning2Message g;<br />

dis : Dispatch =f inner. , mail. g;<br />

end;<br />

class Warning2Mail implementation<br />

comment<br />

No implementation, warning mechanism is h<strong>and</strong>led by the meta<br />

object.<br />

end;<br />

class Warning2User interface<br />

internals<br />

user : PGPUser;<br />

methods<br />

sendWarning2MailTo(aUser : User) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. , user. g;<br />

end;<br />

class Warning2User implementation<br />

methods<br />

sendWarning2MailTo(aUser : User)<br />

temps<br />

aMailMessage : Warning2Mail;<br />

begin<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Secure Mail Message');<br />

aMailMessage.setMailContents(<br />

'Contents of a Secure Mail Message');<br />

aMailMessage.send;<br />

end;<br />

end;<br />

class MCount interface<br />

internals<br />

counts : Dictionary;<br />

methods<br />

(Warning2User.sina)<br />

(MCount.sina)


B.7. Protected Mail System 143<br />

warning2Message(m:SinaMessage) returns nil;<br />

input lters<br />

dis : Dispatch =f inner. g;<br />

end;<br />

class MCount implementation<br />

methods<br />

warning2Message(m:SinaMessage)<br />

begin<br />

counts.atPut(m.selector,counts.atIfAbsent(m.selector,0) + 1);<br />

if (counts.at(m.selector) > 1)<br />

begin<br />

self.printLine('Warning, message sent more than once');<br />

end;<br />

m.continue;<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : Warning2User;<br />

u2 : Warning2User;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendWarning2MailTo(u2);<br />

end<br />

B.7 Protected Mail System<br />

class ProtectedMail interface<br />

internals<br />

mail : Warning2Mail;<br />

secdoc : SecureDocument;<br />

input lters<br />

err : Error = f securityClearance -> fgetMailContents,<br />

setMailContentsg,<br />

true ;fgetMailContents, setMailContentsg g;<br />

dis : Dispatch =f inner. , mail. , secdoc. g;<br />

end;<br />

class ProtectedMail implementation<br />

(Warning2MailMain.sina)<br />

(ProtectedMail.sina)


144 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong><br />

end;<br />

class ProtectedUser interface<br />

internals<br />

user : Warning2User;<br />

securityLevel : Integer;<br />

methods<br />

getSecurityLevel returns Integer;<br />

setSecurityLevel(i:Integer) returns nil;<br />

sendProtectedMailTo(aUser:User);<br />

inputFilters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class ProtectedUser implementation<br />

initial<br />

begin<br />

securityLevel 0;<br />

end;<br />

methods<br />

getSecurityLevel<br />

begin<br />

return securityLevel;<br />

end;<br />

setSecurityLevel(i:Integer)<br />

begin<br />

securityLevel i;<br />

end;<br />

sendProtectedMailTo(aUser : User)<br />

temps<br />

aMailMessage : ProtectedMail;<br />

begin<br />

aMailMessage.setMailOriginator(self);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setSecurityLevel(3);<br />

aMailMessage.setMailContents(<br />

'Contents of a Protected Mail Message');<br />

aMailMessage.send;<br />

aMailMessage.setSecurityLevel(1);<br />

aMailMessage.send;<br />

end;<br />

end;<br />

(ProtectedUser.sina)<br />

(ProtectedMailMain.sina)


B.7. Protected Mail System 145<br />

main<br />

temps<br />

u1 : PUser;<br />

u2 : PUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u1.setSecurityLevel(4);<br />

u2.setName('MailReceiver');<br />

u2.setSecurityLevel(2);<br />

u1.sendProtectedMailTo(u2);<br />

end


146 Appendix B. Sina Implementation of <strong>Multiple</strong> <strong>Views</strong>


Appendix C<br />

C ++ Implementation of <strong>Layering</strong><br />

C.1 Heading Mail System<br />

De nitions<br />

#ifndef HMAIL H<br />

#define HMAIL H<br />

#include "mail.hpp"<br />

class HUser : public User<br />

f<br />

public:<br />

virtual void receive(Mail );<br />

virtual void sendHeadingMailTo(HUser );<br />

g;<br />

class HeadingMail : public Mail<br />

f<br />

public:<br />

virtual char getMailHeading(void);<br />

virtual char getMailAsText(void);<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include "hmail.hpp"<br />

(hmail.hpp)<br />

(hmail.cc)<br />

147


148 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

void<br />

HUser::receive(Mail m)<br />

f<br />

char s ((HeadingMail )m)!getMailAsText();<br />

cout s "nn";<br />

delete s;<br />

g<br />

void<br />

HUser::sendHeadingMailTo(HUser u)<br />

f<br />

HeadingMail mailMessage new HeadingMail();<br />

mailMessage!setMailOriginator(this);<br />

mailMessage!setMailReceiver(u);<br />

mailMessage!setMailContents(<br />

"Contents of a Heading mail message");<br />

mailMessage!send();<br />

g<br />

char<br />

HeadingMail::getMailHeading(void)<br />

f<br />

char o, r, h, s;<br />

o this!getMailOriginator()!getName();<br />

r this!getMailReceiver()!getName();<br />

h this!getRoute()!getName();<br />

s (char )malloc(strlen(o)+strlen(r)+strlen(h)+31);<br />

sprintf(s,"Sender:ntnt%snnReceiver:nt%snnRoute:ntnt%snn",<br />

o,r,h);<br />

return s;<br />

g<br />

char<br />

HeadingMail::getMailAsText(void)<br />

f<br />

char c, h, r;<br />

c this!getMailContents();<br />

h this!getMailHeading();<br />

r (char )malloc(sizeof(char) (strlen(c)+strlen(h)+1));<br />

strcpy(r,h);<br />

strcat(r,c);<br />

delete h;<br />

return r;


C.2. Attachment Mail System 149<br />

g<br />

#define CALL TEST FUNCTION test heading mail();<br />

void test heading mail(void)<br />

f<br />

cout "Heading Mail testnn";<br />

HUser u1 new HUser();<br />

u1!setName("MailOriginator");<br />

HUser u2 new HUser();<br />

u2!setName("MailReceiver");<br />

u1!sendHeadingMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "mail.cc"<br />

C.2 Attachment Mail System<br />

De nitions<br />

#ifndef AMAIL H<br />

#define AMAIL H<br />

#include "hmail.hpp"<br />

class AUser : public HUser<br />

f<br />

public:<br />

virtual void sendAttachmentMailTo(AUser );<br />

g;<br />

class Attachment<br />

f<br />

public:<br />

Attachment() f lename NULL; g<br />

virtual char getFilename(void) f return lename; g<br />

virtual void setFilename(char s) f lename s; g<br />

private:<br />

char lename;<br />

g;<br />

class AttachmentMail : public HeadingMail<br />

(amail.hpp)


150 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

f<br />

public:<br />

AttachmentMail() f attachment NULL; g<br />

virtual Attachment getMailAttachment(void) f return attachment; g<br />

virtual void setMailAttachment(Attachment a) f attachment a; g<br />

virtual char getMailHeading(void);<br />

private:<br />

Attachment attachment;<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include "amail.hpp"<br />

void<br />

AUser::sendAttachmentMailTo(AUser u)<br />

f<br />

AttachmentMail aMailMessage new AttachmentMail();<br />

Attachment a new Attachment();<br />

a!setFilename(" /attachment.doc");<br />

aMailMessage!setMailOriginator(this);<br />

aMailMessage!setMailReceiver(u);<br />

aMailMessage!setMailContents(<br />

"Contents of an attachment mail message");<br />

aMailMessage!setMailAttachment(a);<br />

aMailMessage!send();<br />

g<br />

char<br />

AttachmentMail::getMailHeading(void)<br />

f<br />

char h, a, s;<br />

h HeadingMail::getMailHeading();<br />

if ( attachment NULL) f<br />

s h;<br />

g else f<br />

a this!getMailAttachment()!getFilename();<br />

(amail.cc)


C.3. ReadNoti cation Mail System 151<br />

g<br />

s (char )malloc(strlen(h)+strlen(a)+14);<br />

sprintf(s,"%sAttachment:nt%snn",h,a);<br />

delete h;<br />

g<br />

return s;<br />

#define CALL TEST FUNCTION test attachment mail();<br />

void test attachment mail(void)<br />

f<br />

cout "Attachment Mail testnn";<br />

AUser u1 new AUser();<br />

u1!setName("MailOriginator");<br />

AUser u2 new AUser();<br />

u2!setName("MailReceiver");<br />

u1!sendAttachmentMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "hmail.cc"<br />

C.3 ReadNoti cation Mail System<br />

De nitions<br />

#ifndef RNMAIL H<br />

#define RNMAIL H<br />

#include "usvmail.hpp"<br />

class RNUser : public MVUser<br />

f<br />

public:<br />

virtual void sendReadNoti cationMailTo(RNUser u);<br />

virtual char className(void) f return "RNUser"; g<br />

g;<br />

class ReadNoti cationMail : public UserSystemViewMail<br />

f<br />

public:<br />

ReadNoti cationMail() f mustNotify 0; noti ed 0; g<br />

virtual void setNotify(int i) f mustNotify i; g<br />

(rnmail.hpp)


152 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

virtual char getMailContents(Object );<br />

protected:<br />

virtual int senderIsReceiverAndMustNotify(Object sender);<br />

virtual int isUserView(Object sender);<br />

virtual void notify(void);<br />

virtual char className(void) f return "ReadNotificationMail"; g<br />

private:<br />

int mustNotify;<br />

int noti ed;<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

#include "rnmail.hpp"<br />

(rnmail.cc)<br />

void<br />

RNUser::sendReadNoti cationMailTo(RNUser u)<br />

f<br />

ReadNoti cationMail mailMessage new ReadNoti cationMail();<br />

mailMessage!setMailOriginator(this,this);<br />

mailMessage!setMailReceiver(this,u);<br />

mailMessage!setMailContents(this,<br />

"Contents of a read notification mail message");<br />

mailMessage!setNotify(1);<br />

mailMessage!send(this);<br />

g<br />

char<br />

ReadNoti cationMail::getMailContents(Object sender)<br />

f<br />

if (this!senderIsReceiverAndMustNotify(sender))<br />

this!notify();<br />

return UserSystemViewMail::getMailContents(sender);<br />

g<br />

int<br />

ReadNoti cationMail::senderIsReceiverAndMustNotify(Object sender)<br />

f<br />

return (this!getMailReceiver(this) sender)<br />

&& mustNotify


C.4. History Mail System 153<br />

g<br />

&& !noti ed;<br />

int<br />

ReadNoti cationMail::isUserView(Object sender)<br />

f<br />

return sender!isKindOf(UserSystemViewMailClass)<br />

jj UserSystemViewMail::isUserView(sender);<br />

g<br />

void<br />

ReadNoti cationMail::notify(void)<br />

f<br />

ReadNoti cationMail m new ReadNoti cationMail();<br />

noti ed 1;<br />

m!setMailOriginator(this,this!getMailReceiver(this));<br />

m!setMailReceiver(this,this!getMailOriginator(this));<br />

m!setMailContents(this,"Read Notification");<br />

m!setNotify(0);<br />

m!send(this);<br />

g<br />

#define CALL TEST FUNCTION test readnoti cation mail();<br />

void test readnoti cation mail(void)<br />

f<br />

cout "Read Notification Mail testnn";<br />

RNUser u1 new RNUser();<br />

u1!setName("MailOriginator");<br />

RNUser u2 new RNUser();<br />

u2!setName("MailReceiver");<br />

u1!sendReadNoti cationMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "usvmail.cc"<br />

C.4 History Mail System<br />

De nitions<br />

#ifndef HISMAIL H<br />

#define HISMAIL H<br />

(hismail.hpp)


154 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

#include "rnmail.hpp"<br />

class HisUser : public RNUser<br />

f<br />

public:<br />

virtual void sendHistoryMailTo(HisUser );<br />

virtual char className(void) f return "HisUser"; g<br />

g;<br />

class HistoryMail : public ReadNoti cationMail<br />

f<br />

public:<br />

HistoryMail() f initMeta(); g<br />

HistoryMail() f closeMeta(); g<br />

virtual void historyReport(void);<br />

virtual void setMailOriginator(Object ,MVUser );<br />

virtual MVUser getMailOriginator(Object );<br />

virtual void setMailReceiver(Object ,MVUser );<br />

virtual MVUser getMailReceiver(Object );<br />

virtual void setMailContents(Object ,char );<br />

virtual char getMailContents(Object );<br />

virtual void send(Object );<br />

virtual void reply(Object );<br />

virtual void approve(Object );<br />

virtual int isApproved(Object );<br />

virtual void setDelivered(Object );<br />

virtual int isDelivered(Object );<br />

virtual void setRoute(Object ,MVMailH<strong>and</strong>ler );<br />

virtual MVMailH<strong>and</strong>ler getRoute(Object );<br />

virtual char className(void) f return "HistoryMail"; g<br />

private:<br />

void initMeta(void) f report NULL; g<br />

void closeMeta(void) f if (report) delete report; g<br />

virtual void doMeta(char selector, Object sender);<br />

char report;<br />

g;<br />

#endif<br />

Implementation<br />

#include <br />

(hismail.cc)


C.4. History Mail System 155<br />

#include <br />

#include <br />

#include <br />

#include "hismail.hpp"<br />

#define MAX(A,B) (A


156 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g<br />

size size = old info = +<br />

strlen(ts) = time info = +<br />

1 = tab = +<br />

MAX(strlen(cs),15) = for sender name = +<br />

1 = tab = +<br />

strlen(selector) +<br />

2 = NL + n0 = ;<br />

s (char )malloc(sizeof(char) size);<br />

sprintf(s,"%s%s %-15s %snn",report,ts,cs,selector);<br />

if (report[0] 6= 0)<br />

delete report;<br />

report s;<br />

void<br />

HistoryMail::setMailOriginator(Object sender,MVUser user)<br />

f<br />

this!doMeta("setMailOriginator",sender);<br />

ReadNoti cationMail::setMailOriginator(sender,user);<br />

g<br />

MVUser<br />

HistoryMail::getMailOriginator(Object sender)<br />

f<br />

this!doMeta("getMailOriginator",sender);<br />

return ReadNoti cationMail::getMailOriginator(sender);<br />

g<br />

void<br />

HistoryMail::setMailReceiver(Object sender,MVUser user)<br />

f<br />

this!doMeta("setMailReceiver",sender);<br />

ReadNoti cationMail::setMailReceiver(sender,user);<br />

g<br />

MVUser<br />

HistoryMail::getMailReceiver(Object sender)<br />

f<br />

this!doMeta("getMailReceiver",sender);<br />

return ReadNoti cationMail::getMailReceiver(sender);<br />

g<br />

void


C.4. History Mail System 157<br />

HistoryMail::setMailContents(Object sender,char s)<br />

f<br />

this!doMeta("setMailContents",sender);<br />

ReadNoti cationMail::setMailContents(sender,s);<br />

g<br />

char<br />

HistoryMail::getMailContents(Object sender)<br />

f<br />

this!doMeta("getMailContents",sender);<br />

return ReadNoti cationMail::getMailContents(sender);<br />

g<br />

void<br />

HistoryMail::send(Object sender)<br />

f<br />

this!doMeta("send",sender);<br />

ReadNoti cationMail::send(sender);<br />

g<br />

void<br />

HistoryMail::reply(Object sender)<br />

f<br />

this!doMeta("reply",sender);<br />

ReadNoti cationMail::reply(sender);<br />

g<br />

void<br />

HistoryMail::approve(Object sender)<br />

f<br />

this!doMeta("approve",sender);<br />

ReadNoti cationMail::approve(sender);<br />

g<br />

int<br />

HistoryMail::isApproved(Object sender)<br />

f<br />

this!doMeta("isApproved",sender);<br />

return ReadNoti cationMail::isApproved(sender);<br />

g<br />

void<br />

HistoryMail::setDelivered(Object sender)<br />

f


158 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g<br />

this!doMeta("setDelivered",sender);<br />

ReadNoti cationMail::setDelivered(sender);<br />

int<br />

HistoryMail::isDelivered(Object sender)<br />

f<br />

this!doMeta("isDelivered",sender);<br />

return ReadNoti cationMail::isDelivered(sender);<br />

g<br />

void<br />

HistoryMail::setRoute(Object sender,MVMailH<strong>and</strong>ler h)<br />

f<br />

this!doMeta("setRoute",sender);<br />

ReadNoti cationMail::setRoute(sender,h);<br />

g<br />

MVMailH<strong>and</strong>ler<br />

HistoryMail::getRoute(Object sender)<br />

f<br />

this!doMeta("getRoute",sender);<br />

return ReadNoti cationMail::getRoute(sender);<br />

g<br />

#define CALL TEST FUNCTION test history mail();<br />

void test history mail(void)<br />

f<br />

cout "History Mail testnn";<br />

HisUser u1 new HisUser();<br />

u1!setName("MailOriginator");<br />

HisUser u2 new HisUser();<br />

u2!setName("MailReceiver");<br />

u1!sendHistoryMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "rnmail.cc"


C.5. Dynamic Mail System 159<br />

C.5 Dynamic Mail System<br />

De nitions<br />

#ifndef DMAIL H<br />

#define DMAIL H<br />

#include "usvmail.hpp"<br />

class MailComponent;<br />

class DynamicMail;<br />

class DUser : public MVUser<br />

f<br />

public:<br />

virtual void receive(MailComponent );<br />

virtual void sendDynamicMailTo(DUser );<br />

virtual char className(void) f return "DUser"; g<br />

g;<br />

class DMailH<strong>and</strong>ler : public MailH<strong>and</strong>ler, public Object<br />

f<br />

public:<br />

virtual int send(MailComponent );<br />

static DMailH<strong>and</strong>ler Instance(void);<br />

virtual char className(void) f return "DMailH<strong>and</strong>ler"; g<br />

protected:<br />

DMailH<strong>and</strong>ler() fg<br />

virtual DMailH<strong>and</strong>ler() fg<br />

static DMailH<strong>and</strong>ler instance;<br />

g;<br />

DMailH<strong>and</strong>ler DMailH<strong>and</strong>ler:: instance (DMailH<strong>and</strong>ler )0;<br />

(dmail.hpp)<br />

class MailComponent :public Object f<br />

public:<br />

virtual void setMailOriginator(MailComponent ,Object ,DUser ) 0;<br />

virtual DUser getMailOriginator(MailComponent ,Object ) 0;<br />

virtual void setMailReceiver(MailComponent ,Object ,DUser ) 0;<br />

virtual DUser getMailReceiver(MailComponent ,Object ) 0;<br />

virtual void setMailContents(MailComponent ,Object ,char ) 0;<br />

virtual char getMailContents(MailComponent ,Object ) 0;<br />

virtual void send(MailComponent ,Object ) 0;<br />

virtual void reply(MailComponent ,Object ) 0;<br />

virtual void approve(MailComponent ,Object ) 0;


160 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g;<br />

virtual int isApproved(MailComponent ,Object ) 0;<br />

virtual void setDelivered(MailComponent ,Object ) 0;<br />

virtual int isDelivered(MailComponent ,Object ) 0;<br />

virtual void setRoute(MailComponent ,Object ,DMailH<strong>and</strong>ler ) 0;<br />

virtual DMailH<strong>and</strong>ler getRoute(MailComponent ,Object ) 0;<br />

virtual char className(void) f return "MailComponent"; g<br />

virtual void historyReport(void) fg;<br />

class DynamicMail : public MailComponent f<br />

public:<br />

DynamicMail();<br />

virtual DynamicMail();<br />

virtual void setMailOriginator(MailComponent ,Object ,DUser );<br />

virtual DUser getMailOriginator(MailComponent ,Object );<br />

virtual void setMailReceiver(MailComponent ,Object ,DUser );<br />

virtual DUser getMailReceiver(MailComponent ,Object );<br />

virtual void setMailContents(MailComponent ,Object ,char );<br />

virtual char getMailContents(MailComponent ,Object );<br />

virtual void send(MailComponent ,Object );<br />

virtual void reply(MailComponent ,Object );<br />

virtual void approve(MailComponent ,Object );<br />

virtual int isApproved(MailComponent ,Object );<br />

virtual void setDelivered(MailComponent ,Object );<br />

virtual int isDelivered(MailComponent ,Object );<br />

virtual void setRoute(MailComponent ,Object ,DMailH<strong>and</strong>ler );<br />

virtual DMailH<strong>and</strong>ler getRoute(MailComponent ,Object );<br />

virtual char className(void) f return "DynamicMail"; g<br />

private:<br />

Mail mail;<br />

g;<br />

class MailDecorator : public MailComponent f<br />

public:<br />

MailDecorator(MailComponent p) f component p; g<br />

virtual void setMailOriginator(MailComponent svr,Object o,DUser u)<br />

f<br />

component!setMailOriginator((svr?svr:this),o,u);<br />

g<br />

virtual DUser getMailOriginator(MailComponent svr,Object o) f<br />

return component!getMailOriginator((svr?svr:this),o);<br />

g<br />

virtual void setMailReceiver(MailComponent svr,Object o,DUser u) f<br />

component!setMailReceiver((svr?svr:this),o,u);


C.5. Dynamic Mail System 161<br />

f<br />

g<br />

virtual DUser getMailReceiver(MailComponent svr,Object o) f<br />

return component!getMailReceiver((svr?svr:this),o);<br />

g<br />

virtual void setMailContents(MailComponent svr,Object o,char s) f<br />

component!setMailContents((svr?svr:this),o,s);<br />

g<br />

virtual char getMailContents(MailComponent svr,Object o) f<br />

return component!getMailContents((svr?svr:this),o);<br />

g<br />

virtual void send(MailComponent svr,Object o) f<br />

component!send((svr?svr:this),o);<br />

g<br />

virtual void reply(MailComponent svr,Object o) f<br />

component!reply((svr?svr:this),o);<br />

g<br />

virtual void approve(MailComponent svr,Object o) f<br />

component!approve((svr?svr:this),o);<br />

g<br />

virtual int isApproved(MailComponent svr,Object o) f<br />

return component!isApproved((svr?svr:this),o);<br />

g<br />

virtual void setDelivered(MailComponent svr,Object o) f<br />

component!setDelivered((svr?svr:this),o);<br />

g<br />

virtual int isDelivered(MailComponent svr,Object o) f<br />

return component!isDelivered((svr?svr:this),o);<br />

g<br />

virtual void setRoute(MailComponent svr,Object o,DMailH<strong>and</strong>ler h)<br />

component!setRoute((svr?svr:this),o,h);<br />

g<br />

virtual DMailH<strong>and</strong>ler getRoute(MailComponent svr,Object o) f<br />

return component!getRoute((svr?svr:this),o);<br />

g<br />

virtual void historyReport(void) f<br />

component!historyReport();<br />

g<br />

virtual char className(void) f return "MailDecorator"; g<br />

private:<br />

MailComponent component;<br />

g;<br />

class MailReadNoti er : public MailDecorator f


162 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

public:<br />

MailReadNoti er(MailComponent d):MailDecorator(d) f noti ed 0; g<br />

virtual char getMailContents(MailComponent ,Object );<br />

virtual char className(void) f return "MailReadNotifier"; g<br />

protected:<br />

virtual int senderIsReceiverAndMustNotify(<br />

MailComponent ,Object sender);<br />

virtual void notify(MailComponent );<br />

private:<br />

int noti ed;<br />

g;<br />

class MailHistory : public MailDecorator f<br />

public:<br />

MailHistory(MailComponent d):MailDecorator(d) f initMeta(); g<br />

virtual MailHistory() f closeMeta(); g<br />

virtual void historyReport(void);<br />

virtual void setMailOriginator(MailComponent ,Object ,DUser );<br />

virtual DUser getMailOriginator(MailComponent ,Object );<br />

virtual void setMailReceiver(MailComponent ,Object ,DUser );<br />

virtual DUser getMailReceiver(MailComponent ,Object );<br />

virtual void setMailContents(MailComponent ,Object ,char );<br />

virtual char getMailContents(MailComponent ,Object );<br />

virtual void send(MailComponent ,Object );<br />

virtual void reply(MailComponent ,Object );<br />

virtual void approve(MailComponent ,Object );<br />

virtual int isApproved(MailComponent ,Object );<br />

virtual void setDelivered(MailComponent ,Object );<br />

virtual int isDelivered(MailComponent ,Object );<br />

virtual void setRoute(MailComponent ,Object ,DMailH<strong>and</strong>ler );<br />

virtual DMailH<strong>and</strong>ler getRoute(MailComponent ,Object );<br />

virtual char className(void) f return "MailHistory"; g<br />

private:<br />

virtual void initMeta(void) f report NULL; g<br />

virtual void closeMeta(void) f if (report) delete report; g<br />

virtual void doMeta(char selector, Object sender);<br />

char report;<br />

g;<br />

#endif<br />

Implementation<br />

(dmail.cc)


C.5. Dynamic Mail System 163<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#include "dmail.hpp"<br />

#define MAX(A,B) (A


164 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g<br />

instance!setName("The Only DMailH<strong>and</strong>ler");<br />

g<br />

return (DMailH<strong>and</strong>ler ) instance;<br />

int<br />

DMailH<strong>and</strong>ler::send(MailComponent m)<br />

f<br />

if (m!getMailReceiver(0,this) 6= (DUser )0) f<br />

m!approve(0,this);<br />

g<br />

if (m!isApproved(0,this)) f<br />

m!setRoute(0,this,this);<br />

m!setDelivered(0,this);<br />

m!getMailReceiver(0,this)!receive(m);<br />

return 0;<br />

g else f<br />

return -1;<br />

g<br />

g<br />

DynamicMail::DynamicMail()<br />

f<br />

mail new Mail();<br />

assert( mail 6= (Mail )0);<br />

g<br />

DynamicMail:: DynamicMail()<br />

f<br />

delete mail;<br />

g<br />

void<br />

DynamicMail::setMailOriginator(MailComponent svr,<br />

Object sender,<br />

DUser u)<br />

f<br />

mail!setMailOriginator(u);<br />

g<br />

DUser<br />

DynamicMail::getMailOriginator(MailComponent svr,Object sender)<br />

f<br />

return (DUser ) mail!getMailOriginator();


C.5. Dynamic Mail System 165<br />

g<br />

void<br />

DynamicMail::setMailReceiver(MailComponent svr,<br />

Object sender,<br />

DUser u)<br />

f<br />

mail!setMailReceiver(u);<br />

g<br />

DUser<br />

DynamicMail::getMailReceiver(MailComponent svr,Object sender)<br />

f<br />

return (DUser ) mail!getMailReceiver();<br />

g<br />

void<br />

DynamicMail::setMailContents(MailComponent svr,Object sender,char s)<br />

f<br />

mail!setMailContents(s);<br />

g<br />

char<br />

DynamicMail::getMailContents(MailComponent svr,Object sender)<br />

f<br />

return mail!getMailContents();<br />

g<br />

void<br />

DynamicMail::send(MailComponent svr,Object sender)<br />

f<br />

DMailH<strong>and</strong>ler::Instance()!send((svr?svr:this));<br />

g<br />

void<br />

DynamicMail::reply(MailComponent svr,Object sender)<br />

f<br />

mail!reply();<br />

g<br />

void<br />

DynamicMail::approve(MailComponent svr,Object sender)<br />

f<br />

mail!approve();


166 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g<br />

int<br />

DynamicMail::isApproved(MailComponent svr,Object sender)<br />

f<br />

return mail!isApproved();<br />

g<br />

void<br />

DynamicMail::setDelivered(MailComponent svr,Object sender)<br />

f<br />

mail!setDelivered();<br />

g<br />

int<br />

DynamicMail::isDelivered(MailComponent svr,Object sender)<br />

f<br />

return mail!isDelivered();<br />

g<br />

void<br />

DynamicMail::setRoute(MailComponent svr,<br />

Object sender,<br />

DMailH<strong>and</strong>ler mh)<br />

f<br />

mail!setRoute(mh);<br />

g<br />

DMailH<strong>and</strong>ler<br />

DynamicMail::getRoute(MailComponent svr,Object sender)<br />

f<br />

return (DMailH<strong>and</strong>ler ) mail!getRoute();<br />

g<br />

char<br />

MailReadNoti er::getMailContents(MailComponent svr,Object sender)<br />

f<br />

if (this!senderIsReceiverAndMustNotify(svr?svr:this,sender))<br />

this!notify(svr?svr:this);<br />

return MailDecorator::getMailContents(svr?svr:this,sender);<br />

g<br />

int<br />

MailReadNoti er::


C.5. Dynamic Mail System 167<br />

senderIsReceiverAndMustNotify(MailComponent svr,<br />

Object sender)<br />

f<br />

return (this!getMailReceiver(svr,this) sender) && !noti ed;<br />

g<br />

void<br />

MailReadNoti er::notify(MailComponent svr)<br />

f<br />

DynamicMail m new DynamicMail();<br />

noti ed 1;<br />

m!setMailOriginator(0,svr,svr!getMailReceiver(0,svr));<br />

m!setMailReceiver(0,svr,svr!getMailOriginator(0,svr));<br />

m!setMailContents(0,svr,"Read Notification");<br />

m!send(0,svr);<br />

g<br />

void<br />

MailHistory::historyReport(void)<br />

f<br />

if (report)<br />

cout report;<br />

else<br />

cout "No report information";<br />

g<br />

void<br />

MailHistory::doMeta(char selector,Object sender)<br />

f<br />

char s, ts, cs;<br />

int size;<br />

time tt;<br />

if (!report)<br />

report "";<br />

size strlen(report);<br />

t time(NULL);<br />

ts ctime(&t);<br />

ts[strlen(ts)-1] 0; = remove NL =<br />

cs sender!asString();<br />

size size = old info = +<br />

strlen(ts) = time info = +


168 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

g<br />

1 = tab = +<br />

MAX(strlen(cs),15) = for sender name = +<br />

1 = tab = +<br />

strlen(selector) +<br />

2 = NL + n0 = ;<br />

s (char )malloc(sizeof(char) size);<br />

sprintf(s,"%s%s %-15s %snn",report,ts,cs,selector);<br />

if (report[0] 6= 0)<br />

delete report;<br />

report s;<br />

void<br />

MailHistory::setMailOriginator(MailComponent svr,<br />

Object sender,<br />

DUser user)<br />

f<br />

this!doMeta("setMailOriginator",sender);<br />

MailDecorator::setMailOriginator(svr,sender,user);<br />

g<br />

DUser<br />

MailHistory::getMailOriginator(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("getMailOriginator",sender);<br />

return MailDecorator::getMailOriginator(svr,sender);<br />

g<br />

void<br />

MailHistory::setMailReceiver(MailComponent svr,<br />

Object sender,<br />

DUser user)<br />

f<br />

this!doMeta("setMailReceiver",sender);<br />

MailDecorator::setMailReceiver(svr,sender,user);<br />

g<br />

DUser<br />

MailHistory::getMailReceiver(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("getMailReceiver",sender);<br />

return MailDecorator::getMailReceiver(svr,sender);<br />

g


C.5. Dynamic Mail System 169<br />

void<br />

MailHistory::setMailContents(MailComponent svr,Object sender,char s)<br />

f<br />

this!doMeta("setMailContents",sender);<br />

MailDecorator::setMailContents(svr,sender,s);<br />

g<br />

char<br />

MailHistory::getMailContents(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("getMailContents",sender);<br />

return MailDecorator::getMailContents(svr,sender);<br />

g<br />

void<br />

MailHistory::send(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("send",sender);<br />

MailDecorator::send(svr,sender);<br />

g<br />

void<br />

MailHistory::reply(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("reply",sender);<br />

MailDecorator::reply(svr,sender);<br />

g<br />

void<br />

MailHistory::approve(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("approve",sender);<br />

MailDecorator::approve(svr,sender);<br />

g<br />

int<br />

MailHistory::isApproved(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("isApproved",sender);<br />

return MailDecorator::isApproved(svr,sender);<br />

g<br />

void


170 Appendix C. C ++ Implementation of <strong>Layering</strong><br />

MailHistory::setDelivered(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("setDelivered",sender);<br />

MailDecorator::setDelivered(svr,sender);<br />

g<br />

int<br />

MailHistory::isDelivered(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("isDelivered",sender);<br />

return MailDecorator::isDelivered(svr,sender);<br />

g<br />

void<br />

MailHistory::setRoute(MailComponent svr,Object sender,DMailH<strong>and</strong>ler h)<br />

f<br />

this!doMeta("setRoute",sender);<br />

MailDecorator::setRoute(svr,sender,h);<br />

g<br />

DMailH<strong>and</strong>ler<br />

MailHistory::getRoute(MailComponent svr,Object sender)<br />

f<br />

this!doMeta("getRoute",sender);<br />

return MailDecorator::getRoute(svr,sender);<br />

g<br />

#define CALL TEST FUNCTION test dynamic mail();<br />

void test dynamic mail(void)<br />

f<br />

cout "Dynamic Mail testnn";<br />

DUser u1 new DUser();<br />

u1!setName("MailOriginator");<br />

DUser u2 new DUser();<br />

u2!setName("MailReceiver");<br />

u1!sendDynamicMailTo(u2);<br />

g<br />

#include "main.inc"<br />

#include "usvmail.cc"


Appendix D<br />

Sina Implementation of <strong>Layering</strong><br />

D.1 Heading Mail System<br />

class HUser interface<br />

internals<br />

user : User;<br />

methods<br />

receive(aMail : Mail) returns nil;<br />

sendHeadingMailTo(aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class HUser implementation<br />

methods<br />

receive(aMail : Mail)<br />

begin<br />

server.printLine(aMail.getMailAsText);<br />

end;<br />

sendHeadingMailTo(aUser : User)<br />

temps<br />

aMailMessage : HeadingMail;<br />

begin<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Heading mail message');<br />

aMailMessage.send;<br />

end;<br />

end;<br />

#NoDefSyncFilter;<br />

(HUser.sina)<br />

(HeadingMail.sina)<br />

171


172 Appendix D. Sina Implementation of <strong>Layering</strong><br />

class HeadingMail interface<br />

internals<br />

mail : Mail;<br />

methods<br />

getMailHeading returns String;<br />

getMailAsText returns String;<br />

input lters<br />

disp : Dispatch =f inner. , mail. g;<br />

end;<br />

class HeadingMail implementation<br />

methods<br />

getMailHeading<br />

begin<br />

return 'Sender:<br />

'.copyAppend:(server.getMailOriginator.getName<br />

).copyAppend:('<br />

Receiver: '<br />

).copyAppend:(server.getMailReceiver.getName<br />

).copyAppend:('<br />

Route: '<br />

).copyAppend:(server.getRoute.getName);<br />

end;<br />

getMailAsText<br />

begin<br />

return server.getMailHeading.copyAppend:('<br />

').copyAppend:(server.getMailContents);<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : HUser;<br />

u2 : HUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendHeadingMailTo(u2);<br />

end<br />

D.2 Attachment Mail System<br />

(HeadingMailMain.sina)<br />

(Attachment.sina)


D.2. Attachment Mail System 173<br />

class Attachment interface<br />

methods<br />

setFilename(aName : String) returns nil;<br />

getFilename returns String;<br />

input lters<br />

disp : Dispatch =f inner. g;<br />

end;<br />

class Attachment implementation<br />

instvars<br />

lename : String;<br />

initial<br />

begin<br />

lename 'NoName';<br />

end;<br />

methods<br />

setFilename(aName : String)<br />

begin<br />

lename aName;<br />

end;<br />

getFilename<br />

begin<br />

return lename;<br />

end;<br />

end;<br />

class AUser interface<br />

internals<br />

user : HUser;<br />

methods<br />

sendAttachmentMailTo(aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class AUser implementation<br />

methods<br />

sendAttachmentMailTo(aUser : User)<br />

temps<br />

aMailMessage : AttachmentMail;<br />

attachment :Attachment;<br />

begin<br />

attachment.setFilename(' /attachment.doc');<br />

(AUser.sina)


174 Appendix D. Sina Implementation of <strong>Layering</strong><br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of an attachment mail message');<br />

aMailMessage.setMailAttachment(attachment);<br />

aMailMessage.send;<br />

end;<br />

end;<br />

(AttachmentMail.sina)<br />

class AttachmentMail interface<br />

internals<br />

mail : HeadingMail;<br />

conditions<br />

noAttachment;<br />

methods<br />

setMailAttachment(anAttachment :Attachment) returns nil;<br />

getMailAttachment returns Attachment;<br />

getMailHeading returns String;<br />

input lters<br />

skip : Dispatch =f<br />

noAttachment)[getMailHeading]mail.getMailHeading g;<br />

disp : Dispatch =f inner. , mail. g;<br />

end;<br />

class AttachmentMail implementation<br />

instvars<br />

attachment :Attachment;<br />

conditions<br />

noAttachment<br />

begin<br />

return attachment =nil;<br />

end;<br />

initial<br />

begin<br />

attachment nil;<br />

end;<br />

methods<br />

setMailAttachment(anAttachment :Attachment)<br />

begin<br />

attachment anAttachment;<br />

end;<br />

getMailAttachment<br />

begin


D.3. ReadNoti cation Mail System 175<br />

return attachment;<br />

end;<br />

getMailHeading<br />

begin<br />

return mail.getMailHeading.copyAppend:('<br />

Attachment: ').copyAppend:(server.getMailAttachment.getFilename);<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : AUser;<br />

u2 : AUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendAttachmentMailTo(u2);<br />

end<br />

D.3 ReadNoti cation Mail System<br />

class RNUser interface<br />

internals<br />

user : AUser;<br />

methods<br />

sendReadNoti cationMailTo(aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

(AttachmentMailMain.sina)<br />

(RNUser.sina)<br />

class RNUser implementation<br />

methods<br />

sendReadNoti cationMailTo(aUser : User)<br />

temps<br />

aMailMessage : ReadNoti cationMail;<br />

begin<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a read notification mail message');<br />

aMailMessage.setNotify(true);<br />

aMailMessage.send;


176 Appendix D. Sina Implementation of <strong>Layering</strong><br />

end;<br />

end;<br />

class Noti er interface<br />

conditions<br />

done;<br />

methods<br />

setNotify(aBool : Boolean) returns nil;<br />

notify(aMessage : SinaMessage) returns nil;<br />

skipNotify(aMessage : SinaMessage) returns nil;<br />

input lters<br />

disp : Dispatch =f done)[notify]inner.skipNotify, inner. g;<br />

end;<br />

class Noti er implementation<br />

instvars<br />

mustNotify : Boolean;<br />

noti ed : Boolean;<br />

conditions<br />

done<br />

begin<br />

return (noti ed jj mustNotify.not);<br />

end;<br />

initial<br />

begin<br />

mustNotify false;<br />

noti ed false;<br />

end;<br />

methods<br />

skipNotify(aMessage : SinaMessage)<br />

begin<br />

aMessage.continue;<br />

end;<br />

setNotify(aBool : Boolean)<br />

begin<br />

mustNotify aBool;<br />

end;<br />

notify(aMessage : SinaMessage)<br />

temps<br />

aMailMessage : ReadNoti cationMail;<br />

begin<br />

noti ed true;<br />

aMessage.continue;<br />

(Noti er.sina)


D.3. ReadNoti cation Mail System 177<br />

aMailMessage.setMailOriginator(<br />

aMessage.receiver.getMailReceiver);<br />

aMailMessage.setMailReceiver(<br />

aMessage.receiver.getMailOriginator);<br />

aMailMessage.setMailContents('Read Notification');<br />

aMailMessage.setNotify(false);<br />

aMailMessage.send;<br />

end;<br />

end;<br />

(ReadNoti cationMail.sina)<br />

#NoDefSyncFilter;<br />

class ReadNoti cationMail interface<br />

internals<br />

mail : AttachmentMail;<br />

noti er : Noti er;<br />

conditions<br />

senderIsReceiver;<br />

input lters<br />

meta : Meta = f senderIsReceiver)[getMailContents]noti er.notify g;<br />

disp : Dispatch =f inner. , noti er.setNotify, mail. g;<br />

end;<br />

class ReadNoti cationMail implementation<br />

conditions<br />

senderIsReceiver<br />

begin<br />

return true; == mail.getMailReceiver = message.sender;<br />

== Compiler bug prevents correct evaluation of above<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : RNUser;<br />

u2 : RNUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendReadNoti cationMailTo(u2);<br />

end<br />

(ReadNoti cationMailMain.sina)


178 Appendix D. Sina Implementation of <strong>Layering</strong><br />

D.4 History Mail System<br />

class HisUser interface<br />

internals<br />

user : RNUser;<br />

methods<br />

sendHistoryMailTo(aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class HisUser implementation<br />

methods<br />

sendHistoryMailTo(aUser : User)<br />

temps<br />

aMailMessage : HistoryMail;<br />

begin<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a history mail message');<br />

aMailMessage.send;<br />

aMailMessage.historyReport;<br />

end;<br />

end;<br />

class HistoryReporter interface<br />

externals<br />

Time : Class;<br />

methods<br />

saveHistory(aMessage : SinaMessage) returns nil;<br />

historyReport returns nil;<br />

input lters<br />

disp : Dispatch =f inner. g;<br />

end;<br />

class HistoryReporter implementation<br />

instvars<br />

report : String;<br />

initial<br />

begin<br />

report nil;<br />

end;<br />

(HisUser.sina)<br />

(HistoryReporter.sina)


D.4. History Mail System 179<br />

methods<br />

saveHistory(aMessage : SinaMessage)<br />

begin<br />

if report = nil<br />

then<br />

report '';<br />

end;<br />

report report.copyAppend:(Time.dateAndTimeNow.printString<br />

).copyAppend:(' '<br />

).copyAppend:(aMessage.sender.toString<br />

).copyAppend:(' '<br />

).copyAppend:(aMessage.selector).copyAppend:('<br />

');<br />

aMessage.continue;<br />

end;<br />

historyReport<br />

begin<br />

if report = nil<br />

then<br />

server.print('No report information');<br />

else<br />

server.print(report);<br />

end;<br />

end;<br />

end;<br />

class HistoryMail interface<br />

internals<br />

mail : ReadNoti cationMail;<br />

history : HistoryReporter;<br />

input lters<br />

meta : Meta = f [ ]history.saveHistory g;<br />

disp : Dispatch =f history.historyReport, mail. g;<br />

end;<br />

class HistoryMail implementation<br />

end;<br />

main<br />

temps<br />

u1 : HisUser;<br />

u2 : HisUser;<br />

begin<br />

(HistoryMail.sina)<br />

(HistoryMailMain.sina)


180 Appendix D. Sina Implementation of <strong>Layering</strong><br />

end<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendHistoryMailTo(u2);<br />

D.5 Dynamic Mail System<br />

class DUser interface<br />

internals<br />

user : User;<br />

methods<br />

sendDynamicMailTo(aUser : User) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , user. g;<br />

end;<br />

class DUser implementation<br />

methods<br />

sendDynamicMailTo(aUser : User)<br />

temps<br />

aMailMessage : DynamicMail;<br />

aHistory : HistoryProperty;<br />

aReadNot : MailReadNoti er;<br />

begin<br />

aMailMessage.addML(aReadNot);<br />

aMailMessage.addML(aHistory);<br />

aMailMessage.setMailOriginator(server);<br />

aMailMessage.setMailReceiver(aUser);<br />

aMailMessage.setMailContents(<br />

'Contents of a Dynamic Mail Message');<br />

aMailMessage.send;<br />

aMailMessage.historyReport;<br />

end;<br />

end;<br />

class BasicDL interface<br />

comment<br />

'This class provides the basic protocol for dynamic<br />

layering';<br />

internals<br />

ol : SinaObject; == For Object level layering<br />

ml : SinaObject; == For Meta level layering<br />

(DUser.sina)<br />

(BasicDL.sina)


D.5. Dynamic Mail System 181<br />

conditions<br />

isCascaded; == OL is lled<br />

isMeta; == ML is lled<br />

methods<br />

addOL(object : BasicDL) returns nil;<br />

addML(object : BasicDL) returns nil;<br />

process(aMessage : SinaMessage) returns nil;<br />

input lters<br />

== addML <strong>and</strong> addOL must be used in the top-level<br />

== because adding an object layer disables inner.<br />

d : Dispatch =f isMeta)[process]ml.process,<br />

true)f inner.addML, inner.addOL g,<br />

isCascaded)ol. ,<br />

isMeta)ml. ,<br />

true)inner.process g;<br />

end;<br />

class BasicDL implementation<br />

instvars<br />

cascaded : Boolean;<br />

meta : Boolean;<br />

conditions<br />

isCascaded<br />

begin<br />

return cascaded;<br />

end;<br />

isMeta<br />

begin<br />

return meta;<br />

end;<br />

initial<br />

begin<br />

cascaded false;<br />

meta false;<br />

end;<br />

methods<br />

addOL(object : BasicDL)<br />

begin<br />

if cascaded<br />

then<br />

object.addOL(ol);<br />

end;<br />

ol object;<br />

cascaded true;


182 Appendix D. Sina Implementation of <strong>Layering</strong><br />

end;<br />

addML(object : BasicDL)<br />

begin<br />

if meta<br />

then<br />

object.addOL(mop);<br />

end;<br />

ml object;<br />

meta true;<br />

end;<br />

process(aMessage : SinaMessage)<br />

begin<br />

aMessage.continue;<br />

end;<br />

end;<br />

class DynamicMail interface<br />

internals<br />

layers : BasicDL;<br />

mail : Mail;<br />

input lters<br />

meta : Meta = f [ ]layers.process g;<br />

dis : Dispatch =f layers. , mail. g;<br />

end;<br />

class DynamicMail implementation<br />

end;<br />

(DynamicMail.sina)<br />

(MailReadNoti er.sina)<br />

class MailReadNoti er interface<br />

internals<br />

basics : BasicDL;<br />

conditions<br />

notYetNoti ed;<br />

methods<br />

process (aMessage : SinaMessage) returns nil;<br />

input lters<br />

disp : Dispatch =f notYetNoti ed)inner. , true)basics. g;<br />

end;<br />

class MailReadNoti er implementation<br />

instvars<br />

noti ed : Boolean;


D.5. Dynamic Mail System 183<br />

conditions<br />

notYetNoti ed<br />

begin<br />

return !noti ed;<br />

end;<br />

initial<br />

begin<br />

noti ed false;<br />

end;<br />

methods<br />

process<br />

temps<br />

aMailMessage : DynamicMail;<br />

begin<br />

if aMessage.sender = aMessage.server.getMailReceiver<br />

&& aMessage.selector = 'getMailContents'<br />

then<br />

noti ed true;<br />

aMailMessage.setMailOriginator(<br />

aMessage.receiver.getMailReceiver);<br />

aMailMessage.setMailReceiver(<br />

aMessage.receiver.getMailOriginator);<br />

aMailMessage.setMailContents('Read Notification');<br />

aMailMessage.send;<br />

end<br />

basics.process(aMessage);<br />

end;<br />

end;<br />

(HistoryProperty.sina)<br />

class HistoryProperty interface<br />

internals<br />

basics : BasicDL;<br />

oldReporter : HistoryReporter;<br />

methods<br />

process(aMessage : SinaMessage) returns nil;<br />

input lters<br />

disp : Dispatch =f inner. , oldReporter.historyReport, basics. g;<br />

end;<br />

class HistoryProperty implementation<br />

instvars<br />

methods<br />

process(aMessage : SinaMessage)


184 Appendix D. Sina Implementation of <strong>Layering</strong><br />

begin<br />

oldReporter.saveHistory(aMessage);<br />

basics.process(aMessage);<br />

end;<br />

end;<br />

main<br />

temps<br />

u1 : DUser;<br />

u2 : DUser;<br />

begin<br />

u1.setName('MailOriginator');<br />

u2.setName('MailReceiver');<br />

u1.sendDynamicMailTo(u2);<br />

end<br />

(DynamicMailMain.sina)


Bibliography<br />

Aksit, M. <strong>and</strong> Bergmans, L.: 1992, Obstacles in object-oriented software development,<br />

in Paepcke (1992), pp. 341{358. ISSN 0362-1340, ISBN 0-201-<br />

53372-3.<br />

Aksit, M., Bergmans, L. <strong>and</strong> Vural, S.: 1992, An object-oriented languagedatabase<br />

integration model: The composition- lters approach, in Madsen<br />

(1992), pp. 372{395. ISBN 0-387-55668-0 / ISBN 3-540-55668-0.<br />

Aksit, M. <strong>and</strong> Bosch, J.: 1994, Issues in Object-Oriented Real-Time Language<br />

Design, in Halang <strong>and</strong> Stoyenko (1994), pp. 510{511. ISBN 3-540-57558-8,<br />

ISBN 0-387-57558-8, Proceedings of the NATO Advanced Study Institute<br />

on Real Time Computing, held in Sint Maarten, Dutch Antilles, October<br />

5{17, 1992.<br />

Aksit, M., Bosch, J., van der Sterren, W. <strong>and</strong> Bergmans, L.: 1994, Real-time<br />

speci cation inheritance anomalies <strong>and</strong> real-time lters, in Tokoro <strong>and</strong><br />

Pareschi (1994), pp. 386{407. ISBN 0-387-58202-9 / ISBN 3-540-58202-9.<br />

Aksit, M., Wakita, K., Bosch, J., Bergmans, L. <strong>and</strong> Yonezawa, A.: 1993, Abstracting<br />

object interactions using composition lters, in Guerraoui, Nierstrasz<br />

<strong>and</strong> Riveill (1993), pp. 152{184. ISBN 0-387-57932-X / ISBN 3-540-<br />

57932-X.<br />

Alex<strong>and</strong>er, C.: 1977, A Pattern Language, Oxford University Press.<br />

Algra, E.: 1994, Process programming <strong>and</strong> learning domains in object oriented<br />

hermeneutic software development, M.Sc. thesis, University of Twente,<br />

Dept. of Computer Science, P.O. box 217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Describes a framework <strong>and</strong> its specialisation for the HOOSD tool.<br />

Bergmans, L.: 1994, Composing Concurrent <strong>Objects</strong>, Ph.D. dissertation, University<br />

of Twente, Dept. of Computer Science, P.O. box 217, 7500 AE,<br />

Enschede, The Netherl<strong>and</strong>s. ISBN 90-9007359-0.<br />

Black, U. D.: 1991, OSI: a Model for Computer Communications St<strong>and</strong>ards,<br />

Prentice Hall. ISBN 0-13-637133-7.<br />

Bosch, J.: 1995, Language support for design patterns.<br />

*http://www.pt.hk-r.se/~bosch/despat.ps.Z<br />

Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P. <strong>and</strong> Stal, M.: 1996,<br />

Pattern-Oriented Software Architecture | A System of Patterns, John<br />

Wiley & Sons Ltd., Ba ns Lane, Chichester, West Sussex PO19 1UD,<br />

Engl<strong>and</strong>. ISBN 0-471-95869-7.<br />

185


186 Bibliography<br />

Ellis, M. A. <strong>and</strong> Stroustrup, B.: 1990, The Annotated C++ Reference Manual,<br />

Addison-Wesley Publishing Company, Reading, Massachusetts. ISBN 0-<br />

201-51459-1.<br />

Eur: 1997, Proceedings of the ECOOP '97, number 1241 in Lecture Notes in<br />

Computer Science, Springer-Verlag, Berlin Heidelberg.<br />

Ferber, J.: 1989, Computational re ection in class based object oriented languages,<br />

in Meyrowitz (1989), pp. 317{326. ISBN 0-0201-52249-7, ISSN<br />

0362-1340.<br />

Florijn, G., Meijers, M. <strong>and</strong> van Winsen, P.: 1997, Tool support for object<br />

oriented patterns, in Proceedings of the ECOOP '97 (Eur 1997), pp. 472{<br />

495.<br />

Gamma, E., Helm, R., Johnson, R. <strong>and</strong> Vlissides, J.: 1995, Design Patterns:<br />

Elements of Reusable Object-Oriented Software, Professional computing<br />

series, Addison-Wesley, Reading, MA. ISBN 0-201-63361-2.<br />

Gl<strong>and</strong>rup, M.: 1995, Extending c++ using the concepts of composition lters,<br />

M.Sc. thesis, University ofTwente, Dept. of Computer Science, P.O. box<br />

217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Guerraoui, R., Nierstrasz, O. <strong>and</strong> Riveill, M. (eds): 1993, ECOOP '93, Workshop<br />

on Object-Based Distributed Programming, number 791 in Lecture<br />

Notes in Computer Science, European Conference on Object-Oriented<br />

Programming, Springer-Verlag, Berlin Heidelberg. ISBN 0-387-57932-X<br />

/ ISBN 3-540-57932-X.<br />

Halang, W. A. <strong>and</strong> Stoyenko, A. D. (eds): 1994, Real Time Computing, Vol. 127<br />

of NATO ASI Series F: Computer <strong>and</strong> System Sciences, NATO Advanced<br />

Science Institutes, Springer-Verlag, Berlin, Heidelberg, New York. ISBN<br />

3-540-57558-8, ISBN 0-387-57558-8, Proceedings of the NATO Advanced<br />

Study Institute on Real Time Computing, held in Sint Maarten, Dutch<br />

Antilles, October 5{17, 1992.<br />

Helm, R., Holl<strong>and</strong>, I. M. <strong>and</strong> Gangopadhyay, D.: 1990, Contracts: Specifying<br />

behavioural compositions in object-oriented systems, Proceedings OOP-<br />

SLA/ECOOP '90, ACM SIGPLAN Notices, pp. 169{180. Published as<br />

Proceedings OOPSLA/ECOOP '90, ACM SIGPLAN Notices, volume 25,<br />

number 10.<br />

Johnson, R. E. <strong>and</strong> Foote, B.: 1988, Designing reusable classes, Journal of<br />

Object-Oriented Programming pp. 22{35.<br />

Koehorst, H.: 1994, De ning artifacts of prepatory work in hermeneutic objectoriented<br />

software development, M.Sc. thesis, University of Twente, Dept.<br />

of Computer Science, P.O. box 217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Describes an aspect of the HOOSD tool.<br />

Koopmans, P.: 1996, Sina/st | User's Guide <strong>and</strong> Reference Manual for Sina<br />

version 3.1, University of Twente, Dept. of Computer Science, P.O. box<br />

217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Lieberherr, K. J. <strong>and</strong> Holl<strong>and</strong>, I. M.: 1989, Assuring good style for objectoriented<br />

programs, IEEE Software pp. 38{48.


Bibliography 187<br />

Lieberman, H.: 1986, Using prototypical objects to implement shared behavior<br />

in object oriented systems, in Meyrowitz (1986), pp. 214{223. ISBN 0-<br />

89791-204-7.<br />

Madsen, O. L. (ed.): 1992, ECOOP '92, European Conference on Object-<br />

Oriented Programming, number 615 in Lecture Notes in Computer Science,<br />

European Conference on Object-Oriented Programming, Springer-Verlag,<br />

Berlin Heidelberg. ISBN 0-387-55668-0 / ISBN 3-540-55668-0.<br />

Meyrowitz, N. (ed.): 1986, OOPSLA '86 Conference Proceedings, Vol. 21 of<br />

SIGPLAN Notices, Association for Computing Machinery's Special Interest<br />

Group on Programming Languages (ACM/SIGPLAN), Association for<br />

Computing Machinery, Inc., 11 West 42nd Street, New York, New York<br />

10036, USA. ISBN 0-89791-204-7.<br />

Meyrowitz, N. (ed.): 1989, OOPSLA '89, Conference Proceedings, Vol. 24 of<br />

SIGPLAN Notices, Special Interest Group on Programming Languages,<br />

Association for Computing Machinery, Association for Computing Machinery,<br />

Inc., 11 West 42nd Street, New York, NY 10036, USA. ISBN<br />

0-0201-52249-7, ISSN 0362-1340.<br />

Minsky, N.H.<strong>and</strong>Pal, P.: 1995, Providing multiple views for objects by means<br />

of surrogates, Technical report, Rutgers University, New Brunswick, NJ<br />

08903 USA.<br />

*http://www.cs.rutgers.edu/~minsky/papers/surrogates-paper.ps<br />

Mordhorst, J. <strong>and</strong> van Dijk, W.: 1996, Composition lters in smalltalk, M.Sc.<br />

thesis, University of Twente, Dept. of Computer Science, P.O. box 217,<br />

7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Paepcke, A. (ed.): 1992, OOPSLA '92, Conference Proceedings, Vol. 27 of ACM<br />

SIGPLAN Notices, Association for Computing Machinery's Special Interest<br />

Group on Programming Languages (ACM/SIGPLAN), Association for<br />

Computing Machinery, Inc., 151 Broadway, New York, NY 10036. ISSN<br />

0362-1340, ISBN 0-201-53372-3.<br />

Pree, W.: 1994, Design Patterns for Object-Oriented Software Development,<br />

ACM Press Books, Addison-Wesley, Reading, MA. ISBN 0-201-42294-8.<br />

Schmidt, R. W.: n.d., Dynamically extensible objects in a class-based language.<br />

Stuurman, C.: 1996, Techniques for de ning composition lters using message<br />

manipulators, M.Sc. thesis, University ofTwente, Dept. of Computer Science,<br />

P.O. box 217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Tekinerdogan, B.: 1994, The design of an object-oriented framework for atomic<br />

transactions, M.Sc. thesis, University of Twente, Dept. of Computer Science,<br />

P.O. box 217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Tokoro, M. <strong>and</strong> Pareschi, R. (eds): 1994, ECOOP '94, Object-Oriented Programming,<br />

number 821 in Lecture Notes in Computer Science, European<br />

Conference on Object-Oriented Programming, Springer-Verlag, Berlin Heidelberg.<br />

ISBN 0-387-58202-9 / ISBN 3-540-58202-9.


188 Bibliography<br />

Vuijst, C.: 1994, Design of an object oriented framework for image algebra,<br />

M.Sc. thesis, University ofTwente, Dept. of Computer Science, P.O. box<br />

217, 7500 AE, Enschede, The Netherl<strong>and</strong>s.<br />

Wieringa, R. <strong>and</strong> Jonge, W. d.: 1991a, The identi cation of objects <strong>and</strong><br />

roles, Technical Report IR-267, Faculty of Mathematics <strong>and</strong> Computer<br />

Science, Vrije Universiteit, Amsterdam. Available for ftp in le 91-<br />

<strong>Objects</strong>Roles.ps.Z.<br />

Wieringa, R. <strong>and</strong> Jonge, W. d.: 1991b, The identi cation of objects <strong>and</strong> roles<br />

{ object identi ers revisited, Technical Report IR-267, Faculty of Mathematics<br />

<strong>and</strong> Computer Science, Vrije Universiteit, Amsterdam. Abbreviated<br />

<strong>and</strong> revised version of 91-<strong>Objects</strong>Roles.ps.Z. Available for ftp in le<br />

92-<strong>Objects</strong>Roles.ps.Z..

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!