locked
OO design question. RRS feed

  • Question

  • I'm trying to figure out a good way of looking this..

    I have a "Product" class ( which is the fullblown class having all the child info and such )  and I have a subset class we'll call  "ProductSummary" ( where it is used as an instance of OrderItems - when people are ordering products ) which doesn't have any child info - at least for now.  I also want a very lightweight instance, we'll call "ProductInfo" ( and make it a struct ) that I can use to bind to a list with just ID, Title, SubTitle, Description, and Price.

    now the problem is that I want to have a field called .DisplayName which required in all three classes..  ( btw so far I've not broke encapsulation because all the logic sits in Product.  ProductSummary and ProductInfo are for display only )

    if I make .DisplayName part of ProductSummary then make Product a subclass, I'm spreading my logic in multiple classes ( even though it's subclassed ) and I can use a struct like I wanted to..

    if I have a static helper method on the Product class, it's at least in one place, but would that become a performance bottleneck ( if I extend this model to other fields or methods ) if lots of threads are accessing that method?


    would appreciate some feedback..  thanks!



    Thursday, January 5, 2006 7:58 PM

Answers

  • that would really depend on why you need this property.

    if it's there for you to use in a ui, then i would suggest creating an interface called something like IUIComponent and put that logic in there (or you could create a class that's inherited, too). the idea is that you keep these variables grouped by purpose.

    another way is to create a function that accepts any object and do a select case by object type. for this to work, though, you'd need to already have the display name data available and you're merely assembling what would be the display name.... for example, the name of a project or the first name and last name of a person.

    make sense? hope this helps.

    dushan

    Saturday, January 7, 2006 6:24 PM

All replies

  • I am not sure I understand what your scenario is, from your description. However, eliminating inheritance in your case, and strengthtening encapsulation seem to me to be good ideas. Have you looked at interfaces, and at design patterns like Strategy?

    I strongly recomend a design patterns book, such as the original GoF book or Holub's "Holub on Patterns". Even an ocasional diagonal read can be very enlightening in that type of situations.

    Friday, January 6, 2006 3:15 AM
  • that would really depend on why you need this property.

    if it's there for you to use in a ui, then i would suggest creating an interface called something like IUIComponent and put that logic in there (or you could create a class that's inherited, too). the idea is that you keep these variables grouped by purpose.

    another way is to create a function that accepts any object and do a select case by object type. for this to work, though, you'd need to already have the display name data available and you're merely assembling what would be the display name.... for example, the name of a project or the first name and last name of a person.

    make sense? hope this helps.

    dushan

    Saturday, January 7, 2006 6:24 PM
  • First of all, I would suggest you keep multi-threading out of the whole issue - you'll probably only get data consistency problems and deadlocks. In which case, you wouldn't have problems with the static method.

    Second, I would point you to Eric Evans book on Domain Driven Design, or the corresponding site: http://domaindrivendesign.org so that you could design a clearer model.

    Hope that helps.

    Tuesday, July 4, 2006 2:32 PM
  • I agree with dushan, but I don't link the second solution. Why? because the second solution is not an elegant one. Why? beacuse a good design should be flexible and open for extension. Let's assume that you want to add a new product subclass. In this case you should add in the switch case block a new line. This violates the Open Close Principle - OCP (www.oodesign.com).

    Try to read about desing principles and design patterns(for this one you can find a lot of articles with google). I think for your solution you should keep in mind 2 important design principles: Open Close Principle - OCP and Single Responsibility Principle - SRP.
    Monday, July 10, 2006 7:02 PM
  • To expand on Dushan's suggestion in the first part

    you may want to create a different representation of the business entities for UI purposes. The UI representation can aggregate infromation from several business entities as well as add UI specific members

     

    Arnon

    Saturday, July 15, 2006 7:24 AM
  •  Kyong Kwak wrote:
    now the problem is that I want to have a field called .DisplayName which required in all three classes.

    What if you had an interface IProductDisplay that defined the DisplayName property and had each of your classes implement it. Your view would be defined only in terms of the interface, and your controller/presenter would pass along the relevant objects in each case.

    Does that help?

    Wednesday, July 19, 2006 1:53 PM
  • I agree in using interfaces. Then you can create a helper class that implements the interface, and in this way keep the logic in one place instead of implementing the interface in each class.

    dampbarn

    Monday, January 22, 2007 1:35 PM
  • If you decide to place the 'DisplayName' functionality outside of your entities objects in some kind of 'helper' object then you will be implementing the 'Visitor' pattern - the visitor design pattern is a way of separating an algorithm from an object structure.

    http://en.wikipedia.org/wiki/Visitor_pattern

    HTH

    Ollie Riches

    Saturday, January 27, 2007 12:14 PM
  •  Dushan wrote:

    that would really depend on why you need this property.

    if it's there for you to use in a ui, then i would suggest creating an interface called something like IUIComponent and put that logic in there (or you could create a class that's inherited, too). the idea is that you keep these variables grouped by purpose.

    another way is to create a function that accepts any object and do a select case by object type. for this to work, though, you'd need to already have the display name data available and you're merely assembling what would be the display name.... for example, the name of a project or the first name and last name of a person.

    make sense? hope this helps.

    dushan



    Normally in OO design, if you see a big case statement checking object types you are in need of polymorphism.

    In this case Udi is quite right, they've got aggregate root problems if you need a light version and a display version of an entity. Check out the DDD book he recommends.

    I would also say to have a look on Martin Fowlers site (from his book) at Data Transfer Objects if the UI version of the object is being passed over a remote boundary (say a web service), otherwise it might be worth passing the business objects.

    As always it depends on the specifics of the situation.

    Regards

    Ed Hill
    Wednesday, January 31, 2007 7:54 PM
  • see the customers example from the Visitor Pattern article on oodesign.com
    Sunday, February 11, 2007 6:03 PM