------------------------------
Message: 4
Date: Fri, 17 Aug 2007 13:12:21 -0400
From: Kieran Kelleher <email@hidden>
Subject: Re: How do I get EO's instantiated with dynamic class?
To: Guido Neitzer <email@hidden>
Cc: WebObjects-Dev Dev <email@hidden>
Message-ID: <email@hidden>
Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
And even if there are minor attribute differences, you can just
ignore them (leave as null) for the variations of the entity that
does not require those attributes. The bottom line is to achieve
maintainable and flexible code.
The behaviors themselves can be represented by simple integer
attributes in the entity.
For example , let's say the Domain entity has a "Price Calculation
Behavior" that is a different algorithm/methodology for each domain
type.
Then you can in your Properties file have
//----------------------------------------------------------------------
--------
PricingBehaviour.10=org.myapp.eof.DotComPricingBehaviour
PricingBehaviour.20=org.myapp.eof.DotNetPricingBehaviour
etc., etc. ad infinitum....
//----------------------------------------------------------------------
--------
Your Domain entity will have an Integer attribute "pricingBehaviorType"
Then make a PricingBehavior.java interface that has the method
calculatePrice()
//----------------------------------------------------------------------
--------
Now implement the two small behaviour classes DotComPricingBehavior
and DotNetPricingBehavior, each with a constructor that takes a
Domain class and each implementing the PricingBehaviour interface,
for example
public DotComPricingBehavior( Domain aDomainEntity) {
_domain = aDomainEntity;
}
public BigDecimal calculatePrice(){
....
}
//----------------------------------------------------------------------
--------
//Then in the Domain class itself:
private PricingBehaviour pricingBehavior;
private PricingBehavior pricingBehavior(){
if ( _pricingBehavior == null ) {
String clazzName = ERXProperties.stringForKey
( "PricingBehaviour." + pricingBehaviorType() );
_pricingBehavior = ( PricingBehavior )
WKReflectionUtils.objectFromConstructor( clazzName, this );
}
return _behaviour;
}
public BigDecimal calculatePrice(){
return pricingBehavior(). calculatePrice();
}
//----------------------------------------------------------------------
--------
// And if you want to see the code to return the appropriate behavior
class ....
public static Object objectFromConstructor( String
objectClassName, Object constructorParam ) {
Object object = null;
try {
Constructor constructor = Class.forName
( objectClassName ).getConstructor( new Class[]
{ constructorParam.getClass() } );
object = constructor.newInstance( new Object[]
{ constructorParam } );
} catch ( Exception exception ) {
String errorMessage = "Failed to instantiate class with
name "
+ ( objectClassName == null ? "null" :
objectClassName )
+ " using a constructor parameter object = "
+ constructorParam.toString();
log.error( errorMessage, exception );
throw new RuntimeException( errorMessage, exception );
}
return object;
}
IIRC, this is one of the first basic patterns covered in Head First
Design Patterns book.
HTH, Kieran
On Aug 17, 2007, at 12:37 PM, Guido Neitzer wrote:
On 17.08.2007, at 10:20, Kieran Kelleher wrote:
I prefer using the Strategy Design Pattern instead of inheritance
whenever possible
Actually this really makes sense here, as the domain objects differ
normally not in different attributes (which would make it a
candiate for inheritance) but different behaviour.
As I understand it for this case, you'd have a single "Domain"
entity and class and an open number of "behaviour" plugins,
selected depending on the TLD entry, right?
It seems to be a good solution for this problem if there is no
additional / different information stored for the different "domain
types".
cug