matt o
matt o

Reputation: 19

Java design accessing class variables

I have a small application containing a number of classes. The application is designed to connect to a server and send / recv binary protocol msgs.

I have this part working using a connection manager class and a message processor class. The connection manager gets instantiated and creates 2 threads one to send and one to recv msgs. On receipt of a message a new message processor object is instantiated to handle the parsing of the message.

I have now created a GUI that has connect, logon etc... buttons.

The gui creates an instance of connection manager and when the connect button is presses it calls connection manager.connect.

When the logon button is pressed it calls connection manager.logon.

the connection manager object has a Boolean called connected.

so the gui can read connection manager.connected and see true/false. now what I need to be able to do is access connection manager.connected from my message processor object which gets created inside connection manager each time a message is received. So if message processor sees a logon ack message it can set connection manager.connected = true and the GUI which created the connection manager object can read the value.

However I cant see how I can access connection manager.connected from the message processor object. I think this is possibly a flaw in my design?

code examples.

GUI creates connection manager object reading in GUI text fields

cm = new ConnectionManager(jTextField1.getText(), jTextField2.getText())

Connection Manager has a Boolean connected. It also creates a read and write from network thread

public boolean connected; 
executor.execute(new MessageProcessor(header, message, msgType));

Inside MessageProcessor I want to update cm.connected - is this possible?

Thanks

Upvotes: 0

Views: 50

Answers (3)

Sharon Ben Asher
Sharon Ben Asher

Reputation: 14338

MessageProcessor should hold a reference to its calling ConnectionManager. You can pass the reference in the constructor of MessageProcessor and store it in an instance variable:

public class MessageProcessor {
  private ConnectionManager cm;
  public MessageProcessor(ConnectionManager cm) {
    this.cm = cm;
  }
  public void process() {
    cm.setConnected(false);
  }
}

instantiating a MessageProcessor:

public class ConnectionManager {

  public void connect() {
    MessageProcessor pm = new MessageProcessor(this);
  }
  public void setConnected(boolean connected) {
    this.connected = connected;
  }
}

of course you have coupled MessageProcessor and ConnectionManager. There are (rather) complex solutions that allow you to "decide" at run time between implementations of MessageProcessor and ConnectionManager. These include the factory patter and dependency injection.

Upvotes: 1

ha9u63a7
ha9u63a7

Reputation: 6824

how are you planning to access cm from your MessageProcessor object? it's also about the communication between objects. If you have only one ConnectionManager for your send/receive threads and if you always have one pair of threads (send/receive), you can simply use public static boolean connected and upon establishing a connection you can set it to true. This is not a good solution of you have multiple thead-couples (for send/receive activities). I almost forgot until someone pointed it out, you can pass on a parameter this - reference to who is calling MessageProcessor constructor. However, this is still not very good as any change in class definition will hurt the implementation in MessageProcessor.

In simple word, yes it is possible to access/mutate connected from your MessageProcessor - you should also consider using synchronized methods to access/mutate connected. But if you need to make the solution better, you need to consider using individual connectionManager objects. @sharonbn has already shown you some examples of how to go about doing this.

Upvotes: 0

LarsErik
LarsErik

Reputation: 138

Did you create the MessageProcessor yourself? If so you could add a parameter in constructor and send a reference to the ConnectionManager:

executor.execute(new MessageProcessor(header, message, msgType, this));

Then the MessageProcessor will be able to access connected through ConnectionManager.

Upvotes: 1

Related Questions