172 Chapter 10 Mec hanisms for Soft w are Reuse Ob - - PDF document

172 chapter 10 mec hanisms for soft w are reuse ob ject
SMART_READER_LITE
LIVE PREVIEW

172 Chapter 10 Mec hanisms for Soft w are Reuse Ob - - PDF document

172 Chapter 10 Mec hanisms for Soft w are Reuse Ob ject-orien ted programming has b een billed as the tec hnology that will nally p ermit soft w are to b e constructed from general-purp ose reusable comp


slide-1
SLIDE 1 172
slide-2
SLIDE 2 Chapter 10 Mec hanisms for Soft w are Reuse Ob ject-orien ted programming has b een billed as the tec hnology that will nally p ermit soft w are to b e constructed from general-purp
  • se
reusable comp
  • nen
ts. W riters suc h as Brad Co x ha v e ev en gone so far as to describ e
  • b
ject
  • rien
tation as heralding the \industrial rev
  • lution"
in soft w are dev elopmen t [Co x 1986 ]. While the realit y ma y not quite matc h the exp ectations
  • f
OOP pioneers, it is true that
  • b
ject-orien ted programming mak es p
  • ssible
a lev el
  • f
soft w are reuse that is
  • rders
  • f
magnitude more p
  • w
erful than that p ermitted b y previous soft w are construction tec hniques. In this c hapter, w e will in v estigate the t w
  • most
common mec hanisms for soft w are reuse, whic h are kno wn as inheritanc e and c
  • mp
  • sition.
Inheritance in Ja v a is made more exible b y the presence
  • f
t w
  • dieren
t mec hanisms, in terfaces and sub classing. In addition to con trasting inheritance and comp
  • sition,
w e will con trast inheritance p erformed using sub classing and inheritance p erformed using in terfaces, and relate all to the concept
  • f
substitutabilit y . 10.1 Substitutabilit y The concept
  • f
substitutabilit y fundamen tal to man y
  • f
the most p
  • w
erful soft w are dev el-
  • pmen
t tec hniques in
  • b
ject-orien ted programming. Y
  • u
will recall that substitutabilit y referred to the situations that
  • ccurs
when a variable declared as
  • ne
t yp e is used to hold a value deriv ed from another t yp e. In Ja v a, substitutabilit y can
  • ccur
either through the use
  • f
classes and inheritance,
  • r
through the use
  • f
in terfaces. W e ha v e seen examples
  • f
b
  • th
in
  • ur
earlier case studies. In the Pin Ball game program describ ed in Chapter 7, the v ariable ta rgets w as declared as a PinBallT a rget, but in fact held a v ariet y
  • f
dieren t t yp es
  • f
v alues that w ere created using sub classes
  • f
PinBallT a rget. In the Solitaire program from Chapter 9, the v ariable allPiles w as declared as holding a Ca rdPile, but in fact held v alues that w ere sub classes
  • f
Ca rdPile, suc h as DeckPile and Disca rdPile: 173
slide-3
SLIDE 3 174 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE public class Solitare f static public CardPile allPiles [ ]; public void init () f ... allPiles = new CardPile[13]; // then ll them in allPiles[0] = new DeckPile(335, 30); allPiles[1] = new DiscardPile(268, 30); g ... g W e ha v e also seen examples
  • f
substitutabilit y arising through in terfaces. An example is the instance
  • f
the class FireButtonListener created in the Cannon-ball game (Chapter 6). The class from whic h this v alue w as dened w as declared as implemen ting the in terface ActionListener. Because it implemen ts the ActionListener in terface, w e can this v alue as a parameter to a function (in this case, addActionListener) that exp ects an ActionListener v alue. class CannonWorld extends Frame f ... private class FireButtonListe ner implements ActionListener f public void actionPerformed (ActionEvent e) f ... g g public CannonWorld () f ... fire.addActionL ist en er( ne w FireButtonListe ne r() ); g g W e will return to the distinction b et w een inheritance
  • f
classes and inheritance
  • f
in ter- faces in Section 10.1.2. 10.1.1 The Is-a Rule and the Has-a Rule A commonly emplo y ed rule-of-th um b that can b e used to understand when inheritance is an appropriate soft w are tec hnique is kno wn collo quially as is-a and has-a (or p art-of )
slide-4
SLIDE 4 10.1. SUBSTITUT ABILITY 175 relationship. The is-a relationship holds b et w een t w
  • concepts
when the rst is a sp ecialized instance
  • f
the second. That is, for all practical purp
  • ses
the b eha vior and data asso ciated with the more sp ecic idea form a subset
  • f
the b eha vior and data asso ciated with the more abstract idea. F
  • r
example, all the examples
  • f
inheritance w e describ ed in the early c hapters satisfy the is-a relationship (a Flo rist is-a Shopk eep er, a Dog is-a Mammal, a PinBall is-a Ball, and so
  • n).
The relationship deriv es its name from a simple rule
  • f
th um b that tests the relationship. T
  • determine
if concept X is a sp ecialized instance
  • f
concept Y, simply form the English sen tence \A n X is a Y". If the assertion \sounds correct," that is, if it seems to matc h y
  • ur
ev eryda y exp erience, y
  • u
ma y judge that X and Y ha v e the is-a relationship. The has-a relationship,
  • n
the
  • ther
hand, holds when the second concept is a comp
  • nen
t
  • f
the rst but the t w
  • are
not in an y sense the same thing, no matter ho w abstract the generalit y . F
  • r
example, a Ca r has-a Engine, although clearly it is not the case that a Ca r is-a Engine
  • r
that an Engine is-a Ca r. A Ca r, ho w ev er, is-a V ehicle, whic h in turn is-a MeansOfT ransp
  • rtation.
Once again, the test for the has-a relationship is to simply form the English sen tence \A n X has a Y", and let common sense tell y
  • u
whether the result sounds reasonable. Most
  • f
the time, the distinction is clear-cut. But, sometimes it ma y b e subtle
  • r
ma y dep end
  • n
circumstances. In Section 10.2 w e will use
  • ne
suc h indenite case to illustrate the t w
  • soft
w are dev elopmen t tec hniques that are naturally tied to these t w
  • relationships.
10.1.2 Inheritance
  • f
Co de and Inheritance
  • f
Beha vior There are at least t w
  • dieren
t w a ys in whic h a concept can satisfy the is-a relationship with another concept, and these are reected in t w
  • dieren
t mec hanisms in the Ja v a language. Inheritance is the mec hanism
  • f
c hoice when t w
  • concepts
share structur e
  • r
c
  • de
relationship with eac h
  • ther,
while an in terface is the more appropriate tec hnique when t w
  • concepts
share the sp e cic ation
  • f
b ehavior, but no actual co de. This can b e illustrated with examples from the Ja v a run-time library . The class F rame, from whic h most Ja v a windo ws inherit, pro vides a great deal
  • f
co de, in the form
  • f
metho ds that are inherited and used without b eing
  • v
erridden. Th us, inheritance using the extends mo dier in the class heading is the appropriate mec hanism to use in this situation. // a cannon game is a t yp e
  • f
F rame public class CannonGame extends Frame f ... g On the
  • ther
hand, the c haracteristics needed for an ActionListener (the
  • b
ject t yp e that resp
  • nds
to button presses) can b e describ ed b y a single metho d, and the implemen tation
  • f
that metho d cannot b e predicted, since it diers from
  • ne
application to another. Th us,
slide-5
SLIDE 5 176 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE an interface is used to describ e
  • nly
the necessary requiremen ts, and no actual b eha vior is inherited b y a sub class that implemen ts the b eha vior. class CannonWorld extends Frame f ... // a re button listener implemen ts the action listener in terface private class FireButtonListe ner implements ActionListener f public void actionPerformed (ActionEvent e) f ... g g g In general, the class-sub class relationship should b e used whenev er a sub class can usefully inherit either co de, data v alues,
  • r
b eha vior from the paren t class. The in terface mec hanism should b e used when the c hild class inherits
  • nly
the sp ecication
  • f
the exp ected b eha vior, but no actual co de. 10.2 Comp
  • sition
and Inheritance Describ ed Tw
  • dieren
t tec hniques for soft w are reuse are c
  • mp
  • sition
and inheritanc e. W e ha v e explic- itly noted uses
  • f
inheritance in earlier c hapters, and ha v e sev eral places used comp
  • sition
as w ell, although w e ha v e not p
  • in
ted it
  • ut.
One w a y to view these t w
  • dieren
t mec hanisms is as manifestations
  • f
the has-a rule and the is-a rule, resp ectiv ely . Although in most situations the distinction b et w een is-a and has-a is clear-cut, it do es happ en
  • ccasionally
that it can b e dicult to determine whic h mec hanism is most appro- priate to use in a particular situation. By examining
  • ne
suc h indenite case, w e can more easily p
  • in
t
  • ut
the dierences b et w een the use
  • f
inheritance and the use
  • f
comp
  • sition.
The example w e will use is tak en from the Ja v a library , and concerns the dev elopmen t
  • f
a Stack abstraction from an existing V ecto r data t yp e. The V ecto r data t yp e is describ ed in detail in Chapter 19. While abstractly a v ector is most commonly though t
  • f
as an indexed collection, the Ja v a implemen tation also p er- mits v alues to b e added
  • r
remo v ed from the end
  • f
the collection, gro wing and shrinking the con tainer as necessary . The particular metho ds
  • f
in terest for this discussion can b e describ ed as follo ws: class Vector f // see if collection is empt y public boolean isEmpty () f ... g // return size
  • f
collection
slide-6
SLIDE 6 10.2. COMPOSITION AND INHERIT ANCE DESCRIBED 177 public int size () f ... g // add elemen t to end
  • f
collection public void addElement (Object value) f ... g // return last elemen t in collection public Object lastElement () f ... g // remo v e elemen t at giv en index public Object removeElementAt (int index) f ... g ... g A stack is an abstract data t yp e that allo ws elemen ts to b e added
  • r
remo v ed from
  • ne
end
  • nly
. If y
  • u
think ab
  • ut
a stac k
  • f
dishes sitting
  • n
a coun ter y
  • u
can get a go
  • d
in tuition. It is easy to access the topmost dish,
  • r
to place a new dish
  • n
the top. It is m uc h more dicult to access an y dish
  • ther
than the topmost dish. In fact, it migh t b e that the
  • nly
w a y to do this is to remo v e dishes
  • ne
b y
  • ne
un til y
  • u
reac h the dish y
  • u
w an t. The Stack abstractions dened here will b e sligh tly simpler than the v ersion pro vided b y the Ja v a library . In particular, the library abstraction will thro w an exception if an attempt is made to access
  • r
remo v e an elemen t from an empt y stac k, a condition w e will ignore. The Ja v a library stac k routine names the empt y test metho d empty, instead
  • f
the metho d isEmpt y from class V ecto r, and nally the Stack abstraction pro vides a metho d to searc h the stac k to determine if it includes a giv en elemen t. W e will not describ e this metho d here. 10.2.1 Using Comp
  • sition
W e will rst in v estigate ho w the stac k abstraction can b e formed with comp
  • sition.
Recall from
  • ur
earlier discussion that an
  • b
ject is simply an encapsulation
  • f
data v alues and b eha vior. When comp
  • sition
is emplo y ed to reuse an existing data abstraction in the de- v elopmen t
  • f
a new data t yp e, a p
  • rtion
  • f
the state
  • f
the new data structure is simply an instance
  • f
the existing structure. This is illustrated in Figure 10.1, where the data t yp e Stack con tains a priv ate instance eld named theData, whic h is declared to b e
  • f
t yp e V ecto r. Because the V ecto r abstraction is stored as part
  • f
the data area for
  • ur
stac k, it m ust b e initialized in the constructor. The constructor for class Stack allo cates space for the v ector, giving a v alue to the v ariable theData. Op erations that manipulate the new structure are implemen ted b y making use
  • f
the existing
  • p
erations pro vided for the earlier data t yp e. F
  • r
example, the implemen tation
  • f
the isEmpt y
  • p
eration for
  • ur
stac k data structure simply in v
  • k
es the similarly named function already dened for v ectors. The p eek
  • p
eration is kno wn b y a dieren t name, but
slide-7
SLIDE 7 178 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE class Stack f private Vector theData; public Stack () f theData = new Vector(); g public boolean isEmpty () f return theData.isEmpty( ); g public Object push (Object newValue) f theData.addEleme nt (newValue); g public Object peek () f return theData.lastElem en t() ; g public Object pop () f Object result = theData.lastElem ent () ; theData.removeE lem en tAt (t heD at a. siz e( )-1 ); return result; g g; Figure 10.1: A Stac k created using Comp
  • sition
slide-8
SLIDE 8 10.2. COMPOSITION AND INHERIT ANCE DESCRIBED 179 the task is already pro vided b y the lastElement
  • p
eration in the V ecto r class. Similarly , the push
  • p
eration is simply p erformed b y executing an addElement
  • n
the v ector. The
  • nly
  • p
eration that is sligh tly more complex is p
  • pping
an elemen t from the stac k. This in v
  • lv
es using t w
  • metho
ds pro vided b y the V ecto r class, namely
  • btaining
the topmost elemen t, and remo ving it from the collection. Notice that to remo v e the elemen t w e m ust rst determine its index p
  • sition,
then remo v e the elemen t b y naming its p
  • sition.
The imp
  • rtan
t p
  • in
t to emphasize is the fact that comp
  • sition
pro vides a w a y to lev erage
  • an
existing soft w are comp
  • nen
t in the creation
  • f
a new application. By use
  • f
the existing V ecto r class, the ma jorit y
  • f
the dicult w
  • rk
in managing the data v alues for
  • ur
new comp
  • nen
t ha v e already b een addressed. On the
  • ther
hand, comp
  • sition
mak es no explicit
  • r
implicit claims ab
  • ut
substitutabil- it y . When formed in this fashion, the data t yp es Stack and V ecto r are en tirely distinct and neither can b e substituted in situations where the
  • ther
is required. 10.2.2 Using Inheritance An en tirely dieren t mec hanism for soft w are reuse in
  • b
ject-orien ted programming is the concept
  • f
inheritance; with whic h a new class can b e declared a sub class,
  • r
child class,
  • f
an existing class. In this w a y , all data areas and functions asso ciated with the
  • riginal
class are automatically asso ciated with the new data abstraction. The new class can, in addition, dene new data v alues
  • r
new functions; it can also
  • verride
functions in the
  • riginal
class, simply b y dening new functions with the same names as those
  • f
functions that app ear in the paren t class. These p
  • ssibilities
are illustrated in the class description sho wn in Figure 10.2, whic h implemen ts a dieren t v ersion
  • f
the Stack abstraction. By naming the class V ecto r in the class heading, w e indicate that
  • ur
Stack abstraction is an extension,
  • r
a renemen t,
  • f
the existing class V ecto r. Th us, all data elds and
  • p
erations asso ciated with v ectors are immediately applicable to stac ks as w ell. The most
  • b
vious features
  • f
this class in comparison to the earlier are the items that are missing. There are no lo cal data elds. There is no constructor, since no lo cal data v alues need b e initialized. The metho d isEmpt y need not b e pro vided, since the metho d is inherited already from the paren t class V ecto r. Compare this function with the earlier v ersion sho wn in Figure 10.1. Both tec hniques are p
  • w
erful mec hanisms for co de reuse, but unlik e comp
  • sition,
inheritance carries an implicit assumption that sub classes are, in fact, subt yp es. This means that instances
  • f
the new abstraction should react similarly to instances
  • f
the paren t class. In fact, the v ersion using inheritance pro vides more useful functionalit y than the v ersion using comp
  • sition.
F
  • r
example, the metho d size in the V ecto r class yields the n um b er
  • f
elemen ts stored in a v ector. With the v ersion
  • f
the Stack formed using inheritance w e get this function automatically for free, while the comp
  • sition
v ersion needs to explicitly add a new
  • p
eration if w e w an t to include this new abilit y . Similarly , the abilit y to access
slide-9
SLIDE 9 180 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE class Stack extends Vector f public void push (Object value) f addElement (value); g public Object peek () f return lastElement(); g public Object pop () f Object result = lastElement(); removeElementAt (th eD ata .s ize ()
  • 1
); return result; g g; Figure 10.2: A stac k created using Inheritance in termediate v alues directly using an index is in this v ersion p
  • ssible
with a stac k, but not p ermitted in the abstraction created using comp
  • sition.
10.3 Comp
  • sition
and Inheritance Con trasted Ha ving illustrated t w
  • mec
hanisms for soft w are reuse, and ha ving seen that they are b
  • th
applicable to the implemen tation
  • f
stac ks, w e can commen t
  • n
some
  • f
the adv an tages and disadv an tages
  • f
the t w
  • approac
hes.
  • Inheritance
carries with it an implicit, if not explicit, assumption
  • f
substitutabilit y . That is, classes formed b y inheritance are assumed to b e subt yp es
  • f
the paren t class, and therefore candidates for v alues to b e used when an instance
  • f
the paren t class is exp ected. No suc h assumption
  • f
substitutabilit y is asso ciated with the use
  • f
comp
  • sition.
  • Comp
  • sition
is the simpler
  • f
the t w
  • tec
hniques. Its adv an tage is that it more clearly indicates exactly what
  • p
erations can b e p erformed
  • n
a particular data structure. Lo
  • king
at the declaration for the Stack data abstraction, it is clear that the
  • nly
  • p
erations pro vided for the data t yp e are the test for emptiness, push, p eek and p
  • p.
This is true regardless
  • f
what
  • p
erations are dened for v ectors.
  • In
inheritance the
  • p
erations
  • f
the new data abstraction are a sup erset
  • f
the
  • p
er- ations
  • f
the
  • riginal
data structure
  • n
whic h the new
  • b
ject is built. Th us, to kno w exactly what
  • p
erations are legal for the new structure the programmer m ust examine the declaration for the
  • riginal.
An examination
  • f
the Stack declaration, for example,
slide-10
SLIDE 10 10.3. COMPOSITION AND INHERIT ANCE CONTRASTED 181 do es not immediately indicate that the size metho d can b e legally applied to stac ks. It is
  • nly
b y examination
  • f
the declaration for the earlier V ecto r data abstraction that the en tire set
  • f
legal
  • p
erations can b e ascertained. The dicult y that
  • ccurs
when, to understand a class constructed using inheritance, the programmer m ust frequen tly ip bac k and forth b et w een t w
  • (or
more) class declarations has b een lab eled the \y
  • -y
  • "
problem [T aenzer 1989 ].
  • The
brevit y
  • f
data abstractions constructed with inheritance is, in another ligh t, an adv an tage. Using inheritance it is not necessary to write an y co de to access the func- tionalit y pro vided b y the class
  • n
whic h the new structure is built. F
  • r
this reason, implemen tations using inheritance are almost alw a ys, as in the presen t case, consid- erably shorter in co de than are implemen tations constructed with comp
  • sition,
and they
  • ften
pro vide greater functionalit y . F
  • r
example, the inheritance implemen tation mak es a v ailable not
  • nly
the size test for stac ks but also the index related
  • p
erations (inserting, mo difying
  • r
remo ving elemen ts b y giving their index lo cations).
  • Inheritance
do es not prev en t users from manipulating the new structure using metho ds from the paren t class, ev en if these are not appropriate. F
  • r
example, when w e use inheritance to deriv e the class Stack from the class V ecto r, nothing prev en ts users from adding new elemen ts to the stac k using the inherited metho d insertElementA t, and thereb y placing elemen ts in lo cations
  • ther
than the top
  • f
the stac k.
  • In
comp
  • sition
the fact that the class V ecto r is used as the storage mec hanism for
  • ur
stac k is merely an implemen tation detail. With this tec hnique it w
  • uld
b e easy to reimplemen t the class to mak e use
  • f
a dieren t tec hnique (suc h as a link ed list), with minimal impact
  • n
the users
  • f
the Stack abstraction. If users coun ted
  • n
the fact that a Stack is merely a sp ecialized form
  • f
V ecto r, suc h c hanges w
  • uld
b e more dicult to implemen t.
  • A
comp
  • nen
t constructed using inheritance has access to elds and metho ds in the paren t class that ha v e b een declared as p rotected. A comp
  • nen
t constructed using comp
  • sition
can
  • nly
access the public p
  • rtions
  • f
the included comp
  • nen
t.
  • Inheritance
ma y allo w us to use the new abstraction as an argumen t in an existing p
  • ly-
morphic function. W e will in v estigate this p
  • ssibilit
y in more detail in Chapter 12. Because comp
  • sition
do es not imply substitutabilit y , it usually precludes p
  • lymor-
phism.
  • Understandabilit
y and main tainabilit y are dicult to judge. Inheritance has the ad- v an tage
  • f
brevit y
  • f
co de but not
  • f
proto col. Comp
  • sition
co de, although longer, is the
  • nly
co de that another programmer m ust understand to use the abstraction. A programmer faced with understanding the inheritance v ersion needs to ask whether an y b eha vior inherited from the paren t class w as necessary for prop er utilization
  • f
the new class, and w
  • uld
th us ha v e to understand b
  • th
classes.
slide-11
SLIDE 11 182 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE
  • Data
structures implemen ted through inheritance tend to ha v e a v ery small adv an tage in execution time
  • v
er those constructed with comp
  • sition,
since
  • ne
additional func- tion call is a v
  • ided
(although
  • ptimization
tec hniques, suc h as inline functions, can in theory b e used to eliminate m uc h
  • f
this
  • v
erhead). Of the t w
  • p
  • ssible
implemen tation tec hniques, can w e sa y whic h is b etter in this case? One answ er in v
  • lv
es the substitution principle. Ask y
  • urself
whether, in an application that exp ected to use a V ecto r data abstraction, it is correct to substitute instead an instance
  • f
class Stack. The b
  • ttom
line is that the t w
  • tec
hniques are v ery useful, and an
  • b
ject-orien ted programmer should b e familiar with b
  • th
  • f
them. 10.4 Com bining Inheritance and Comp
  • sition
The Ja v a I/O system, whic h w e will in v estigate in more detail in Chapter 14, pro vides an in teresting illustration
  • f
the w a y in whic h inheritance and comp
  • sition
can in teract with eac h
  • ther,
and the particular problems eac h mec hanism is designed to solv e. T
  • b
egin with, there is an abstract concept, and sev eral concrete realizations
  • f
the concept. F
  • r
the le input system the abstract concept is the idea
  • f
reading a stream
  • f
b ytes in sequence,
  • ne
after the
  • ther.
This idea is em b
  • died
in the class InputStream, whic h denes a n um b er
  • f
metho ds for reading b yte v alues. The concrete realizations dier in the source
  • f
the data v alues. V alues can come from an arra y
  • f
b ytes b eing held in memory , from an external le,
  • r
from another pro cess that is generating v alues as needed. There is a dieren t sub class
  • f
InputStream for eac h
  • f
these. InputStream ByteArra yInputStream FileInputStream Pip edInputStream SequenceInputStream StringBuerInputStream Because eac h
  • f
these is declared as a sub class
  • f
InputStream, they can b e substituted for a v alue
  • f
t yp e InputStream. In this fashion pro cedures can b e written to pro cess a
slide-12
SLIDE 12 10.5. NO VEL F ORMS OF SOFTW ARE REUSE 183 stream
  • f
b yte v alues, without regard to where the v alues
  • riginate
(whether in memory ,
  • r
from an external le,
  • r
from another pro cess). Ho w ev er, there is an additional source
  • f
v ariation among input streams. Or rather, there is additional functionalit y that is sometimes required when using an input stream. F urthermore, this functionalit y is indep enden t
  • f
the source for the b yte v alues. One example is the abilit y to k eep trac k
  • f
line n um b ers, so that the programmer can determine
  • n
whic h line
  • f
the input the curren t b yte
  • riginates.
Another useful function is the abilit y to buer input, so as to ha v e the p
  • ssibilit
y
  • f
rereading recen tly referenced b ytes
  • nce
again. These features are pro vided b y dening a sub class
  • f
InputStream, named FilterInput- Stream. A FilterInputStream is formed as a sub class
  • f
InputStream. Th us, using the prin- ciple
  • f
substitutabilit y , a FilterInputStream can b e used in places where an InputStream is exp ected. On the
  • ther
hand, a FilterInputStream holds as a comp
  • nen
t another instance
  • f
InputStream, whic h is used as the source for data v alues. Th us, the class InputStream is b
  • th
paren t and comp
  • nen
t to FilterInputStream. As requests for v alues are receiv ed, the FilterInputStream will access the InputStream it holds to get the v alues it needs, p erforming whatev er additional actions are required (for example, coun ting newline c haracters in
  • rder
to k eep trac k
  • f
the curren t line n um b er). class FilterInputStre am extends InputStream f protected InputStream in; ... g Because the comp
  • nen
t held b y the FilterInputStream can b e an y t yp e
  • f
InputStream, this additional functionalit y can b e used to augmen t and t yp e
  • f
InputStream, regardless
  • f
where the b yte v alues
  • riginate.
This idea
  • f
lters (sometimes called wr app ers in
  • ther
  • b
ject-
  • rien
ted literature) can b e quite p
  • w
erful when there are
  • rthogonal
sources
  • f
v ariation. Here the t w
  • reasons
  • f
v ariation are the source
  • f
the input v alues, and the additional functionalit y that ma y
  • r
ma y not b e needed in an y particular application. 10.5 No v el F
  • rms
  • f
Soft w are Reuse In this section w e will describ e sev eral no v el w a ys in whic h comp
  • sition,
  • r
inheritance,
  • r
b
  • th,
are used to ac hiev e dieren t eects. 10.5.1 Dynamic Comp
  • sition
One adv an tage
  • f
comp
  • sition
  • v
er inheritance concerns the dela y in binding time. With inheritance, the link b et w een c hild class and paren t class is established at compile time, and cannot later b e mo died. With comp
  • sition,
the link b et w een the new abstraction and the
slide-13
SLIDE 13 184 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE class Frog f private FrogBehavior behavior; public Frog () f behavior = new TadpoleBehavior() ; g public grow () f // see if b eha vior should c hange if (behavior.growUp( )) behavior = new AdultFrogBehavio r( ); behavior.grow() ; // b eha vior do es actual w
  • rk
behavior.swim() ; g g Figure 10.3: Class F rog holds dynamically c hanging b eha vior comp
  • nen
t
  • lder
abstraction is created at run-time, and is therefore m uc h w eak er, since it can also b e c hanged at run time. This is sometimes called dynamic c
  • mp
  • sition.
T
  • illustrate,
imagine a class that is sim ulating the b eha vior
  • f
a F rog. Although the frog in terface can b e xed throughout its life, the actual actions it p erforms migh t b e v ery dieren t when the frog is a tadp
  • le
  • r
when it is an adult. One w a y to mo del this is to create a class F rog that uses comp
  • sition
to hold a v alue
  • f
t yp e F rogBehavio r (Figure 10.3). The F rog class is largely a facade, in v
  • king
the F rogBehavio r
  • b
ject to do the ma jorit y
  • f
the real w
  • rk.
The no v el idea is that the v ariable holding the instance
  • f
F rogBehavio r can actually b e p
  • lymorphic.
There migh t b e more than
  • ne
class that implemen ts the F rogBehavio r sp ecication, suc h as T adp
  • leBehavio
r and AdultF rogBehavio r. Figure 10.4 illustrates these classes. The paren t class F rogBehavio r is here declared abstr act, whic h means that it must b e
  • v
erridden b efore an y instances can b e created. As the frog \gro ws", it can dynamically c hange b eha vior b y reassigning the v alue b ehavio r to a dieren t v alue (for example, mo ving from a T adp
  • leBehavio
r to an AdultF rogBehavio r). The user
  • f
the F rog abstraction need not kno w ab
  • ut
this c hange,
  • r
ev en b e a w are when it
  • ccurs.
Dynamic comp
  • sition
is a useful tec hnique if the b eha vior
  • f
an
  • b
ject v aries dramatically according to some in ternal concept
  • f
\state", and the c hange in state
  • ccurs
infrequen tly . 10.5.2 Inheritance
  • f
Inner Classes W e ha v e seen another com bination
  • f
inheritance and comp
  • sition
in some
  • f
the case studies presen ted in earlier c hapters. F
  • r
example, the \listener" classes that resp
  • nded
to ev en ts w ere constructed using inheritance, but w ere themselv es comp
  • nen
ts in the application class.
slide-14
SLIDE 14 10.5. NO VEL F ORMS OF SOFTW ARE REUSE 185 abstract class FrogBehavior f public boolean growUp () f return false; g public void grow (); public void swim (); g class TadpoleBehavior extends FrogBehavior f private int age = 0; public boolean growUp () f if (++age > 24) return true; g public void grow () f ... g public void swim () f ... g g class AdultFrogBehavi
  • r
extends Behavior f public void grow () f ... g public void swim () f ... g g Figure 10.4: Class F rogBehavio r can dynamically c hange
slide-15
SLIDE 15 186 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE The follo wing is a sk eleton
  • f
the class PinBallGame from Chapter 7. public class PinBallGame extends Frame f ... private class MouseKeeper extends MouseAdapter f ... g private class PinBallThread extends Thread f ... g g The classes MouseKeep er and PinBallThread are eac h constructed using inheritance. Eac h are then used to create a new comp
  • nen
t, that will b e held as part
  • f
the state
  • f
the pin ball game. When used in this fashion, inner classes com bine asp ects
  • f
b
  • th
inheritance and comp
  • sition.
10.5.3 Unnamed Classes In sev eral
  • f
the earlier case studies w e ha v e seen situations where inheritance is used to
  • v
erride an existing class, y et
  • nly
  • ne
instance
  • f
the new class is created. An alternativ e to naming the new class and then creating an instance
  • f
the named class is to use a class denition expression. Suc h an expression places the en tire class denition inside the instance creation expression. An example where this could b e used is in the denition
  • f
an ev en t listener. F
  • r
example, the CannonBall game describ ed in Chapter 6 con tained the follo wing co de: class CannonWorld extends Frame f ... private class FireButtonListe ner implements ActionListener f public void actionPerformed (ActionEvent e) f ... g g public CannonWorld () f fire.addActionL ist en er( ne w FireButtonListe ne r() ); ... g g Note ho w the constructor for the class CannonW
  • rld
creates an instance
  • f
the inner class FireButtonListener. This is the
  • nly
instance
  • f
this class created. An alternativ e w a y to ac hiev e the same eect w
  • uld
b e as follo ws:
slide-16
SLIDE 16 10.6. CHAPTER SUMMAR Y 187 class CannonWorld extends Frame f ... public CannonWorld () f fire.addActionL ist en er( ne w ActionListener( )f public void actionPerformed (ActionEvent e) f ... g g); ... g g Notice that in this example the
  • b
ject b eing created is declared
  • nly
as b eing an instance
  • f
ActionListener. Ho w ev er, a class denition follo ws immediately the ending paren thesis, indicating that a new and unname d class is b eing dened. This class denition w
  • uld
ha v e exactly the same form as b efore, ending with a closing curly brace. The paren thesis that follo ws this curly brace ends the argumen t list for the addActionListener call. (The reader should carefully matc h curly braces and paren thesis to see ho w this tak es place). An adv an tage to the use
  • f
the class denition expression in this situation is that it a v
  • ids
the need to in tro duce a new class name (in this case, the inner class name FireButtonListener). A disadv an tage is that suc h expressions tend to b e dicult to read, since the en tire class denition m ust b e wrapp ed up as an expression, and the close
  • f
the expressions
  • ccurs
after the end
  • f
the class denition. 10.6 Chapter Summary The t w
  • most
common tec hniques for reusing soft w are abstractions are inheritance and comp
  • sition.
Both are v aluable tec hniques, and a go
  • d
  • b
ject-orien ted system will usually ha v e man y examples
  • f
eac h. A go
  • d
rule
  • f
th um b for deciding when to use inheritance is the is-a rule. F
  • rm
the sen tence \An X is a Y", and if it sounds righ t to y
  • ur
ear, then the t w
  • concepts
X and Y can probably b e related using inheritance. The corresp
  • nding
rule for comp
  • sition
is the has-a rule. The decision whether to use inheritance
  • r
not is not alw a ys clear. By examining
  • ne
b
  • rderline
case,
  • ne
can more easily see some
  • f
the adv an tages and disadv an tages
  • f
the t w
  • soft
w are structuring tec hniques. The idea
  • f
lters, found in the p
  • rtion
  • f
the Ja v a library used for input and
  • utput,
is an in teresting tec hnique that com bines features
  • f
b
  • th
inheritance and comp
  • sition.
slide-17
SLIDE 17 188 CHAPTER 10. MECHANISMS F OR SOFTW ARE REUSE Study Questions 1. Explain in y
  • ur
  • wn
w
  • rds
the principle
  • f
substitutabilit y . 2. What is the is-a rule? What is the has-a rule? Ho w are these t w
  • rules
related to inheritance and comp
  • sition?
3. Ho w are in terfaces and inheritance related? 4. What are some
  • f
the adv an tages
  • f
comp
  • sition
  • v
er inheritance? 5. What are some
  • f
the adv an tages
  • f
using inheritance that are not a v ailable when comp
  • sition
is used? 6. Ho w do es a FilterStream com bine inheritance and comp
  • sition?
Exercises 1. A set is simply an unorganized collection
  • f
v alues. Describ e ho w
  • ne
could use a V ecto r to implemen t a set. W
  • uld
inheritance
  • r
comp
  • sition
b e the more appropriate mec hanism in this case? 2. Mo dify the Stack data abstractions giv en in this c hapter so that they will thro w a Empt yStackException if an attempt is made to read
  • r
remo v e a v alue from an empt y stac k.