I'm part of a team designing the server for a client/server model naval warfare video game (University course). We have a fairly concrete (well, I think) system design, but there is one aspect that bothers me.
The basic layout of the system is:
Server [thread] (handles incoming connections)
|
Game [thread] (deals with game events in it's work queue and sending messages to clients)
|--Environment (holds environment variables, deals with collision)
|--Client(s) [thread] (handles incoming messages from client sockets and adds events to the Game's work queue)
|--Ship (holds game data, eg: hit points, fire power, etc)
|--Parser (parses client messages and creates game event objects)
|--GameEvent (event objects held in a queue that can preform appropriate work and send appropriate responses to clients)
Now, my issue is that both Client and GameEvent (and probably Environment, once we get to it) need a reference to the Game object that they belong to.
Clients need to add GameEvent's to the Game's work queue.
GameEvent's need to access other game data (other Client's Ships, Environment).
Is there a better/more conventional method instead of having these objects store a local reference to their Game? What about declaring all of Game's methods as static? We only need to handle one game at a time, so there wouldn't ever be more than one instance of Game...
I'm sure there is a convention for a system with one central object that has many helper objects that need to reference it.
Did you consider using a Dependency Injection framework like Guice? There you have config classes called "modules", where you bind your interface Game to an implementation (you can decide if you want a singleton or new instances). A Client class would look like
public class Client {
private final Game game;
#Inject
public Client(Game game) {
this.game = game;
}
...
}
You can construct this class as usual, providing a Game instance (e.g. for testing, using a mock Game class). But if you let Guice create this instance for you (which doesn't need to be directly, it works as well if another class injects Client), you get automatically the instance specified in your Guice module.
I know it takes some time to wrap your head around that concept, but I can confirm that this leads to cleaner, more flexible code.
If there's really only logically ever one instance, you can use a singleton. The canonical form of a singleton is:
public enum Singleton {
INSTANCE;
// fields and methods here
}
That way, you don't have to shoehorn everything into static methods (though, if you want to write static methods that reference INSTANCE, that's fine too). Any code that wants to access the singleton just uses Singleton.INSTANCE, and you don't have to pass it around if you don't want to.
Passing the reference around will keep your options open, it can still be a reference to an actual static object. Also the concept of a request context might be useful, an object that holds all references needed to process a single request, and you pass that around.
Check out Inversion of Control (IOC) and containers.
That way, in your Client and GameEvent classes, whenever you need access to the Game, you just do something like:
var game = IoC.Resolve<Game>();
And then use the game instance methods...
I would strongly advise not using a singleton or a static class in your design. There are lots of reasons for this, but the one that will probably affect you most immediately is that it makes things very hard to test. At testing time, there will probably be more than one instance of Game.
A common convention to ameliorate having one big central object with lots of helper objects is to try to avoid one big central object. You note that there are different clients of 'Game' with different needs. Maybe your interface on Game is too wide.
There's nothing wrong with passing references to a constructor and storing them. You should also introduce an interface that will mediate access between your Game and your client and environment objects.
Related
I am working on a Java 2D game for which I am using AWT graphics, a JFrame and a JPanel. I would like to know where I should store some non-final but globally accessible (I need to be able to read/change these variables from every other Object/Class) variables to coordinate e.g. the width and height of the game's panel, which I want to be able to change in a little settings menu within the game.
At the moment, I am storing these variables in a separate interface which most of my other classes implement, but this means I cannot change the variables as they are all final.
As I see it I have two options:
Put all these variables as static, non-final ones in my main game class and access them via Game.PanelWidth
OR
Create a separate class just for these variables and access them like this: Variables.PanelWidth, where "Variables" would be that new class' name.
Which method is better, or should I use a completely different approach?
Without going through your code, it's hard to provide a specific response.
General recommendations:
At the moment, I am storing these variables in a separate interface which most of my other classes implement, but this means I cannot change the variables as they are all final.
It's not a good idea to use inheritance to access your settings. For this reason alone I think either of the options you're considering is an improvement as it uses composition instead of inheritance.
You should consider applying the Single Responsibility Principle.
Who is responsible for managing your game's settings? Maybe a Properties object.
Who is responsible for constructing such an object? Maybe the main method.
If you apply this principle, hardly any of your classes should require access to the PanelWidth property.
Specific recommendations:
Java provides a Properties class. This class is both thread safe and easy to use when loading/storing properties to files.
From the Javadoc:
This class is thread-safe: multiple threads can share a single Properties object without the need for external synchronization.
Rather than creating a static properties object, consider constructing the properties object in the main method (basically, poor-man's dependency injection)
The choice is largely up to you and should be driven by a balance between complexity and the actual needs of the application.
The interface you mentioned is a known anti-pattern Constant Interface - generally frowned upon because you litter the inheritance tree and namespace everywhere with information that should remain encapsulated. It does work though and in small projects it may be acceptable.
A separate class is a better approach, it solves at least the namespace litter. Make its constructor final to prevent accidental subclassing.
Generally, static members can work in small projects, but it can turn out to be impossible in case the project grows and it turns out that the variables aren't really application global, but only use-case global. Refactoring such a case can create a lot of work later.
Using an actual instance of the "global" settings class prevents this from the start, the cost is that you need to pass the instance around to where it needs to be accessed (e.g. as constructor parameter).
Next is threading and the issue of communicating changes to those global variables. Unless your application is running in a single thread (that would be the case in a purely event driven swing application), you cannot simply make changes to values and expect the change to take effect properly at every dependency site (imagine just having read panelWidth, but before you can read panelHeight new dimensions are set). You need a way to prevent these situations. So simple members are out. You'll want get/set methods that ensure only complete information is read and that writes of related values are atomic.
The atomicity can be ensured by encapsulating related values into a composite object, e.g.: Instead of panelWidth, panelHeight you have a panelDimension. No getters/setters for the individual values, are provided. You can only get the entire Dimension (for reads) or replace it with a new dimension (for writes). The actual member can be either volatile, of the AtomicReference variety or protected by making getter/setter synchronized.
To properly communicate changes to every dependency site, you may need some notification mechanism, so either the entire global state or individual parts of it may need the ability to register listeners and notify those listeners on changes (again threading issues are to be considered, since listener callbacks are usually implemented on the thread making the change, which may need consideration in the listener called).
I have a question about how to approach a certain design. I am creating a chat client a application and my implementation has several GUIs, One for Login screen, 2nd for register screen, third for the chat GUI. I want to have one thread starting when when the login screen starts that is the ConnectionHandler, basically it will send all commands to the server, based on a SynchronizedQue which i want to wrap in a MessageQue object which will be a static, one off object. The idea is to have this thread running through out the lifetime of the application.
Basically the login screen will send a message to the SynchronizedQue and then the ConnectionHandler reads that it has been updated, takes the message to a socket and sends it away.
Is it a correct object oriented approach to this case? I have read that static objects, variables etc are not a correct object oriented approach. Basically the question is about a design philosophy for implementing a one off components that sit in memory and other classes communicate with it.
EDIT:
Another idea that just popped into my mind at the time of writing this is to put the static object MessageQue in to a MessegeQueHandler class, so the MessegeQueHandler class can be created at will but the messege que will exist in the background which could be a little bit more object oriented.
Thanks for the guidance.
What you describe is the Singleton Pattern and is a very common pattern used in both OO design and other paradigms. So yes, it is OK to use it in OO design.
I'm using an API providing access to a special server environment. This API has a wide range of Data objects you can retrieve from it. For Example APICar
Now I'd like to have "my own" data object (MyCar) containing all information of that data object but i'd like to either leave out some properties, augment it, or simply rename some of them.
This is because i need those data objects in a JSON driven client application. So when someone changes the API mentioned above and changes names of properties my client application will break immediatly.
My question is:
Is there a best practice or a design pattern to copy objects like this? Like when you have one Object and want to transfer it into another object of another class? I've seen something like that in eclipse called "AdapterFactory" and was wondering if it's wide used thing.
To make it more clear: I have ObjectA and i need ObjectB. ObjectA comes from the API and its class can change frequently. I need a method or an Object or a Class somewhere which is capable of turning an ObjectA into ObjectB.
I think you are looking for Design Pattern Adapter
It's really just wrapping an instance of class A in an instance of class B, to provide a different way of using it / different type.
"I think" because you mention copying issues, so it may not be as much a class/type thing as a persistence / transmission thing.
Depending on your situation you may also be interested in dynamic proxying, but that's a Java feature.
What are best practices in defining access controls for methods in MVC pattern. I'm uncertain where to use static methods in a scenario like an ATM (client-server model). I'm using Java.
Appreciate if someone can shed some light on this.
Here's my approach I used to come up with a class diagram.
First I designed all the screens, sketched on a paper. (I'm kinda
artist if you wonder and into graphic design stuff :) )
Then I created View classes Created Model classes by studying the scenario
and use of data
Created Controllers for each Model and some more additional ones
Added methods to Controllers by looking at the buttons I got in the screens, which I think a straight forward way to never miss any method? + some additional ones for GUI controlling
etc.
What do you think about my approach?
Thanks.
I don't see what MVC has to do with it. A static method cannot access instance variables. Therefore static should only be used for methods that receive ALL their necessary data via parameters. Usually this is "utility" routines such as sort routines, formatters, common calculations, etc.
The other place where you might use static routines is to access static variables in a class. But it's rare that you want to do this without also accessing instance variables.
Note that there's no real requirement to make any routine static -- you can have an instance method that doesn't reference any instance variables. But a static method becomes accessible from situations where you don't have an instance handy to invoke the method.
I have three classes interacting in an interesting way. One is a model class, and it has to be accessed by both of the other classes, so a single instance of it is kept as a member of each. Both of these classes interact with the model in different ways.
There are a couple of instances where the model object has to be completely thrown away and replaced with a new instance, and this complicates things. And these occasions arise in both of the viewing/controlling classes. So, either one of those classes has to be able to send a signal to the other saying "We need to coordinate and facilitate the replacement of our Model object with a new Model object." Right now I have code in class B to tell class A to construct a new Model and send it back, but now I need to handle the opposite situation, where the event arises in class A, and unfortunately class A does not have a reference to class B and probably shouldn't.
What's a good way to handle this?
Update: Sorry, folks, this can't be a singleton. Singletons are when you need to guarantee there's only one of something. That has nothing to do with any of the requirements I expressed above. This class is not a singleton and shouldn't be.
Update: Up till now, there has actually only been one instance of this Model class, but I had a vague suspicion I needed to allow for more, and I didn't want to limit myself by using the Singleton design pattern when that actually addresses different concerns from what I have. Turns out I was right: yesterday I received a new requirement and now I need support an arbitrary number of these. :) Don't limit yourself when you don't have to, and don't misuse design patterns for situations where they were not intended!
You'll want an intermediary model layer, a model "holder" object that each of the two classes reference. The ModelHolder holds a reference to the model.
This ModelHolder should also support listeners, so when its model is thrown out, it can notify any listeners that the model has changed.
Ok, if you need to change the model (but not force) you can make a listener interface, and make both objects A and B implement it:
public interface ModelListener {
public void modelChanged(Model newModel);
}
and at the proper time you can notify the listeners of the new model change. You can also have a list that holds all the registered listeners.
List<ModelListener> modelListeners = new ArrayList<ModelListener>();
public void setNewModel(Model m) {
for (ModelListener aListener : m.modelListeners)
aListener.modelChanged(m);
}
As always there are tradeoffs between simplicity and robustness. You might want to experiment with the levels you need for your own case.
I encounter this design issue often in GUI projects (Swing, GWT). What I usually do is create a higher-level "State" model, which holds an instance of the object that is shared between 2 or more classes. State then has a ModelListener interface, which the other classes can implement to get notification of changes to the underlying model. State.setFoo() then fires ModelChanged events to the listeners, which respond accordingly.