How much complexity to put in POJOs?

Discussion in 'Java' started by Scott Balmos, Jul 11, 2005.

  1. Scott Balmos

    Scott Balmos Guest

    Hi all,

    I seem to have this problem no matter what OO-based language I'm using,
    so this is probably not Java-specific. How much accessor/modifier
    complexity do you put in your data objects? Do your data objects have
    only the standard get/set combos for all data structures, or what
    others do you add?

    I wish I could provide a good example, but it's Monday, and the
    flywheel in the brain is still spinning up to speed.

    The best example I can think of is say you have a military personnel
    app, with objects representing a soldier and their rank (ie class
    Soldier has get/setRank). Would you put, say, function promote() in the
    Soldier or Rank object class itself, or in the personnel-management
    class(es), and have only get/set methods in Soldier and Rank?

    It's this type of drawing the line at how much self-management a data
    representation object should have that always trips me up.

    Opinions appreciated. Thanks!

    --Scott
     
    Scott Balmos, Jul 11, 2005
    #1
    1. Advertising

  2. Scott Balmos

    Joan Guest

    "Scott Balmos" <> wrote in message
    news:...
    > Hi all,
    >
    > I seem to have this problem no matter what OO-based language I'm using,
    > so this is probably not Java-specific. How much accessor/modifier
    > complexity do you put in your data objects? Do your data objects have
    > only the standard get/set combos for all data structures, or what
    > others do you add?
    >
    > I wish I could provide a good example, but it's Monday, and the
    > flywheel in the brain is still spinning up to speed.
    >
    > The best example I can think of is say you have a military personnel
    > app, with objects representing a soldier and their rank (ie class
    > Soldier has get/setRank). Would you put, say, function promote() in the
    > Soldier or Rank object class itself, or in the personnel-management
    > class(es), and have only get/set methods in Soldier and Rank?
    >
    > It's this type of drawing the line at how much self-management a data
    > representation object should have that always trips me up.
    >
    > Opinions appreciated. Thanks!


    My personal style is to not use getters/setters. I rely on my ability
    to not step on my foot. However, that said, I am rather fond of "private."
     
    Joan, Jul 11, 2005
    #2
    1. Advertising

  3. Scott Balmos

    Filip Larsen Guest

    Scott Balmos wrote

    > The best example I can think of is say you have a military personnel
    > app, with objects representing a soldier and their rank (ie class
    > Soldier has get/setRank). Would you put, say, function promote() in

    the
    > Soldier or Rank object class itself, or in the personnel-management
    > class(es), and have only get/set methods in Soldier and Rank?


    I almost always end up having the policy code separated from the entity
    classes so that each class has a clearcut responsibility. With your
    example that would correspond to the three classes: Soldier (entity for
    one soldier), SoldierRegister (container operations) and SoldierManager
    ("pure" policy). SoldierManager would most likely be associated with a
    single SoldierRegistry which it manages. If there are a lot of different
    management policies that needs to be combined in many ways, the
    SoldierManager may end up delegating the different management policies
    to, say, SoldierPromotingPolicy, SoldierSaleryPolicy and
    SoldierEducationPolicy.

    By the way, try get your hands on some good OO modelling and design
    books, preferably some that don't let the programming language dictate
    design too much. To pick one out of the crowd of such good books, I can
    recommend Craig Larmans "Applying UML and Patterns: An Introduction to
    Object-Oriented Analysis and Design and Iterative Development".


    Regards,
    --
    Filip Larsen
     
    Filip Larsen, Jul 11, 2005
    #3
  4. Scott Balmos

    Scott Balmos Guest

    "Filip Larsen" <> wrote in
    news:42d2cbb6$0$67259$:

    > Scott Balmos wrote
    >
    >> The best example I can think of is say you have a military personnel
    >> app, with objects representing a soldier and their rank (ie class
    >> Soldier has get/setRank). Would you put, say, function promote() in

    > the
    >> Soldier or Rank object class itself, or in the personnel-management
    >> class(es), and have only get/set methods in Soldier and Rank?

    >
    > I almost always end up having the policy code separated from the
    > entity classes so that each class has a clearcut responsibility. With
    > your example that would correspond to the three classes: Soldier
    > (entity for one soldier), SoldierRegister (container operations) and
    > SoldierManager ("pure" policy). SoldierManager would most likely be
    > associated with a single SoldierRegistry which it manages. If there
    > are a lot of different management policies that needs to be combined
    > in many ways, the SoldierManager may end up delegating the different
    > management policies to, say, SoldierPromotingPolicy,
    > SoldierSaleryPolicy and SoldierEducationPolicy.
    >


    Okay, this pretty much matches what I imagine anyway. The question is
    between Soldier & SoldierManager. Let's say you want to promote everyone
    in your battalion. Some pseudocode for SoldierManager.promote(),
    neglecting function parameters, is below.

    With a "logicless" Soldier:

    SoldierManager.promote()
    Soldier[] battalion = SoldierRegistry.getSoldiers()
    foreach Soldier in battalion
    Soldier.setRank(Soldier.getRank().getNextRank()) // getRank returns
    object Rank
    Soldier.getServiceRecord().addEntry("Promoted!")
    // send out notification emails to HQ, etc

    .... as opposed to this foreach in a "smart" Soldier:
    foreach Soldier in battalion
    Soldier.promote()

    Makes sense... Soldier, and other concrete data objects have just
    get/set methods, which handle only enforcement of data integrity for the
    object type, say before writing to the database (though some may say
    this is redundant, considering the database is supposed to enforce data
    integrity itself, also).

    > By the way, try get your hands on some good OO modelling and design
    > books, preferably some that don't let the programming language dictate
    > design too much. To pick one out of the crowd of such good books, I
    > can recommend Craig Larmans "Applying UML and Patterns: An
    > Introduction to Object-Oriented Analysis and Design and Iterative
    > Development".
    >
    >
    > Regards,


    Thanks for the recommendation. I'll put it on the list (ever-growing, as
    it is...). It's mainly because I still don't have enough experience,
    having worked on only two or three "major" projects. I've waffled both
    ways in my design methods. That's why I posted this in the first place,
    to try and pin myself down to the One True Way [tm], if there was such a
    thing.

    --Scott
     
    Scott Balmos, Jul 11, 2005
    #4
  5. Scott Balmos

    Guest

    Scott Balmos wrote:
    > >
    > >> The best example I can think of is say you have a military personnel
    > >> app, with objects representing a soldier and their rank (ie class
    > >> Soldier has get/setRank). Would you put, say, function promote() in

    > > the
    > >> Soldier or Rank object class itself, or in the personnel-management
    > >> class(es), and have only get/set methods in Soldier and Rank?

    > >


    >
    > --Scott


    Hi, Scott,

    Excellent question. I think you're hitting this problem, however,
    because you're not asking the right question (even though the one you
    have asked is ... excellent).

    Before diving in, I should say that I like Filip's suggestion
    (essentially splitting the Soldier into more single-responsibility
    parts) though I wouldn't have used his class names. I'd have
    preferred, "SoldierManager," to be just, "Solider;" but that's another
    story.

    Also, before getting wet, I wasn't sure which of your suggestions you
    think is best. You gave the, "Logicless Soldier," example, and the,
    "Smart Soldier," example, and said, "Makes sense ..." Which
    alternative did you think best?

    Anyway, IMHO, to decide which is best, you have to ask a question that
    you haven't touched on at all, and realise that this is *not* just a
    question of the logical decomposition of a Solder-entity: this is a
    question of encapsulation. You have to ask, "How can I maximise this
    behaviour's encapsulation?"

    Let's presume that you have all these soldier-related classes in a
    package called, "fight," which contains the public interface,
    "Solier." Your question boils down to asking: should Solider have a
    promote() method, or a getRank() method?

    This entirely depends on whether the Rank class is used by many
    clients outside the fight package: in other words, it depends entirely
    on how well encapsulated you want the Rank class (or more specifically,
    the ranking behaviour) to be.

    If you have many clients outside the fight package that need the
    specifics of rankings and ranking behaviours (such as the ranking
    succession you alluded to in your example), then it makes sense to
    have a public Rank class (or better yet, a public Rank interface) in
    the fight package (actually, there are better places for it than the
    fight package but that's, again, another story); and so it makes sense
    for the Soldier interface to have getRank() method.

    If, however, no one cares about the ranking behaviour of your Soldier
    outside your fight package, then this behaviour should be as
    encapsulated as possible: your Soldier interface should just have a
    promote() method.

    This doesn't mean either that there must or must not be a Rank
    interface, it's just that, if you want a Rank interface, it will be
    package-private to the fight package and Soldier will delegate to it
    (a second principle, in fact, will come into play here: the principle
    of variance encapsulation; if you think that promotion behaviour is
    likely to change, then there *should* be a separate, package-private
    Rank interface, but that's another blah blah blah).

    Also, cilents must make significant use of the Rank interface to
    warrant making it a public interface: if the view package (for
    example) wants to print a soldier's status, it will certainly want to
    know his rank, but it would be more flexible if the view package gave
    a some sort of TextStream to the Soldier to let it print out whatever
    details it likes (or alternatively, and slighty more ugly, have Soldier
    expose method: String getRank()) - this is not sufficient cause to
    explose a public
    interface.

    ..ed

    --
    www.EdmundKirwan.com - Home of The Fractal Class Composition.
     
    , Jul 12, 2005
    #5
  6. Scott Balmos

    Scott Balmos Guest

    Hi Ed,

    Yeah, now we're coming to the meat of the problem. I knew it was a
    problem with conceptually planning the amount of encapsulation. Like I
    said, it's probably a lack of experience. :)

    For clarification, I was saying that the logicless Soldier, which Filip
    was describing, made sense. The basic jist that I've developed, along
    with Filip's response, is that structural data objects should be
    concerned solely with representing and maintaining the integrity of the
    data they represent. E.g. a Soldier just represents a Soldier, the Rank
    just represents the rank (and also knows its relation to other Ranks,
    via getLowerRanks(), getHigherRanks(), etc in general).

    Actual complex operations on those data objects, aside from simple
    property manipulation, should be handled in separate management
    classes, collectively the business logic tier. Back to our example,
    changing a Soldier's rank to a new rank, in the process of promoting
    them, is a simple property manipulation. Thus Soldier.setRank(Rank foo)
    makes sense. But the complex operation of promoting (or demoting) a
    Soldier, which may involve setting a Rank property, moving the Soldier
    from one PayGradeList (extends List) to another, etc etc etc should be
    handled in a separate business logic tier object, e.g.
    SoldierManager.promote(Soldier luckyGuy).

    Your points on object visibility are well-taken. And at the expense of
    stretching my off-the-cuff military personnel app example to the
    limits, I can say "I get it" for the most part. :D

    Thanks.

    --S
     
    Scott Balmos, Jul 12, 2005
    #6
  7. Scott Balmos coughed up:
    > Hi all,
    >
    > I seem to have this problem no matter what OO-based language I'm
    > using, so this is probably not Java-specific. How much
    > accessor/modifier complexity do you put in your data objects? Do your
    > data objects have only the standard get/set combos for all data
    > structures, or what others do you add?


    Hah! Join the club. This is a classic OO question. In fact, I might
    regard it as /the/ question, and as you have already figured out, it all
    "depends".

    ....[rip]...

    > It's this type of drawing the line at how much self-management a data
    > representation object should have that always trips me up.
    >
    > Opinions appreciated. Thanks!



    Scott--- *please* post this question to comp.object. You'll get a very
    valuable conversation in there!

    I'll look for it.

    Thomas



    --
    Puzzle: You are given a deck of cards all face down
    except for 10 cards mixed in which are face up.
    If you are in a pitch black room, how do you divide
    the deck into two piles (may be uneven) that each
    contain the same number of face-up cards?
    Answer (rot13): Sebz naljurer va gur qrpx, qrny bhg
    gra pneqf naq syvc gurz bire.
     
    Thomas G. Marshall, Jul 13, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. exquisitus

    Advice on writing POJOs for EJBs

    exquisitus, Feb 25, 2005, in forum: Java
    Replies:
    1
    Views:
    333
    Bryce
    Feb 25, 2005
  2. Claude
    Replies:
    0
    Views:
    352
    Claude
    Mar 7, 2004
  3. cpp4ever
    Replies:
    3
    Views:
    378
    Francesco
    Sep 8, 2009
  4. Raymond Schanks
    Replies:
    0
    Views:
    537
    Raymond Schanks
    Apr 11, 2010
  5. George Hester
    Replies:
    3
    Views:
    89
    Thomas 'PointedEars' Lahn
    Aug 11, 2004
Loading...

Share This Page