Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Class Design

Options
  • 29-03-2012 8:33pm
    #1
    Registered Users Posts: 3,500 ✭✭✭


    Hey all,

    Currently teaching myself java and am running into a few problems with designing classes and knowing what to put in them. Ive gotten my hands on the Head First Object Orientated Analysis and Design book so will be giving that a read soon but in the mean time hope someone can help.

    I want to write a simple program to help me remember key points for the SCJP exam. Like a flash card with a question and answer.

    I want to be able to add questions and save them to a text file or something. Could some one give me a general jist of to what classes I should have in this program.

    I have a Card class with two String instance variables. One for question and one for answer. I have getter and setters for both.

    I have a Deck class with an ArrayList for holding the cards. Im not quite sure what other methods to put in this class. Like should I have an addCard method? Or should that be in a seperate class??

    Next I made a MainGui class that sorted out all the GUI bits. Not sure what methods tho to have in this class either. Should I have a method to set a label to the card question in the GUI class??

    Sorry if i havent explained myself well. Its hard to even get across where I am gettin stuck. Any help would be great!


Comments

  • Registered Users Posts: 586 ✭✭✭Aswerty


    Well first of all try keep as much logic possible out of the GUI class. Just have your GUI components and event handlers in it where your event handlers make calls on your business logic stored in other classes. Creating a card class that contains a question and answer variable is the correct approach. Though grouping the cards into a deck can be done a number of ways. I'll put forward two different approaches here.

    The first approach is to do what you were doing by creating a Deck class with a Card[] to store the cards. You then create methods such as Load() and Save() which would read and write the whole deck to a file (alternatively you could do your loading in the constructor). Other methods such as AddCard() and RemoveCard() would allow you to modify the deck. You should make your Card[] variable private and only view the cards through methods such as GetCard(int cardIndex) or GetAllCards(). This will mean your deck of cards can only be modified through the AddCard() and RemoveCard() methods.

    The second approach and the one I would favour is to get the rid of the Card[] variable in the Deck class. This would force you to directly access individual cards stored in the file as opposed to read and writing everything at once. This means the GetCard(int cardIndex) method would now implement file reading logic. This approach might be a bit trickier though (also depending on how you store cards in the file an index variable may be useful in the Card class). Another method that a Deck class might implement is SizeOfDeck() to get the number of cards in it.

    The main difference in the approaches is one reads/writes to file at the start and end of the program and the other reads/writes throughout the programs lifetime (more akin to how a database is accessed).


  • Registered Users Posts: 3,500 ✭✭✭Drexel


    Aswerty wrote: »
    Well first of all try keep as much logic possible out of the GUI class. Just have your GUI components and event handlers in it where your event handlers make calls on your business logic stored in other classes. Creating a card class that contains a question and answer variable is the correct approach. Though grouping the cards into a deck can be done a number of ways. I'll put forward two different approaches here.

    The first approach is to do what you were doing by creating a Deck class with a Card[] to store the cards. You then create methods such as Load() and Save() which would read and write the whole deck to a file (alternatively you could do your loading in the constructor). Other methods such as AddCard() and RemoveCard() would allow you to modify the deck. You should make your Card[] variable private and only view the cards through methods such as GetCard(int cardIndex) or GetAllCards(). This will mean your deck of cards can only be modified through the AddCard() and RemoveCard() methods.

    The second approach and the one I would favour is to get the rid of the Card[] variable in the Deck class. This would force you to directly access individual cards stored in the file as opposed to read and writing everything at once. This means the GetCard(int cardIndex) method would now implement file reading logic. This approach might be a bit trickier though (also depending on how you store cards in the file an index variable may be useful in the Card class). Another method that a Deck class might implement is SizeOfDeck() to get the number of cards in it.

    The main difference in the approaches is one reads/writes to file at the start and end of the program and the other reads/writes throughout the programs lifetime (more akin to how a database is accessed).

    Hey thanks for the reply. Your first approach is pretty much the way I was thinking of doin it. Where I think I am tripping up is the GUi class. To set the labels to the questions and answers I will need a setQuestionLabel() or something like that. Should this take in a String or what? Also will this all be put together in a kinda 'main program' class?


  • Registered Users Posts: 586 ✭✭✭Aswerty


    In the main program class you would create all your GUI components. Some components should be JButtons/Buttons and when these components are pressed on the GUI they should cause an event. You create an event handler for when events occur (you also need to have an action listener for the components causing events).

    For example when creating a new card you would have a create new card button. You would also have a TextField for entering the question and a TextField for entering an answer. So the user would enter the question and answer in the appropriate TextField and then press the create new card button. This would call the appropriate event handler. The event handler would perform logic similar to:
    public class MainProgram
    {[INDENT]
    // GUI components and action listeners would be initalised
    
    // a single instance of Deck class is initialised as a class variable (i.e. along side gui components)
    // we assume the deck is loaded in the constructor otherwise we would do deck.Load() after initialising
    Deck deck = new Deck();
    
    
    public void CreateNewCard(ActionEvent e)
    {
        // the TextFields would have been initialised in the GUI component section
        deck.AddCard(QuestionTeftField.Text, AnswerTextField.Text);
    }[/INDENT]
    }
    

    The AddCard() method would look like so:
    public class Deck
    {
    [INDENT]String[] DeckOfCards;
    
    public void AddCard(string question, string answer)
    {
        Card newCard = new Card(string question, string answer);
        
        // add new card to DeckOfCards
    }[/INDENT]
    }
    

    Not much code should exist in your main() method of the MainProgram class other than to run the application and to set application properties such as the GUI visibility, size, etc.


  • Registered Users Posts: 3,500 ✭✭✭Drexel


    Aswerty wrote: »
    In the main program class you would create all your GUI components. Some components should be JButtons/Buttons and when these components are pressed on the GUI they should cause an event. You create an event handler for when events occur (you also need to have an action listener for the components causing events).

    For example when creating a new card you would have a create new card button. You would also have a TextField for entering the question and a TextField for entering an answer. So the user would enter the question and answer in the appropriate TextField and then press the create new card button. This would call the appropriate event handler. The event handler would perform logic similar to:
    public class MainProgram
    {[INDENT]
    // GUI components and action listeners would be initalised
    
    // a single instance of Deck class is initialised as a class variable (i.e. along side gui components)
    // we assume the deck is loaded in the constructor otherwise we would do deck.Load() after initialising
    Deck deck = new Deck();
    
    
    public void CreateNewCard(ActionEvent e)
    {
        // the TextFields would have been initialised in the GUI component section
        deck.AddCard(QuestionTeftField.Text, AnswerTextField.Text);
    }[/INDENT]
    }
    

    The AddCard() method would look like so:
    public class Deck
    {
    [INDENT]String[] DeckOfCards;
    
    public void AddCard(string question, string answer)
    {
        Card newCard = new Card(string question, string answer);
        
        // add new card to DeckOfCards
    }[/INDENT]
    }
    

    Not much code should exist in your main() method of the MainProgram class other than to run the application and to set application properties such as the GUI visibility, size, etc.

    Ok this has cleared things up a lot for me. I am goina go and write it now and see what happens. Dunno why but I seem to have problems knowing what to put where!! Im hoping this is just lack of experience!!


  • Registered Users Posts: 3,500 ✭✭✭Drexel


    OK I have the most of it built. I havent sorted the saving and loading yet tho.

    I have 3 classes. The card and deck class and a mainGui class. My maingui class is massive tho and there is alot of methods in it. Is this ok. For instance i have showQuestion(), addCard(), showAnswer(), hideAnswer() in the main gui class. And actionListeners for my buttons. Is the main gui the place for them methods?


  • Advertisement
  • Registered Users Posts: 586 ✭✭✭Aswerty


    Methods that manipulate the state of a card should go in the Card class, methods the manipulate the state of a deck should go in the Deck class and methods that manipulate the state of the GUI should be in the mainGui class.

    So the AddCard() method obviously manipulates the deck so it should go in the Deck class. The ShowQuestion() method I would expect to be executed when an event is fired (e.g. the user clicks a show question button). This means that it is the GUI being manipulated and as such go in the mainGui class. If you are finding that the mainGui class is becoming bloated you can look to take code that has a common concern and put the code into another class. An example of this might be to pull all code pertaining to the visibility of information on a card into its own class but this might be a bad approach. It is difficult to determine what you could refactor without seeing the full code.

    Alternatively for ShowQuestion(), ShowAnswer(), HideQuestion() and HideAnswer() you could instead add a bool isFacingForward variable (maybe boolean/Boolean in Java) to the Card class and then you could toggle this variable to set what is visible on the card. The GUI might then just have a ShowCard() method and the Card class might have a FlipCard() method.


  • Registered Users Posts: 3,500 ✭✭✭Drexel


    Aswerty wrote: »
    Methods that manipulate the state of a card should go in the Card class, methods the manipulate the state of a deck should go in the Deck class and methods that manipulate the state of the GUI should be in the mainGui class.

    So the AddCard() method obviously manipulates the deck so it should go in the Deck class. The ShowQuestion() method I would expect to be executed when an event is fired (e.g. the user clicks a show question button). This means that it is the GUI being manipulated and as such go in the Deck class. If you are finding that the mainGui class is becoming bloated you can look to take code that has a common concern and put the code into another class. An example of this might be to pull all code pertaining to the visibility of information on a card into its own class but this might be a bad approach. It is difficult to determine what you could refactor without seeing the full code.

    Alternatively for ShowQuestion(), ShowAnswer(), HideQuestion() and HideAnswer() you could instead add a bool isFacingForward variable (maybe boolean/Boolean in Java) to the Card class and then you could toggle this variable to set what is visible on the card. The GUI might then just have a ShowCard() method and the Card class might have a FlipCard() method.

    Ya i kinda had duplicate code in the GUI class for adding the cards to the deck. I got it sorted now tho. Think I just have to keep this(Methods that manipulate the state of a card should go in the Card class, methods the manipulate the state of a deck should go in the Deck class and methods that manipulate the state of the GUI should be in the mainGui class.) in mind when creating a class.

    Thanks for your help. Much appreciated!


Advertisement