Singletons
I'm making a chat client that I plan to be reusable for many different chat servers and protocols. It has a complex GUI. I find myself making lots of Singletons, such as one for setting server aspects, one for updating graphical components (I'm separating my GUI from the rest of my program), and perhaps one for a Client class which relays instructions from graphical components to more knowledgeable Event objects.
Are these many Singletons a sign of design flaw?
[481 byte] By [
dynobirda] at [2007-10-2 3:57:55]

> I'm making a chat client that I plan to be reusable
> for many different chat servers and protocols.
Okay. Though many of these programs, such as Trillian, do already exist.
> It has a complex GUI. I find myself making lots of
> Singletons, such as one for setting server aspects,
> one for updating graphical components (I'm separating
> my GUI from the rest of my program), and perhaps one
> for a Client class which relays instructions from
> graphical components to more knowledgeable Event
> objects.
>
It sounds to me like you need a better Controller in your MVC architecture. In a single-user application, Singletons are not necessarily an evil. However, they do 'smell' like global variables, which can be a sign of a poor design.
Consider refactoring your multiple singletons into a Controller object (normally it 'lives' on the top-level Frame of a GUI application). You can then provide standard methods in the controller that are handling the functionality your Singletons currently are involved in.
> Are these many Singletons a sign of design flaw?
See above.
- Saish
Saisha at 2007-7-15 23:19:33 >

> SWLeadership
> You sure have been working on this chat client for a
> long time. When do you think you will be done?
I actually took a break from this specific project to better learn OOA/D. I also worked on a series of much easier projects in order to practice design. Was that question necessary?
> Saish
> Consider refactoring your multiple singletons into a
> Controller object (normally it 'lives' on the
> top-level Frame of a GUI application). You can then
> provide standard methods in the controller that are
> handling the functionality your Singletons currently
> are involved in.
Hm, I never thought about how my structure looked relevant to an MVC. I never planned to make one big MVC, but instead many small ones. It sucks that they don't let you post images, so I'll have to describe it.
I had my graphical controllers talk to my model, which was a Singleton called Client. Client then talked to my Event structure, which is another set of controllers. The Event controllers. then talked to my views.
So it went graphical controllers -> model -> event (protocol) controllers -> views. But then again, my graphical controllers also had to talk to my views. So it really isn't MVC at all, but by looking at it isn't pretty, and sort of spells "Singleton."
I thought about making my Client be my Model, but how could I make my views reflect the state of the client? Perhaps my model would be Client plus the Event hierarchy.
Anyways, here's an actual question, that was just pondering. So my standard methods in my top Controller object will be static methods that return the graphical components?
Sorry, one more question.
Is a program supposed to be one big MVC, many small MVC's, or either design? Is it best to have it one way or the other?
For example, take this situation:
I have a Controller object at the top of my GUI hierarchy, a model that includes a Client "Mediator" (I think that's the right word) that relays stuff to an Event structure, which is also part of my model, and my views just being a chat screen, title bar, buddy list, etc.
(Continuing from that situation)
Now let's say I was to make a Games object with a bunch of games. Should I incorporate this into my big MVC as an addition to the model, perhaps another object that Client talks to, or should i make a new MVC for it?
The design pattern itself is MVC, and it normally applies application-wide. However, in implementing the pattern, you do end up with 'mini-MVC's'. (Though I never thought of it that way). Basically, you have to separate two concepts: client and server versus MVC.
In MVC, your model is quite simply your application data. At least in an ideal world, your model could exist totally separately from your user interface. It is what makes your application unique. At least conceptually, I should be able to add a J2EE controller and view to your application (making it a web application) without having to modify the model. The model is where you should focus the majority of your efforts.
Now, we have the model down. What about the view and controller? In practice, it is difficult to separate view and controller. The view presents model data to the user. The controller responds to user requests. In effect, the controller is the 'plumbing' of your application. The controller determines what type of action the user is requesting, performs the relevant operation(s) on the model, and then dispatches the request to the appropriate view, normally passing the view model data.
So, here is what you have (ideally): a model that really exists on its own and can be tested separately, even from a command line. Your view is dependent on the model, which makes sense, the view can only display data it is given. You could have multiple views for the same set of model classes (think administrator interface versus guest user interface). Each view type will normally have its own set of controller classes. If you do support multiple view types, some controller functionality can be abstracted into common or application controller classes.
So, within your Swing application, you model data is whatever it is your system is tracking, doing, monitoring, etc. Your views are JFrames, JDialogs, JLabels, etc. Your controllers are your event listeners and menus (you can see how it is a bit difficult to separate the concepts of view and controller here).
Your controller typically lives at some top-level object, such as the main JFrame or the class that started the application itself via a main() method. I believe you can eliminate many of your Singletons by placing them in a common controller class. Your listeners will invoke methods on that class which will in turn delegate these requests to your model classes.
Within a Swing GUI application, you can also leverage the Observer-Observable pattern and have the model (or the controller) 'inform' relevant views of changes to model data or state.
- Saish
Saisha at 2007-7-15 23:19:33 >

>Your controller typically lives at some top-level object, such as the main >JFrame or the class that started the application itself via a main() method. I >believe you can eliminate many of your Singletons by placing them in a >common controller class. Your listeners will invoke methods on that class >which will in turn delegate these requests to your model classes.
I like the idea of a common controller. I just want to make sure we're on the same page.
My CommonController will obviously have to implement my Model's interface, so that my subcontrollers are able to talk to my Model through my Common Controller.
This means that my Common Controller will have to have to have static methods and a static Model datatype, since my subcontrollers/listeners need to be talking to the same CommonController. So, in order to achieve the goal of a Common Controller, should my Common Controller have static methods (which grant model-changing requests from my subcontrollers) which communicate to a static Model field in my CommonController?
> >Your controller typically lives at some top-level
> object, such as the main >JFrame or the class that
> started the application itself via a main() method. I
> >believe you can eliminate many of your Singletons by
> placing them in a >common controller class. Your
> listeners will invoke methods on that class >which
> will in turn delegate these requests to your model
> classes.
>
> I like the idea of a common controller. I just want
> to make sure we're on the same page.
>
Just so we are on the same page. It does not have to be a single class. You could, maybe should, have a single class to manage the listeners, create the appropriate view, initialize any model set-up paremeters, etc. However, any number of actual classes may act as controller classes.
> My CommonController will obviously have to implement
> my Model's interface, so that my subcontrollers are
> able to talk to my Model through my Common
> Controller.
>
No. The model is the model. If you have another set of classes implement model interfaces, this is normally called a facade. It is designed to abstract away complexities in your model to callers (or to provide more efficient remote API methods). Sometimes, this is referred to as a 'service layer'.
Subcontrollers and controllers are an interesting hint at another idea: design patterns. Take a look at Struts. In many J2EE applications, the Servlet serves as a controller.Struts has a common controller that delegates to, in your terminology, sub-controllers call Actions. Each command in the application is given its own Action class with invokes model functionality and dispatches the results to a given view (normally a JSP page or HTML page).
Now, the above does not map exactly to a Swing user interface application. But think of what your application does. There are commands or actions that will change model data. This might be 'add new user', 'delete folder', 'start new game', etc. You will undoubtedly have menu items or buttons or dropdown selections that invoke these actions. The controller's responsibility is to handle that request and return to the user an appropriate response. In a Swing application, you would have a dedicated Listener class responding to UI events, invoking specific functionality and either updating the current view or opening a new window/dialog/view for the user.
The controller does not have to implement the model's interface. Indeed, a controller, as the above discussion hopefully hints at, is tied somewhat to the underlying model. A Swing controller and a J2EE controller have similarities in that they are controllers, but both respond to different types of events. And ideally, both are optimized to handle requests from the view(s) that invoke them.
A controller is the plumbing of your architecture. You can have a single controller performing a single task 'logon user'. Or you can abstract the concept such that you have a centralized controller invoking a series of API commands. Either way, the controller's interface may differ, and often offers significant benefits, when it is optimized for its particular task.
The model, on the other hand, ideally, exists apart from any user interface. It represents the business rules or functional specification that makes your system unique. You should be able to test the vast majority of your model code from the command line, apart from any user interface. The reason is that a given model component may have many different views (and probably, hence, many different controllers invoking it). Tying a model component to a particular user interface lets the UI drive the design of the heart of the system. Sometimes, this is a good 'first cut' at a design, but it should not be a driving precept, IMO.
> This means that my Common Controller will have to
> have to have static methods and a static Model
> datatype, since my subcontrollers/listeners need to
> be talking to the same CommonController. So, in
> order to achieve the goal of a Common Controller,
> should my Common Controller have static methods
> (which grant model-changing requests from my
> subcontrollers) which communicate to a static Model
> field in my CommonController?
Now you've totally lost me. Static versus non-static is an implementation choice. I will admit, it is somewhat more convenient, in terms of saving keystrokes, to invoke a static method than an instance method. There may also be slight, though probably negligable, benefits in terms of garbage collection if the method in question truly can be written stateless. However, I do not see how this would apply in your situation.
When you start thinking that most of your classes should have all static methods, I have a strong hunch that the design is flawed and not truly object-oriented. A profusion of Singletons is another (potential) bad smell.
Objects 'talk' to each other, at the simplest level, through references. If a given UI component (view) needs to be able to invoke controller functionality, then pass the controller to the view's constructor so it can invoke methods back on the controller. Or, write the controller such that the view can either call a constructor and then a method, or simply a method in one go, with enough information to complete its request. Whenever one object 'needs' another object, either pass the requried object to the dependant object via a constructor or a method parameter.
- Saish
Saisha at 2007-7-15 23:19:33 >

