|
Evaluating Software Design Patterns — the "Gang of Four" patterns implemented in Java 6 |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object dk.rode.thesis.builder.AbstractExpressionBuilder<E> dk.rode.thesis.builder.TypedExpressionBuilder<E>
E
- The type of value the evaluation of constructed
expressions produces.@Participant(value="ConcreteBuilder") public class TypedExpressionBuilder<E>
A typed expression builder builds typed
expressions.
An actual builder must be supplied at construction to perform the
construction of expressions, but this builder will use a local
context
.
Implementation notes:
This builder uses covariant types for the created expressions
where possible. The expression type is narrowed to TypedExpression
.
Narrowing it even further, i.e. to the exact expression type, is
not always possible if the implementation types are hidden: how
can the builder cast to the exact type if only the interfaces are
known? As TypedExpression
has a concrete decorator class,
TypedExpressionDecorator
, the narrowing to TypedExpression
can be performed because an implementation is always known.
This presents a problem with the buildFlowExpression()
method
because it already has a narrowed return type, namely FlowExpression
,
and because it is created via composition; this builder has no control
over the creation process. The FlowExpression
type must not be lost,
or the functionality offered by it cannot be used by the client.
This is not a problem for the buildInitialisedFlowExpression(Expression...)
method, because it returns an Expression
type like most other
builder methods.
Inheritance, proxies, and/or decoration/adaptation must be used. Dynamic proxies can
only be used of an interface is used. Decoration and adaptation can only be used
if a non-final type is known. Inheritance only if a concrete class is known,
regardless if an interface is known. As FlowExpression
is concrete,
but non final, we have to make a decorator wrapping the created
FlowExpression
, overriding all methods, and adapting it to the
TypedExpression
interface. This is tedious at best, but cannot be avoided.
The decorator class is TypedFlowExpression
.
Dynamic proxies created by a ProxyFactory
cannot be used for several reasons.
First, FlowExpression
is a concrete type, so casting a proxy into the return
type required by the buildFlowExpression()
method will cause a class cast
exception. Secondly, FlowExpression
already implements
InitialisableExpression
that use covariant return types to refine its
copy()
method. TypedExpression
also use covariant return types to
to refine its copy()
method. This works for FlowExpression
because
it is a concrete type known to implement both interfaces, but cannot work for dynamic
proxies because if incompatible return types. See the JavaDoc for
TypedFlowExpression.copy()
to get an idea of the different narrowed return
types that fits the TypedFlowExpression
class.
Instead of inheritance, this builder relies on composition: the actual builder to construct the expressions is supplied at construction time. This can be viewed as an application of the Decorator pattern, and perhaps also as a degenerate version of the Bridge pattern where the abstraction and implementation share the same interface.
Field Summary | |
---|---|
protected ExpressionBuilder<E> |
builder
The expression builder used to construct the expressions. |
protected Class<E> |
type
A class literal representing the type of value the evaluation of constructed expressions produces. |
Fields inherited from class dk.rode.thesis.builder.AbstractExpressionBuilder |
---|
context, root, sequence |
Constructor Summary | |
---|---|
TypedExpressionBuilder(Class<E> type,
ExpressionBuilder<E> builder)
Constructor. |
|
TypedExpressionBuilder(TypedExpressionBuilder<E> builder)
Copy constructor. |
Method Summary | ||
---|---|---|
TypedExpression<Boolean> |
buildAndExpression(Expression<Boolean> first,
Expression<Boolean> second)
Builds a new short-circuit AND expression. |
|
TypedExpression<E> |
buildAssignmentExpression(VariableExpression<E> variable,
Expression<? extends E> expression)
Builds a new ASSIGNMENT expression. |
|
TypedExpression<E> |
buildBreakExpression(TypedExpression<E> expression)
Builds a new BREAK expression. |
|
TypedExpression<E> |
buildConditionalExpression(Expression<Boolean> condition,
Expression<? extends E> first,
Expression<? extends E> second)
Builds a new CONDITIONAL expression. |
|
TypedExpression<E> |
buildCurrentExpression()
Builds a new CURRENT expression. |
|
TypedExpression<Boolean> |
buildEqualExpression(Expression<?> first,
Expression<?> second)
Builds a new EQUAL expression. |
|
TypedFlowExpression<E> |
buildFlowExpression()
Builds a new uninitialised
FLOW expression. |
|
TypedExpression<E> |
buildInitialisedFlowExpression(Expression<? extends E>... expressions)
Builds a new initialised
FLOW expression. |
|
TypedExpression<E> |
buildNextExpression(Expression<? extends Number> count)
Builds a new NEXT expression. |
|
TypedExpression<Boolean> |
buildNonShortCircuitAndExpression(Expression<Boolean> first,
Expression<Boolean> second)
Builds a new non short-circuit AND expression. |
|
TypedExpression<Boolean> |
buildNonShortCircuitOrExpression(Expression<Boolean> first,
Expression<Boolean> second)
Builds a new non short-circuit OR expression. |
|
TypedExpression<Boolean> |
buildNotExpression(Expression<Boolean> expression)
Builds a new NOT expression. |
|
TypedExpression<Boolean> |
buildOrExpression(Expression<Boolean> first,
Expression<Boolean> second)
Builds a new short-circuit OR expression. |
|
TypedExpression<E> |
buildResetExpression()
Builds a new RESET expression. |
|
TypedExpression<Boolean> |
buildReverseExpression(Expression<Boolean> reverse)
Builds a new REVERSE expression. |
|
TypedExpressionBuilder<E> |
copy()
Returns a deep copy of this object. |
|
protected static
|
getTypedExpression(Expression<T> expression,
Class<T> type)
Returns a typed expression of the
typed supplied as type based on expression . |
|
Class<E> |
type()
Returns a class literal representing the type of value the evaluation of constructed expressions produces. |
Methods inherited from class dk.rode.thesis.builder.AbstractExpressionBuilder |
---|
buildConstantExpression, buildExpression, buildVariableExpression, equals, getContext, getRootExpression, getSequence, hashCode, initialiseExpressions, toString |
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
Methods inherited from interface dk.rode.thesis.builder.ExpressionBuilder |
---|
buildConstantExpression, buildExpression, buildVariableExpression, getRootExpression, getSequence |
Field Detail |
---|
protected final ExpressionBuilder<E> builder
Never null.
protected final Class<E> type
Constructor Detail |
---|
public TypedExpressionBuilder(Class<E> type, ExpressionBuilder<E> builder)
The same sequence
as used by builder
will be
used by this builder, but a new local context
will be
created and used.
type
- The class literal representing the type of value the
evaluation of constructed expressions produces; cannot
be null.builder
- The actual builder to use; cannot be null.
NullPointerException
- If either argument is null.public TypedExpressionBuilder(TypedExpressionBuilder<E> builder)
The same sequence
as used by builder
will be
used by this builder, but a new local context
will be
created and used.
The root expression from builder
is not copied.
Hence, this builder is ready to construct new expressions, and
return a unique root expression from AbstractExpressionBuilder.getRootExpression()
.
builder
- The builder to copy; cannot be null.
NullPointerException
- If builder
is null.Method Detail |
---|
public TypedExpression<Boolean> buildAndExpression(Expression<Boolean> first, Expression<Boolean> second)
ExpressionBuilder
buildAndExpression
in interface ExpressionBuilder<E>
first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedExpression<E> buildAssignmentExpression(VariableExpression<E> variable, Expression<? extends E> expression)
ExpressionBuilder
buildAssignmentExpression
in interface ExpressionBuilder<E>
variable
- The variable to be assigned the result of the
evaluation of expression
; cannot be null,
or be a constant
.expression
- The expression to deliver the variable value when
evaluated; cannot be null.
public TypedExpression<E> buildBreakExpression(TypedExpression<E> expression)
ExpressionBuilder
buildBreakExpression
in interface ExpressionBuilder<E>
expression
- The target expression, if any; can be null.
public TypedExpression<E> buildConditionalExpression(Expression<Boolean> condition, Expression<? extends E> first, Expression<? extends E> second)
ExpressionBuilder
buildConditionalExpression
in interface ExpressionBuilder<E>
condition
- The condition expression; cannot be null.first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedExpression<E> buildCurrentExpression()
ExpressionBuilder
buildCurrentExpression
in interface ExpressionBuilder<E>
public TypedExpression<Boolean> buildEqualExpression(Expression<?> first, Expression<?> second)
ExpressionBuilder
buildEqualExpression
in interface ExpressionBuilder<E>
first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedFlowExpression<E> buildFlowExpression()
ExpressionBuilder
uninitialised
FLOW expression.
buildFlowExpression
in interface ExpressionBuilder<E>
public TypedExpression<E> buildInitialisedFlowExpression(Expression<? extends E>... expressions) throws ExpressionException
ExpressionBuilder
initialised
FLOW expression.
buildInitialisedFlowExpression
in interface ExpressionBuilder<E>
expressions
- The expressions, in order, to be
associated with the returned expression;
cannot be null.
ExpressionException
- If the building fails.public TypedExpression<E> buildNextExpression(Expression<? extends Number> count)
ExpressionBuilder
buildNextExpression
in interface ExpressionBuilder<E>
count
- The expression that will determine the number
of times next()
will be invoked on
the sequence
when the
constructed expression is evaluated.
public TypedExpression<Boolean> buildNonShortCircuitAndExpression(Expression<Boolean> first, Expression<Boolean> second)
ExpressionBuilder
buildNonShortCircuitAndExpression
in interface ExpressionBuilder<E>
first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedExpression<Boolean> buildNonShortCircuitOrExpression(Expression<Boolean> first, Expression<Boolean> second)
ExpressionBuilder
buildNonShortCircuitOrExpression
in interface ExpressionBuilder<E>
first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedExpression<Boolean> buildNotExpression(Expression<Boolean> expression)
ExpressionBuilder
buildNotExpression
in interface ExpressionBuilder<E>
expression
- The expression operand; cannot be null.
public TypedExpression<Boolean> buildOrExpression(Expression<Boolean> first, Expression<Boolean> second)
ExpressionBuilder
buildOrExpression
in interface ExpressionBuilder<E>
first
- The first expression operand; cannot be null.second
- The second expression operand; cannot be null.
public TypedExpression<E> buildResetExpression()
ExpressionBuilder
buildResetExpression
in interface ExpressionBuilder<E>
public TypedExpression<Boolean> buildReverseExpression(Expression<Boolean> reverse)
ExpressionBuilder
buildReverseExpression
in interface ExpressionBuilder<E>
reverse
- The expression that will determine if the
sequence
is tried
reversed when the constructed expression is
evaluated.
public TypedExpressionBuilder<E> copy()
Copyable
copy
in interface Copyable<ExpressionBuilder<E>>
protected static final <T> TypedExpression<T> getTypedExpression(Expression<T> expression, Class<T> type)
typed
expression of the
typed supplied as type
based on expression
.
T
- The type.expression
- The expression to associate type
with,
if not already; cannot be null.type
- The type; cannot be null.
NullPointerException
- If either argument is null.public final Class<E> type()
|
Gunni Rode / rode.dk | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |