• 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
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Need advice on a simple design

 
Ranch Hand
Posts: 164
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello ranchers I have often encountered the following dilemma while programming and I would like to get your opinion on this.
Lets take for example a class called Food which has some extending children like Vegetable and Fruit
Vegetable has some children like Carrot and Cabbage
Fruit also has some children, for example Orange and Apple
Just a simple 3 layer inheritance structure. Now what I want to ask is if you have an array of type Food and you want to find all the fruits in the array, for instance loop through the array and print out "A fruit!" if that object is a Fruit
You would have to ask each object what kind of food it is, and the question is: What is the best way of getting this info?

I know there are a lot of ways to do this, the one I have usually preferred is using this design:


And then in the main class:


I've read that this is not a good practice, you should use enums instead, but I really don't like enums for some reason. You could also use instanceof operator to achieve this but I've also read that using instanceof in this way is a bad practice too.
What is the best practice here? How would you do this?>
 
Saloon Keeper
Posts: 15731
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Definitely not int constants. Enums *are* preferable. You should really learn to appreciate them.

In this particular case, I would use the instanceof operator. However, in any serious application I would question why you have an array of Food in the first place, when you only need Fruits.
 
Bartender
Posts: 1111
Eclipse IDE Oracle VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can easily see why he would want to operate on only some of the items in a list.
and i dislike instance of (isn't it a code smell?), but vote for enum instead
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wendy Gibbons wrote:I can easily see why he would want to operate on only some of the items in a list.
and i dislike instance of (isn't it a code smell?), but vote for enum instead


I have to disagree; in this case, the attribute is simply duplicating the behaviour of instanceof, so I'd get rid of it completely.

For some other type of categorization, I would definitely agree with Stephan that enums are the way to go.

Winston
 
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll chime in to support instance of as well. If all of the valid implementations of Food have to be defined in food then you will have a very tightly coupled solution. It may not be a requirement for your example, but in the spirit of OO discussion, what if a third party wants to implement a "Meat" class inheriting from Food. How will the Food enum be updated to support it?

The enum approach is only going to let you support "one layer" of abtraction. The base layer of course is Food itself and the second layer in the example is Fruit or Vegetable.

In the enum example, how would you further distinguish Orange and Apple? They are both valid fruit and instance of would not allow Fruit to be determined but also instance of Apple or Orange. The enum approach would not support this capability.


 
Wendy L Gibbons
Bartender
Posts: 1111
Eclipse IDE Oracle VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Brian Burress wrote:I'll chime in to support instance of as well. If all of the valid implementations of Food have to be defined in food then you will have a very tightly coupled solution. It may not be a requirement for your example, but in the spirit of OO discussion, what if a third party wants to implement a "Meat" class inheriting from Food. How will the Food enum be updated to support it?

The enum approach is only going to let you support "one layer" of abtraction. The base layer of course is Food itself and the second layer in the example is Fruit or Vegetable.

In the enum example, how would you further distinguish Orange and Apple? They are both valid fruit and instance of would not allow Fruit to be determined but also instance of Apple or Orange. The enum approach would not support this capability.




good point, could you make the classes visitable?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Wendy Gibbons wrote:good point, could you make the classes visitable?


Ooof. Over-engineering perhaps?

Winston
 
Brian Burress
Ranch Hand
Posts: 143
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have not used the visitor pattern myself to have practical experience with it. Quickly reviewing the def of the pattern here, I am not sure if it would be applicable when you are trying to get some sort of result or status back for a specific instance of an object as the focus seems to be more for performing operations across. I am not immediately seeing an aspect in the visitor examples that would support this. You could have various 'visit' methods accepting an object as Fruit or Vegetable, but then we go back to the point of distinguising between Orange, Apple, etc.

Possibly one of the better responses to the original posting would be to ask for more requirements on what the solution is trying to accomplish. Depending on the problem statement, the rest of the posts help portray possible approaches.
 
Stephan van Hulst
Saloon Keeper
Posts: 15731
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well obviously the problem lies in that we have a foodBasket to begin with, instead of a fruitBasket. Where did the basket come from? Wasn't there a way to get one with just fruits?

The solutions offered here are ways to deal with a problem that shouldn't be there in the first place.
 
Wendy L Gibbons
Bartender
Posts: 1111
Eclipse IDE Oracle VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Well obviously the problem lies in that we have a foodBasket to begin with, instead of a fruitBasket. Where did the basket come from? Wasn't there a way to get one with just fruits?

The solutions offered here are ways to deal with a problem that shouldn't be there in the first place.



That is true, but after joining a company with 10 years of legacy code, lots of it is generated, problems that shouldn't be there, often are.
 
Unnar Björnsson
Ranch Hand
Posts: 164
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You seem to agree that the foodBasket should be fruitBasket, ok but if I want to make an inventory of food available at the store? The easiest way would be to use one Arraylist<Food>() which has the same problem as foodBasket, so would you split the inventory into multiple arraylists for each category then?
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Unnar Björnsson wrote:You seem to agree that the foodBasket should be fruitBasket, ok but if I want to make an inventory of food available at the store? The easiest way would be to use one Arraylist<Food>() which has the same problem as foodBasket, so would you split the inventory into multiple arraylists for each category then?


No, but I think I might have some sort of Inventory hierarchy that mirrors my Food one. That way, you can just update relevant totals whenever you add or remove items from your stock. I suspect there might even be a way of doing it with your existing classes, but I'm afraid my brain's a bit tired at the moment. If I think of something tomorrow, I'll post it.

Winston
 
His brain is the size of a cherry pit! About the size of this ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic