Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #10860

Re: Design Question

From markspace <-@.>
Newsgroups comp.lang.java.programmer
Subject Re: Design Question
Date 2011-12-18 19:23 -0800
Organization A noiseless patient Spider
Message-ID <jcmaoa$rpc$1@dont-email.me> (permalink)
References <Xns9FBFC38D782BCjpnasty@94.75.214.39>

Show all headers | View raw


On 12/18/2011 4:13 PM, Novice wrote:
> Am I right in thinking that I should actually have an abstract class, maybe
> called AbstractScore, and that it should have two subclasses,

> Or is there a better way?


Generally, one wants to "prefer composition to inheritance."  That is, 
sub-classing (any object, abstract or otherwise(*)) should be considered 
after trying to compose a class out of other classes seems unsatisfactory.

((*) However if you must subclass, using an abstract class as the base 
class is best.)

In this case, composition might lead you to use two dialogs, each with 
different behaviors.  Both dialogs might have-a "score" which they 
share.  This is more MVC, where the dialogs (the view, the V part), are 
separate from the model (the M part).  Model here means your program 
logic (the score from a game) and view means the GUI (or some other 
"front end").

class MyInterumScoreDialog extends Dialog {
   private int score;
   ...
}

class MyFinalScoreDialog extends Dialog {
   private int score;
   ...
}

This allows you to have two objects, with different behavior, but which 
also share a state (the score).  The score here would probably be 
injected with a setter method or with the object's constructor.  This is 
the nice part of composition, that it works well with "dependency 
injection."


However, with a bit more reflection, you might decide that the two 
dialogs above share a lot of things in common, and only differ slightly 
in their behaviors.  So you might want to combine them into one object, 
if possible.  The things that are different are the text they display, 
the score itself, the label on the button, and the action taken when the 
button is clicked.  If these things could be represented in an abstract 
way, we'd have a more concise way of expressing what is we want, and an 
even more composed object.

This type of operation is so common in GUIs (display a message, collect 
a button press) that Swing devotes a whole slew of boilerplate methods 
to it.

<http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html>

Let's see if I can pick one out of that list that seems to fit... Well 
the bit on "Customizing the Button Text" seems closest.  Unfortunately, 
they don't provide a way to abstract the action taken.  Here's the basic 
code from the tutorial which I've tweaked a bit.

Object[] options = {"OK",};

int n = JOptionPane.showOptionDialog(frame,
     "Your intermediate score is:\n"+score,
     "Intermediate Score",
     JOptionPane.DEFAULT_OPTION,
     JOptionPane.QUESTION_MESSAGE,
     null,     //do not use a custom Icon
     options,  //the titles of buttons
     options[0]); //default button title

Just FYI, I didn't test or compile that code. Caveat emptor.

So now what do we do about that action?  Well we can just test a return 
value, and take an appropriate action.  We can do this inside a 
"controller" (the C part of MVC), which would be some bit of code that 
executes in response to a user action.  In this case, probably finishing 
a level activates the score dialog.

public class MyGame {

   private int score;
   private boolean gameOver; // == "score is final" when true

   ...

   void endLevel() {  // called at the end of each level
     // ... other end of level stuff here ...

     // display the score dialog
     if( gameOver ) {
       // display the final score, and exit

       ... JOptionPane.showOptionDialog( ...
       System.exit(0);
     } else {  // intermediate score, display and keep going

      ... JOptionPane.showOptionDialog( ...
       // just fall through, final score doesn't return
     }
   }

   ...
}

Note that you'll have to change some of the code from the JOptionPane 
exampled I showed for the final block of code.  E.g., the text strings 
that say "intermediate" should be changed to say "final".

So this seems to separate concerns a bit more to me than inheritance, or 
making a class with a special state (which seems to me to mix a bit the 
"model" (game code) with the "view" (GUI)) in an odd fashion.

The way it's done here, the GUI is pretty ignorant of what our game's 
state is (we just pass it strings, it has no idea what's going on) and 
we've eliminated some complexity (that complexity being a special 
combined model/GUI class that needs to hold the "final score" state) by 
using a standard, built-in class (or method, in this case) that gives us 
the behavior we need.

Sometimes, OO makes sense, but sometimes procedural is better. 
Especially in "terminal" elements of a design (that is, the leaves or 
lowest elements of your design).  At some point you have to stop making 
objects and just make the code actually do something.  When to do that 
is a matter of some experience, but also "how easy is this to do?"  Once 
it's easy enough, just do it.

In this case, I found a standard method that would do what I wanted with 
only a little manipulation, so I took that way out.  Once my design 
reach a point that I could call that method, rather than decompose 
further, or make more objects, I just yell "done!" and write the method, 
and move on to the next design requirement.

Back to comp.lang.java.programmer | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Design Question Novice <novice@example..com> - 2011-12-19 00:13 +0000
  Re: Design Question Arne Vajhøj <arne@vajhoej.dk> - 2011-12-18 19:24 -0500
    Re: Design Question ilAn <idonot@wantspam.net> - 2011-12-20 16:47 +0200
      Re: Design Question Arne Vajhøj <arne@vajhoej.dk> - 2011-12-20 10:39 -0500
  Re: Design Question markspace <-@.> - 2011-12-18 19:23 -0800
    Re: Design Question Novice <novice@example..com> - 2011-12-19 13:26 +0000
    Re: Design Question Novice <novice@example..com> - 2011-12-19 13:28 +0000
  Re: Design Question Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-12-19 07:16 -0400
    Re: Design Question Novice <novice@example..com> - 2011-12-19 13:49 +0000
      Re: Design Question Martin Gregorie <martin@address-in-sig.invalid> - 2011-12-19 22:22 +0000
        Re: Design Question Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-12-19 20:13 -0400
          Re: Design Question Lew <lewbloch@gmail.com> - 2011-12-20 07:37 -0800
            Re: Design Question Arne Vajhøj <arne@vajhoej.dk> - 2011-12-20 10:42 -0500
              Re: Design Question Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-12-20 17:46 -0400
        Re: Design Question Martin Gregorie <martin@address-in-sig.invalid> - 2011-12-20 20:40 +0000
  Re: Design Question Novice <novice@example..com> - 2011-12-19 13:34 +0000
  Re: Design Question Roedy Green <see_website@mindprod.com.invalid> - 2011-12-19 06:25 -0800
  Re: Design Question Gene Wirchenko <genew@ocis.net> - 2011-12-19 11:38 -0800
    Re: Design Question Lew <lewbloch@gmail.com> - 2011-12-20 07:42 -0800
      Re: Design Question Gene Wirchenko <genew@ocis.net> - 2011-12-20 11:51 -0800
        Re: Design Question soulspirit@gmail.com - 2011-12-20 14:55 -0800
          Re: Design Question Gene Wirchenko <genew@ocis.net> - 2011-12-20 15:25 -0800
            Re: Design Question soulspirit@gmail.com - 2011-12-21 01:11 -0800
              Re: Design Question Gene Wirchenko <genew@ocis.net> - 2011-12-21 11:08 -0800
                Re: Design Question soulspirit@gmail.com - 2011-12-21 15:27 -0800
                Re: Design Question Gene Wirchenko <genew@ocis.net> - 2011-12-21 18:06 -0800

csiph-web