GnarlyTot GnarlyTot - 8 days ago 6
Java Question

Java beginner troubles; calling from methods. hopefully small issue,

I'm working on this little project, I was given the driver and had to write the helper class for it.

Driver:

public class MyBookDriver {

private static final Scanner KBD = new Scanner(System.in);

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Constructors
MyBookAccount bbSheldon = new MyBookAccount("Sheldon", true);
MyBookAccount bbPenny = new MyBookAccount("Penny", false);
MyBookAccount bbAmy = new MyBookAccount("Amy", "Montreal", true);
MyBookAccount bbLeonard = new MyBookAccount("Leonard");
System.out.println("\n" + MyBookAccount.getNumAccounts()
+ " MyBook accounts have been created.");

// Mybook ID
System.out.println("\nMyBook Accounts:");
System.out.println(" Sheldon's ID: " + bbSheldon.ID);
System.out.println(" Penny's ID: " + bbPenny.ID);
System.out.println(" Amy's ID: " + bbAmy.ID);
System.out.println(" Leonard's ID: " + bbLeonard.ID);
pause();

// logged in
System.out.println("\nMyBook Accounts:");
System.out.println(" Sheldon is "
+ (bbSheldon.isLoggedIn() ? "" : "not ") + "logged in");
System.out.println(" Penny is "
+ (bbPenny.isLoggedIn() ? "" : "not ") + "logged in");
System.out.println(" Amy is "
+ (bbAmy.isLoggedIn() ? "" : "not ") + "logged in");
System.out.println(" Leonard is "
+ (bbLeonard.isLoggedIn() ? "" : "not ") + "logged in");
pause();

//post a wall message
System.out.println("\nPosting wall update:");
bbSheldon.setWallPost("I like flags!");
bbPenny.setWallPost("Looking for a job.");
bbLeonard.setWallPost("I'm just hoping I can date a girl "
+ "from next door.");
System.out.println(" Sheldon's: " + bbSheldon.getWallPost() + "\n"
+ " Penny's: " + bbPenny.getWallPost() + "\n"
+ " Amy's: " + bbAmy.getWallPost() + "\n"
+ " Leonard's: " + bbLeonard.getWallPost() + "\n");
pause();

//Sending messages
System.out.println("\nSending messages:");
bbLeonard.sendMessage(bbPenny, "Will you go out with me tonight?");
bbAmy.sendMessage(bbSheldon, "Neuroscience is a real science.");
bbPenny.sendMessage(bbAmy, "What a nice picture.");
checkMessages(bbSheldon);
checkMessages(bbPenny);
checkMessages(bbAmy);
checkMessages(bbLeonard);
pause();

//toString
System.out.println("\nDisplaying info:");
System.out.println(bbSheldon);
System.out.println(bbPenny);
System.out.println(bbAmy);
System.out.println(bbLeonard);
pause();
}

private static void checkMessages(MyBookAccount user) {
MyBookAccount aFriend;
aFriend = user.getFriend();
if (aFriend != null) {
System.out.println(" " + user.getName() + "'s message from "
+ aFriend.getName()
+ " is " + user.getMessage());
} else {
System.out.println(" " + user.getName() + " has no messages");
}
}


private static void pause() {
System.out.print("\n...press enter...");
KBD.nextLine();
}
}


And my (messy unfinished) code:

public class MyBookAccount {

public final int MAX_CHAR = 20;
public final int ID;
public static int nextId = 1;
private String name;
private String location;
private Boolean loggedIn;
private String wallPost = "(none)";
private String latestMessage = "(none)";
private MyBookAccount friend = null;
private static int numberOfAccounts = 0;

MyBookAccount(String n, String l, Boolean i) {
name = n;
location = l;
loggedIn = i;
ID = nextId;
nextId++;
numberOfAccounts++;
}

MyBookAccount(String n, Boolean i) {
name = n;
location = "Halifax";
loggedIn = i;
ID = nextId;
nextId++;
numberOfAccounts++;
}

MyBookAccount(String n) {
name = n;
location = "Halifax";
loggedIn = false;
ID = nextId;
nextId++;
numberOfAccounts++;
}

public static int getNumAccounts() {
return numberOfAccounts;
}

public void setLoggedIn(boolean log) {
loggedIn = !log;
}

boolean isLoggedIn() {
return loggedIn;
}

public void setWallPost(String newPost) {
if (newPost.length() > MAX_CHAR) {
System.out.println("Cannot update wall post for " + name
+ ". Post must be 20 characters or less.");
} else {
wallPost = newPost;
}

}

public String getWallPost() {
return wallPost;
}

public String getMessage() {
return this.latestMessage;
}

public void sendMessage(MyBookAccount to, String message) {
friend = to;
if (to.loggedIn != true) {
System.out.println("Could not post message from " + name
+ ". " + to.name + " is not logged in!");
latestMessage = "(none)";
} else if (to.loggedIn == true) {
latestMessage = message;
}
}

public MyBookAccount getFriend() {
return friend;
}

public void setName(String n) {
name = n;
}

public String getName() {
return name;
}

public void setLocation(String location) {
this.location = location;
}

public String getLocation() {
return location;
}

@Override
public String toString() {
if (friend == null) {
return "MyBookAccount #" + ID + "{\n "
+ name + " in " + location + "\n "
+ "About me: " + wallPost + "\n "
+ "Logged In:" + loggedIn + "\n ";

} else {
return "MyBookAccount #" + ID + "{\n "
+ name + " in " + location + "\n "
+ "About me: " + wallPost + "\n "
+ "Logged In:" + loggedIn + "\n "
+ "Message from " + friend.name + ": "
+ latestMessage + ".\n";
}

}
}


I just can't figure out one thing.

In the messages part, I' getting the from and to people mixed up.
For example; It should say

Sending messages:
Could not post message from Leonard. Penny is not logged in!
Sheldon's message from Amy is Neuroscience is a real science.
Penny has no messages
Amy's message from Penny is What a nice picture.
Leonard has no messages


and I get:

Sending messages:
Could not post message from Leonard. Penny is not logged in!
Sheldon has no messages
Penny's message from Amy is What a nice picture.
Amy's message from Sheldon is Neuroscience is a real science.
Leonard has no messages


Any ideas on how to remedy this?
Thanks a bundle.

Answer

I'm not trying to debug your code here, but let me just make a remark on this:

public void sendMessage(MyBookAccount to, String message) {
    friend = to; 
    if (to.loggedIn != true) {
        System.out.println("Could not post message from " + name
                + ". " + to.name + " is not logged in!");
        latestMessage = "(none)";
    } else if (to.loggedIn == true) {
        latestMessage = message;
    }
}

This code smells, because it will not send any message, but just alter the state of this (the sender's) object ( friend = to, latestMessage = ...). Plus it checks the conditions of the receiver, while the message should just send a message and react on any bad outcome. Rather imagine something like this:

class MyBookAccount {
    //....
    public void sendMessage(MyBookAccount receiver, String message) {
       try{
         receiver.accept(this, message);
       }catch(MessageRejectedException e){
         //maybe put in queue to try again later, or log the date, time and reason of failure.
       }
    }
}

where:

class MyBookAccount {
  private final List<String> receivedMessages = new ArrayList<>();
  ...
  public void accept(MyBookAccount sender, String message){
      if(!loggedIn){
        throw new MessageRejectedException("not online");
      }
      receivedMessages.add(message);
      //you can also have a list of Objects that are like 
      //class Message{String senderName; String message; Date reveived; /*...*/}
      //trigger UI update or fire property changed event that announces the list of messages has changed
  }

  public Optional<String> getLastMessage(){
     return receivedMessages.isEmpty() ? Optional.empty() 
             : Optional.of(receivedMessages.get(receivedMessages.size()-1));
  }

This way the receiver of the message has full control over the conditions that it needs to receive a message, or how many messages it likes to keep, or if it likes to record a date with the message (when the message was received). The sender does not care, whether the receiver is just a proxy, the receiver itself or what conditions have to be met to send the message, it just has to handle the possible error conditions (which can be many) - and it is free to ignore or log them as well.

Comments