1

I have written a program with both a Advanced Mode and a Beginner Mode to allow the user to get the hang of my program before it is actually used. The Advanced Mode is almost identical to the Beginner Mode apart from one or two methods needing to be replaced by another, so I have decided to create a general Mode class for both Advanced Mode and Beginner Mode classes to use instead of just coping code: Here is the class structure if my explanation isn't very clear:

  • GUI Class
  • General Mode Class
    • Beginner Mode
    • Advanced Mode

Let's say that the General Mode class has the following code:

public class GeneralMode {

    private int range;
    private String id;


    public GeneralMode() {

    }

    public int getRange() {
        return range;
    }

    public String getID() {
    return id;
    }

    public void doStuff() {

    }

}

The GeneralMode class is where all the work gets done for the program. Now, I would like to make it so that the Advanced Mode class can take the input from the GUI class and use it in the same way as the GeneralMode class does.

Thank you for all your help!

2
  • "I would like to make it so that the MainMode class " - I don't see any MainMode class in your program. Can you explain? Commented Feb 5, 2009 at 9:23
  • You should clarify whether your GUI class contains a mode or is parent of modes. You should certainly be doing a contains relationship. Commented Feb 5, 2009 at 10:34

5 Answers 5

8

Make 'GeneralMode' class, an abstract class, with abstract methods that have to be implemented by the concrete 'advanced' and 'beginner' classes. The functionality that both modes have in common, can be implemented in the 'GeneralMode' class.

Then, in your GUI class, instantiate the correct concrete class, and put it in a 'GeneralMode' variable. Then, you can use it without you having to know whether your program is running in beginner mode or in advanced mode.

pseudocode:

GeneralMode mode = (UseAdvancedMode == true)? new AdvancedMode() : new BeginnerMode();
Sign up to request clarification or add additional context in comments.

1 Comment

Hmm, this answer has been voted up 6 times, but my rep-score remains the same; how comes ?
3

making the GeneralMode an abstract class definitely is the way to go to get the polimorphic behavior straight (as correctly explained by Frederik Gheysels).

one other important OO paradigm is to

favor composition over inheritance (Item 14, 'Effective Java' by Josh Bloch)

if your bulleted list represents your current inheritance hierarchy (ignore my comment if it doesn't...), i would strongly encourage you to change it so that your GUI Class is composed of a mode (rather than the mode being an extension of it -- the classical "is a" vs "has a" question). extracting whatever GUI settings into a parameter object which you will then pass to the modes to do their work would reduce the coupling even further.

Comments

2

Just to add to Frederik's answer, GeneralMode could also be an interface with BeginnerMode and AdvancedMode implementing this interface.

Use an abstract class if you want to share logic across all subclasses, if all classes will have the same implementation of getId and any other methods that will be the same.

If you want to leave the implementation of these methods up to the implementing class, then use an interface.

1 Comment

Indeed, I made it an abstract class, since TS was talking about 'only one or two methods have different logic'.
1

Another possibility is to use the Strategy Pattern. I'd prefer that one in your case, because I see more flexibility e.g. when changing the mode during run time. In that case you won't need to change your whole model instance (The Mode-Object), but only it's behaviour by loading a different Strategy. So you won't lose the state of your context by switching the mode.

public class GeneralContext //was GeneralMode in your Code-Example
{
 ...
 public void doStuff()
 {
   myMode.doStuff()
 }

 public void changeStrategy(int mode)
 {
   switch(mode)
   {
      case EXPERT_MODE: myMode= new ExpertMode(); break;
       ....    
      default: throw NoSuchMode();
   }
 }

  ....
 private interface Mode
 {
   void doStuff();
 }

 private class ExpertMode implements Mode
 {
   void doStuff()
   {
     ....
   }
 }
 private class BeginnerMode implements Mode
 {
   void doStuff()
   {
     ....
   }
 }

}

Further reading: GoF-Book (see wikipedia), Pages 315 ff.

Comments

0

You're on the right way. You just need to modify the doStuff() method to take the input parameters you need from the GUI. Then the GUI can call this method over the mode object it has, and pass it the appropriate parameters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.