I have a bit of code which uses a plugin and core model, revolving around four major objects: the Core, Server, Logger, and Parser, in slightly particular order.The Core acts as the central factory, with a catch: it's bound to a single render context (much of this is graphics related, but the other details are not important). The objects it creates and manages are specific to that core, and multiple cores can be created with different contexts. Cores can never share resources with each other. The Core is initialized from a configuration file; more on this later. The Core must have, from its creation, a Server, Parser, and Logger.The Server handles loading and initializing all the plugins, as well as creating objects from them. It acts as a single, in-process plugin server and object registry, similar in many ways to a STA in-process COM server. As plugins are loaded into the process, not a particular Core, I'm fairly sure this is appropriate. The Server must have a Parser and Logger.The Logger handles logging messages, particularly errors, to disk. It does very simple pre-formatted file writing, with some basic log level filtering. The Logger requires a Parser for resolving file paths.The Parser handles variable replacement, particularly in paths. For example, a plugin may request the file $(root)/resources/a.txt and the Parser will replace that with the application's root directory; or $(startup)/a.txt for the startup directory. Simple stuff. Variables are contained in the Parser itself, and many are specific to the thread. However, a few are tied to a single Core, and thus enters the...Config file. Each Core is initialized from a config file, which contains a multitude of settings: plugins for the Server, variables for the Parser, and a file for the Logger. Each Core can use a different config file, and most likely will.In my current model, the Server, Logger, and Parser are singletons. They all must provide a single global instance, accessible from the core and plugins (and each other), potentially before a Core has been created. All handle process-level functions, but the Logger and Parser do handle some Core-level functionality.The issue with this is that, in order to make the Logger and/or Parser Core-specific, the Server would then need its own instances, which would be potentially lacking important characteristics (like what file to use for the Logger). The Server also handles work that is very clearly common to the whole process: there's just no way to load a plugin into a single Core, that's not how shared libraries work.In a previous version, I had all four of these created when a Core was created, and belong to a specific Core. This caused some issues and oddities, however: the Core loads itself as a plugin when it starts up, but the Server had the same lifetime as the Core, making this seem odd. The Parser has a number of variables that belong to the process: the initial directory, root directory, and so on. The Logger must precede the Core in some way, particularly the plugin-loading stage, so errors can be accurately logged.My questions then are:Is this setup too over-engineered? The separation of responsibility between objects seems good, but perhaps too split.What design pattern(s), be it singleton or otherwise, is/are appropriate in this case, for these objects? 
What other patterns can I use for this singleton?
design patterns;architecture
Here are my points: There is a difference between having only one instance of the object in the entire application vs. an object becoming singleton so that any one calling new() will magically find theInstance. In your case, there is no benefit of having server being singleton because no one is creating server other than main(). It's just plain simple to have it as ordinary object. Even if it is singleton, it will be called only once! Parser should never be singleton either for a different reason here. If i understood correctly, parser's only role is when core is launched; Ideally it should follow use-and-throw pattern rather than singletonEven parser continues to serve some specific queries till core wants it, by design parser should be one instance per core because same instance of parser should never share information about various different cores. It makes parser dedicated per core.Most people design logger as a singleton. It is not really much big deal, however, if you are a multi-threaded system a singleton logger is a big villain. First off, every singleton needs to be threadsafe. Suppose even if you make it thread safe, every time a thread x calls logger it is busy doing printf for thread y so as a result thread x waits whereas ideally you should be worrying about getting the maximum out of your quad-Core system and serve as many requests as possible.Ideally the only genuine case where logger should be centralized or singleton is where the exact order of events must be registered one-by-one. For most purposes, different files and messages with their own timestamps are usually better even for debugging.So for me Server (which is one instance) is created by main() and core, parser and logger are a tuple that is born and dies per request (always together). Each tuple doesn't know the state or existence of other such tuples, and that is good so that arbitrary number of threads can be instantiated in parallel, (one thread per tuple) without losing scalability but preserving loose coupling.Only thing is - it means you are not using any design pattern! But that's not a bad thing. It is not necessary that including a design pattern makes your design necessarily better. Remember:There are really rare reasons where using singleton becomes must;  everywhere else, using singleton is always an invitation to problems.