J
Jean Lutrin
Hi all,
I have two questions: one regarding a pattern
that I don't know the name of and one other
regarding the decorator pattern.
In one project I've been working on, I had to optimize
a *very* memory consuming code (which I didn't write).
The code (oversimplified) looks like this :
abstract class SomeClass {
abstract int doSomeTask();
abstract int doAnotherTask();
abstract int doAThirdTask();
}
class Inefficient extends SomeClass {
int doSomeTask() {
// very ineficient method consuming lots of ressources
}
int doAnotherTask() {
...
}
int doAThirdTask() {
...
}
}
Once we noticed there were problems in the code, we
ran a profiler and noticed an excessive memory usage
traced back to one single method.
We had no access to the source code, so I did the
following.
I added an "optimized method" class looking like this :
class Efficient extends SomeClass {
private Inefficient wrapped;
Efficient() {
wrapped = new Inefficient();
}
int doSomeTask() {
// optimized method
};
int doSomeOtherTask() {
return wrapped.doSomeOtherTask();
}
int doAThirdTask() {
return wrapped.doSomeOtherTask();
}
}
Note that I extend SomeClass and not the Inefficient class. This
way, the client of this class only see that the class they use
extends SomeClass : they don't need to know that Efficient
actually "wrap" an Inefficient object. The inefficient method
of the Inefficient class is never called : it has been "replaced" by
another method, much more optimized. For all the rest, it is
the old class that actually does all the job.
Everything is working all and well (and "non-garbage-collectable"
memory usage went way down btw, by a factor of 60 !, which was
actually the whole purpose of this manipulation).
However, I don't know if there's a name for this way
of proceeding. I don't add any new functionality to
the class: it is a concrete implementation of the
abstract class. And this implementation is based, under
the hood, on another concrete implementation of the
abstract class (but nobody notices it: this detail is
hidden from the client). Nothing is added, no new
functionality is added.
How would you name this way of proceeding ?
Is it similar to some well known pattern ?
My second question concerns the Decorator pattern. The
Java I/O streams are often cited, nearly everywhere, as
*the* major use of the Decorator pattern in the Java API
Let's look at those three :
public abstract class InputStream {...}
public class FilterInputStream extends InputStream {...}
public class BufferedInputStream extends FilterInputStream {...}
Which class is said to be decorating which one ?
In a post from the year 2000, on this very group, I found
the following :
I would be tempted to say "of course that the FilterInputStream
has the same interface as the InputStream"... The InputStream
is an abstract class !
So Does it means that everytime you extends an abstract class
(without making the extending class final) you are using
the "Decorator" pattern ?
I don't see which object is wrapping which one : do you
really find that the FilterInputStream wraps the
abstract InputStream class ?
Thanks in advance for any help on this.
As always, excuse my french
Jean
I have two questions: one regarding a pattern
that I don't know the name of and one other
regarding the decorator pattern.
In one project I've been working on, I had to optimize
a *very* memory consuming code (which I didn't write).
The code (oversimplified) looks like this :
abstract class SomeClass {
abstract int doSomeTask();
abstract int doAnotherTask();
abstract int doAThirdTask();
}
class Inefficient extends SomeClass {
int doSomeTask() {
// very ineficient method consuming lots of ressources
}
int doAnotherTask() {
...
}
int doAThirdTask() {
...
}
}
Once we noticed there were problems in the code, we
ran a profiler and noticed an excessive memory usage
traced back to one single method.
We had no access to the source code, so I did the
following.
I added an "optimized method" class looking like this :
class Efficient extends SomeClass {
private Inefficient wrapped;
Efficient() {
wrapped = new Inefficient();
}
int doSomeTask() {
// optimized method
};
int doSomeOtherTask() {
return wrapped.doSomeOtherTask();
}
int doAThirdTask() {
return wrapped.doSomeOtherTask();
}
}
Note that I extend SomeClass and not the Inefficient class. This
way, the client of this class only see that the class they use
extends SomeClass : they don't need to know that Efficient
actually "wrap" an Inefficient object. The inefficient method
of the Inefficient class is never called : it has been "replaced" by
another method, much more optimized. For all the rest, it is
the old class that actually does all the job.
Everything is working all and well (and "non-garbage-collectable"
memory usage went way down btw, by a factor of 60 !, which was
actually the whole purpose of this manipulation).
However, I don't know if there's a name for this way
of proceeding. I don't add any new functionality to
the class: it is a concrete implementation of the
abstract class. And this implementation is based, under
the hood, on another concrete implementation of the
abstract class (but nobody notices it: this detail is
hidden from the client). Nothing is added, no new
functionality is added.
How would you name this way of proceeding ?
Is it similar to some well known pattern ?
My second question concerns the Decorator pattern. The
Java I/O streams are often cited, nearly everywhere, as
*the* major use of the Decorator pattern in the Java API
Let's look at those three :
public abstract class InputStream {...}
public class FilterInputStream extends InputStream {...}
public class BufferedInputStream extends FilterInputStream {...}
Which class is said to be decorating which one ?
In a post from the year 2000, on this very group, I found
the following :
A classic example in Java is the FilterInputStream
class (and its many subclasses BufferedInputStream,
DataInputStream, CheckedInputStream, InflaterInputStream,
DigestInputStream, LineNumberInputStream, PushbackInputStream)
which is a Decorator of an InputStream. It provides the same
API as the InputStream which it wraps, but allows you to
add additional capability. It is this idea of adding
functionality by wrapping another object while implementing
the same API that is characteristic of the Decorator pattern.
I too, think Decorator is an extremely poor name.
I would be tempted to say "of course that the FilterInputStream
has the same interface as the InputStream"... The InputStream
is an abstract class !
So Does it means that everytime you extends an abstract class
(without making the extending class final) you are using
the "Decorator" pattern ?
I don't see which object is wrapping which one : do you
really find that the FilterInputStream wraps the
abstract InputStream class ?
Thanks in advance for any help on this.
As always, excuse my french
Jean