The DYNAMIC FACTORY pattern describes how to create a factory that
allows the creation of unanticipated products derived from the same
abstraction by storing the information about their concrete type in
external metadata
from : http://www.wirfs-brock.com/PDFs/TheDynamicFactoryPattern.pdf
The PDF says:
Configurability
. We can change the behavior of an application by just changing its configuration
information. This can be done without the need to change any source code (just change the descriptive information about the type in the metadata repository) or to restart the application (if caching is not used – if caching is used the cache will need to be flushed).
It is not possible to introduce new types to a running C++ program without modifying source code. At the very least, you'd need to write a shared library containing a factory to generate instances of the new type: but doing so is expressly rules out by the PDF:
Extensibility / Evolvability
. New product types should be easily
added without requiring neither a
new factory class nor modifying
any existing one.
This is not practical in C++.
Still, the functionality can be achieved by using metadata to guide some code writing function, then invoking the compiler (whether as a subprocess or a library) to create a shared library. This is pretty much what the languages mentioned in the PDF are doing when they use reflection and metadata to ask the virtual machine to create new class instances: it's just more normal in those language environments to need bits of the compiler/interpreter hanging around in memory, so it doesn't seem such a big step.
Yes...
Look at the Factories classes in the Qtilities Qt library.
#TonyD regarding
We can change the behavior of an application by just changing its configuration information.
It is 100% possible if you interpret the sentence in another way. What I read and understand is you change a configuration file (xml in the doc) that gets loaded to change the behaviour of the application. So perhaps your application has 2 loggers, one to file and one to a GUI. So the config file can be edited to choose one or both to be used. Thus no change of the application but the behaviour is changed. The requirement is that anything that you can configure in the file is available in the code, so to say log using network will not work since it is not implemented.
New product types should be easily added without requiring neither a new factory class nor modifying any existing one.
Yes that sounds a bit impossible. I will accept the ability to add ones without having to change the original application. Thus one should be able to add using plugins or another method and leave the application/factory/existing classes in tact and unchanged.
All of the above is supported by the example provided. Although Qtilities is a Qt library, the factories are not Qt specific.
Related
In order to start my C++ program, I need to read some configs, e.g. ip address, port number, file paths... These settings may change quite frequently (every week or everyday!), so hardcoding them into source files is not a good idea.
After some research, I'm confused about whether there is a best practice to load config settings from a file and made those configs available to other class/module/*.cpp in the same project.
static is bad; singleton is bad (an anti-pattern?) So, what other options do we have? Or, maybe the idea of "config file" is wrong?
EDIT: I have no problem of loading the config file. I'm worried about, after loading all those settings into a std::map< string, string > in memory, how to let other classes, functions access those settings.
EDIT 2: Thanks for everybody's input. I know these patterns that I listed here are FINE, and they are used by lots of programs. I'm curious about whether there is a (sort of) BEST pattern to handle configurations of a program.
Arguably, a configuration file is a legitimate use for a Singleton. The Singleton pattern is usually frowned upon because Singletons cause problems with race conditions in a multi-threaded environment, and since they're globally accessible, you run into the same problems you have with globals. But if your Singleton object is initialized once when you read in the config file, and never altered after that, I can't think of a legitimate reason to call it an "anti-pattern" other than some sort of cargo-cult mentality.
That being said, when I need to make a configuration file available as an object to my application, I don't use a Singleton. Usually I pass the configuration object around to those objects/functions which need it.
The best pattern I know of solving this is through an options class, that gets injected into your code on creation/configuration.
Steps:
create an options parser class
configure the parser on what parameters and options it should accept, and their default values (default values can be your "most probable" defaults)
write client code to accept options as parameters (instead of singleton and/or static stuff).
inject options when creating objects.
Have a look at boost.program_options for an already mature module for program options.
If you're familiar with python, have a look at the examples in the doc of argparse (same concept, implemented in python library). They are very easy to get the concept and interactions from.
I want my language backend to build functions and types incrementally but don't pollute the main module and context when functions and types fail to build successfully (due to problems with the user input).
I ask an earlier question regarding this.
One strategy i can see for this would be building everything in temp module and LLVMContext, migrating to main context only after success, but i am not sure if that is possible with the current API. For instance, i wouldn't know know to migrate that content between different contexts, as they are supposed to represent isolated islands of LLVM functionality, but maybe there is always the alternative to save everything to .bc and load somewhere else?
what other strategies would you suggest for achieving this?
Assuming you have two modules - source and destination, it's possible to copy a function from source to destination. The code in LLVM you can use as an example is the body of the LLVM linker, in lib/linker/LinkModules.cpp.
In particular, look at the linkFunctionProto and linkFunctionBody methods in that file. linkFunctionBody copies the function definition, and uses the llvm::CloneFunctionInto utility for the heavy lifting.
As for LLVMContext, unless you specifically need to run several LLVM instances simultaneously in different threads, don't worry about it too much and just use getGlobalContext() everywhere a context is required. Read this doc page for more information.
I'm writing an NPAPI plugin in C++ on Windows. When my plugin's instantiated, I want to pass it some private data from my main application (specifically, I want to pass it a pointer to a C++ object). There doesn't seem to be a mechanism to do this. Am I missing something? I can't simply create my object in the plugin instance, since it's meant to exist outside of the scope of the plugin instance and persists even when the plugin instance is destroyed.
Edit:
I'm using an embedded plugin in C++ via CEF. This means that my code is essentially the browser and the plugin. Obviously, this isn't the way standard NPAPI plugins behave, so this is probably not something that's supported by NPAPI itself.
You can't pass a C++ object to javascript; what you can do is pass an NPObject that is also a C++ object and exposes things through the NPRuntime interface.
See http://npapi.com/tutorial3 for more information.
You may also want to look at the FireBreath framework, which greatly simplifies things like this.
Edit: it seems I misunderstood your question. What you want is to be able to store data linked to a plugin instance. What you need is the NPP that is given to you when your plugin is created; the NPP has two members, ndata (netscape data) and pdata (plugin data). The pdata pointer is yours to control -- you can set it to point to any arbitrary value that you want, and then cast it back to the real type whenever you want to use it. Be sure to cast it back and delete it on NPP_Destroy, of course. I usually create a struct to keep a few pieces of information in it. FireBreath uses this and sends all plugin calls into a Plugin object instance so that you can act as though it were a normal object.
Relevant code example from FireBreath:
https://github.com/firebreath/FireBreath/blob/master/src/NpapiCore/NpapiPluginModule_NPP.cpp#L145
Pay particular attention to NPP_New and NPP_Destroy; also pay particular attention to how the pdata member of the NPP is used.
This is also discussed in http://npapi.com/tutorial2
There is no way to do this via NPAPI, since the concept doesn't make sense in NPAPI terms. Even if you hack something up that passes a raw pointer around, that assumes everything is running in one process, so if CEF switches to the multi-process approach Chromium is designed around, the hack would break.
You would be better off pretending they are different processes, and using some non-NPAPI method of sharing what you need to between the main application and the plugin.
I'm trying to get this thing with using different ClassLoaders to work with no success and I'm getting kind of desperate. What I'm trying to do is to launch 2 different instances of a 3rd party program that was created with several static attributes and therefore can't just be instantiated twice in my code. I've been advised to use different ClassLoaders to load the .jar file, though I don't really know how to do this. Could I maybe get some pointers on where I could start?
I also need to pass an object of my own program to this program instance and I also have no idea of how I could do this...
Thanks in advance for the help,
Andre
PS: This whole discussion started in the java forums, so there's a more detailed description of what I need to do and why I need to do this. The advice I'm referring to in this post was from malcommmc:
Another approach might be to run the
whole system in one JVM, but create a
new classloader for each instance of
the 3rd party code and make sure that
the classes containing the offending
statics are only loadable by these new
class loaders. Under these conditions
the JVM can support multiple copies of
the same class, providing the FQN is
unique within a class loader.
In this case run each instance as a
separate Thread, and set the thread's
context class loader to point to the
relevant class loader.
Presumably the object you are
proposing to pass is specified with
some interface or abstract class known
to the 3rd party app. You need that
interface to be known to the system
class loader, i.e. on the class path,
but the principal classes of the 3rd
party app must not be on the
classpath, but be accessed as a jar
referenced by a URLClassLoader.
This was already solved in the Java forums - link provided in the question
I am trying to share some data across DLLs in a project which has an extremely complicated dependency structure (numberous DLLs).
I want to be able to associate a key with some data in one part of the application, and then extract that data by supplying the appropriate key in some other part of the app. In a way, one can say that I looking for something that is similar to Java's System.setProperty()/getProperty().
I was sure that the Process APIs would give me some access to a process-wide buffer, but I had no luck. Any ideas?
(I know that the clean solution is to introduce a new DLL and to link it properly to the existing DLLs. Unfortunately, this type of solution is beyond the mandate of my team).
You don't need fancy API's for that. Windows has a much older API precisely for this kind of stuff. These things are known as "atoms". You'd use functions as AddAtom and FindAtom. By default atoms are process-wide.
To be clear here there is one exe with multiple DLL's in only one process but multiple modules. So you aren't looking for inter-process communications.
In answer I see two strategies:
use Windows API atoms which are slightly limited (basically only string data) which can work within or between processes.
If you write a DLL which contains your speculated SetProperty/getproperty functionality you don't have to compile ALL the other DLL's again (which is presumably what is beyond your team's specification) - you only need to recompile those DLL's which are currently using your new features (set/getproperty) (which is presumably within your teams power). So this seems a direct and powerful solution.