Thomas Menke wrote:
> For the record I answer my own question:
>
> Thomas Menke wrote:
>   
>> Problem is: I need to instantiate customer based on the information in 
>> customerType. But before I can read customerType I can't instantiate the 
>> correct class because I don't know which type. And after the 
>> customerType has been set by stripes it is already too late because 
>> stripes already tried and failed to set the customer.name property.
>>     
First of all - Thank You for sharing your solution!!! :-)

That's an interesting problem.  So you would like your customerType 
setter method - as a side effect (if I can call it that) - to create the 
appropriate customer subclass and you want to have a pre-specified 
ordering on the execution of the setter methods of the action bean for 
everything to work.  Interesting... .

I commented on this primarily because I have a similar need and had to 
think about how I would go about solving it.

>> What would be the "best" way to deal with this?
>>     
Not sure if this is a written best practice no-no or not but relying on 
a setter to produce the appropriate class before other setter methods 
get called is not the "best" way to deal with this class of problem in 
my personal opinion... .  An alternative idea is presented later (below).

> Stripes populates the values in order of the length of the name of the
> property. Thus I just need to make sure that this:
> public Customer.Type customerType;
> is shorter than that:
> public Customer customer;
>   
Wow.  Okay.  So that sounds like your design is relying on a "very" 
specific coding / implementation in the Stripes framework.

Question:  Does this specific Stripes "implementation" equally apply to 
Stripes 1.6?
Question:  Can this specific Stripes "implementation" be guaranteed to 
ALWAYS work this way and never be refactored in the future?
Question:  Can you always guarantee a newer variable will not be 
introduced that is shorter than this variable "cType"?
Question:  If your code is ever maintained by some one else can you 
guarantee that some one doesn't come along and say... "cType" is a 
poorly named variable... let me expand that to "customerType"... oops 
that just broke your action bean... sure you could plaster comment 
warnings all over the place but guess what this happens...

I'm not sure anyone could say "yes" to the above answers even if you 
could say "yes" to the 1st it is the 2nd that I would concern myself 
with the most.

I know you say you wanted to write test code to learn Stripes so the 
4rth question above is probably not even worth mentioning but you did 
ask how "best" to solve this :-)

> It is not right now, thus I rename customerType to cType. Then I use a
> setter-method for cType which is guaranteed to be called prior to
> setting any nested values of customer by stripes. In this method I
> instantiate the correct sub class of Customer and assign it to customer.
> And everything works fine.
>
> Special thanks to bgunter&aporter for explaing that to me :-).
>   
It's great that Ben and Aaron assisted in helping you resolve this 
offline and as such I am not sure what caveats and disclaimers they 
attached to your following this approach (which I imagine there were 
some or plenty)... .  Though personally I think framework Developers 
should discourage their user community from relying on such specific 
implementation details of the framework especially when it depends on 
something as fluid as length of a variable name.

Why?  Because there are alternative solutions that although not as 
direct that are more robust and should be prefered.  For example:

One important realization is that as far as the action bean is concerned 
the type it sees from the JSP is of the abstract superclass when setting 
any attributes or calling methods.  The only time it deals with the 
specific subclass is in the setter of of the customer type.  Well how about:

1) Creating a simple helper object that extends Customer called say 
CustomerDetails except you also add to it:
    a)  a CustomerType attribute
    b)  a method with the following signature that simply examines the 
customer type attribute that it has internally, constructs the 
appropriate subclass and populates it with the attributes it has internally:
         public Customer createCustomer()

2) (Optional) Make the CustomerDetails class package private and put it 
in the same package as its action ean

3) Having Stripes deal with and populate this CustomerDetails object 
which is an attribute retained by the action bean

4) In your event handler methods methods simply do to get the 
appropriate customer object to perform further processing e.g. data 
access, service call, etc...:
        Customer customer = this.getCustomerDetails.createCustomer();

What is the downside:

- Well you are instantiating an additional intermediary object i.e. you 
are not dealing directly with the end object

What is the upside:

- It eliminates having code that has a side effect in a setter which 
goes against best practices (for me personally)
- It is agnostic of how Stripes is implemented internally "today" and 
"tomorrow" (barring major revision framework changes of course)
- It eliminates having to incorporate disclaimer / banner comments on 
NOT changing cType and not making ANY other variable shorter than this 
cType variable
- It does not sacrifice readability of the variable (as per your choice 
to use cType)
- The code that determines the type and creates the appropriate subclass 
is encapsulated in the helper object

In the end, everyone can decide what makes sense for them but IFF anyone 
chooses to adopt the strategy you propose as a solution then I would 
strongly encourage above and beyond banner comments et al. having at 
least 1 Unit Test case that specifically tests for and ensures that the 
"side effect" is not broken in the future.

HTH,

--Nikolaos

> Thomas
>
> ------------------------------------------------------------------------------
> This SF.net email is sponsored by Sprint
> What will you do first with EVO, the first 4G phone?
> Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
> _______________________________________________
> Stripes-users mailing list
> Stripes-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/stripes-users
>
>   


-- 
Nikolaos Giannopoulos
Director, BrightMinds Software Inc.
e. nikol...@brightminds.org
w. www.brightminds.org
t. 1.613.822.1700
c. 1.613.797.0036
f. 1.613.822.1915


------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Stripes-users mailing list
Stripes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/stripes-users

Reply via email to