Getting rid of singletons?
I'm writing a web app that is getting too complex and I'd like to simplify how my components work together. I have a few singletons that "know" about all the objects they have to do with.
For example I have a windowSystem
that holds an array of all the window
objects that exist. All of the windows don't know anything about each other but I have this irritating singleton there for things like a closeAllWindows()
function or if(sameWindowExi开发者_JS百科sts()) { return }
-type things that (I think) require some sort of way to keep track of all the windows
. I create one windowSystem
instance when my program starts.
It feels like these are unnecessary because they know more than they should. What other options do I have?
Edit: Here is some code that shows the creation of various _____System
s
var refDate = usDate.now();
var eventSystem = usEventSystem($("#topLevelElement")),
backend = usBackend(eventSystem.trigger),
windowSystem = usWindowSystem($("#windows"), eventSystem.registerEvent),
timelineSystem = usTimelineSystem($("#view"),
backend.getEvents,
usDate.now().shift({ hours:-6 }),
usDate.now().shift({ hours:6 }),
eventSystem.registerEvent,
eventSystem.unregisterEvent,
windowSystem.createWindow);
usWindow.setRegisterEventFunc(eventSystem.registerEvent).setUnregisterEventFunc(eventSystem.unregisterEvent);
What I really dislike about it is that I'm passing lots of functions from other systems into each other (and they in turn pass those on to the objects -like a window
- they create) which doesn't seem to scale well.
Instead of having your window managing logic in a singleton sitting above the windows you could try transferring it to a base class that all windows inherit from. It could look something like:
function BaseWindow() {
//whatever common constructor logic you may want
//such as creating an id
this.id = this.id + 1
}
//this is static
BaseWindow.activeWindow = null;
//this is a property visible to each window instance but is updated by the base class
BaseWindow.prototype.id = 0;
//this is a property visible to each window instance but may be overridden by a subclass
BaseWindow.prototype.name = "BaseWindow";
//this is function visible to each window instance
BaseWindow.prototype.show = function ( ) {
//hide BaseWindow.activeWindow then show "this" window;
};
function WindowA() {
//do some window specific stuff like set the window name
this.name = "WindowA";
}
WindowA.prototype = new BaseWindow;
Manual dependency injection could be provided by one singleton. I know you are trying to get rid of those, but if you had a single one that tracked all your interesting instances (like windows) you could say something like Injector.get("Window", "Debug");
to grab whatever window instance your Debug code wants. This still gives you injection--a different window could be provided to the Debug class if needed, and the configuration of provided class instances could be configured in a number of ways (Data, hard-coded, etc).
You could also then use Injector.getAll("Window")
to get and close them all.
I realize you've still got a singleton, but at least it's just one and it provides you some flexibility down the line to reconfigure your classes in one place.
精彩评论