• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to convert a sub-class (ProspectCustomer) to another sub-class (ValuedCustomer)?

 
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

"He who asks a question is a fool for five minutes; he who does not ask a question remains a fool forever."



1. Suppose we have a list of Customer : ProspectCustomer (new) and ValuedCustomer (existing/old)

ProspectCustomer extends Customer
ValuedCustomer extends Customer

2. If I add a new invoice to a ProspectCustomer, this ProspectCustomer will become a ValuedCustomer.

2.a. Customer customer = new ProspectCustomer();
2.b. customer.addInvoice(invoice);
2.c. dao.persist(customer);
{
1. store customer and invoice;
2. // now this ProspectCustomer will become a ValuedCustomer
if (customer instanceOf ProspectCustomer) {
Customer valuedCustomer = new ValuedCustomer();
copy customer to valuedCustomer
customer=valuedCustomer;
}
}

3. // out of dao
if (customer instanceOf ValuedCustomer)
display true; // should be


Question:
1. Mechanically, is the idea in 2.c. dao.persist(customer); OK
2. Designwise, how would you approach it?
 
Ranch Hand
Posts: 4632
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
to me it looks like you're over complicating things:
just have a Customer and a status (Prospect, Valued, Doesn't Pay etc)

similar to here at JavaRanch, there are 200,000+ users.
each has a title Green Horn, Ranch Hand etc.
there are not a bunch of Green Horn users and a separate bunch
of Ranch Hand users.
 
H Paul
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. Thanks, Michael, Is this what you have in mind?

Customer customer = new Customer(Type.Prospect);
customer.addInvoice();
customer.setStatus(Type.Valued);
dao.persist(customer);

2. Suppose I keep the original idea "extends", I plan to use JPA and map to

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "CUSTOMER_TYPE", discriminatorType = DiscriminatorType.STRING)

which is 1 single Customer that has a column named that has different values Prospect, Valued, Doesn't Pay.

So should I use your suggestion because in the database there is only 1 Customer with CUSTOMER_TYPE that
match well the concept of CUSTOMER_TYPE. This is a point I will consider. :-D

3. Now, suppose for the sake of technical theory, [I do not have a real world case], what if we have

A extends C
B extends C

How would you approach converting A to B? or it got to have a context for any meaningful suggestion? Thanks.
 
lowercase baba
Posts: 13089
67
Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
there is no automatic way to convert an object of type 'A' into an object of type 'B'. You can't convert a Dog to a BaseballTeam.

You may be able to write a method/constructor in class A that takes a B as a parameter, and builds an A. Note that this does not CONVERT B into an A, it just uses B as a template for building A...but this is fraught with danger. The original object still exists, so if you have multiple references to it, it can be hard/impossible to change them all

 
H Paul
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Valid or not:



From US Government, VicePresident is a virtual President (only) in the unexpected event where the President is not there. (The Presidency post is available.)

When such unexpected event occured, can we not make the VicePresident a President? (a subclass to another powerful subclass).
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

H Paul wrote:
When such unexpected event occured, can we not make the VicePresident a President?



As already stated, no. All you can do is create a new President object based on the VicePresident object, and you have to write the code to do it.

And this may be another case where it makes more sense to define these things as attributes of a single class, rather than expressing them in a type hierarchy. Hard to say without a concrete, real-world example with concrete, real-world requirements and surrounding design.

Also note that just because something happens in the real world, that doesn't mean it automatically translates to or is valid in Java.
 
H Paul
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. Thanks Jeff.

2.
Suppose we have an existing database where we have a ValuedCustomer table that has many relationship with other tables and a stand alone ProspectCustomer table.
Keywise: Both tables have the same format.

So if I have to translate this into Java, I would have:


Would this be reasonable to setup the object model this way? OR ?
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

H Paul wrote:Would this be reasonable to setup the object model this way? OR ?


Michael Dunn in his first answer already suggested that this is probably not the best way to set this up. Instead of having special subclasses for ValuedCustomer and ProspectCustomer, it's probably better to just have one Customer class and give it a field that specifies what kind of customer it is. Likewise, I wouldn't make separate tables in the database for special kinds of customers; just have one Customer table with a column that specifies what kind of customer it is.

You could use an enum for the customer type.

 
H Paul
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

If you can't beat them. Join them.



So what are typical questions one should ask (if such questions exist) on deciding making it an attribute or a type hierachy?
 
Marshal
Posts: 28226
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How about "Why should this feature require a subtype?" and "What's different about customers with and without this feature?"

If you implement the feature by having a variable which says whether it should be applied or not, then your methods are going to start to include code like


The case can be made that the posted code should be a method on its own, and then that it should be an overridden method where the "// do special" code is in the subclass and the "do ordinary" code is in the base class.

Without knowing what "Feature X" is, it's impossible to decide which of the two approaches should be taken.

However I can tell you that in real-life systems the number of such features will increase linearly with time. So at the end of several years you might end up with a dozen or two features. You might end up with classes like ProspectForeignCustomer and ValuedLocalCustomer and WalmartCustomer and FormerMailOrderCustomer and... the list would go on. Or your code could be a rat's nest of if-statements testing all of those features.

But that's just given the choice between sub-classing and using attributes. There are other approaches which might be better, but normally people don't look for those solutions until they notice the mess they have got themselves into.
 
H Paul
Ranch Hand
Posts: 491
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

"Most people would rather die than think: many do."


1. Thanks Paul.

2. If I keep what Jesper and Michael said alone, i.e probably only 1 Customer class,
would that imply all the attributes be optional for both Prospect and Valued?
I can not have any mandatory notion for any attributes?
Or if I introduce a mandatory attribute for which a Prospect Customer can not satify, then I am in trouble.

Am I dying correctly?
 
reply
    Bookmark Topic Watch Topic
  • New Topic