   factory pattern
  Hy i read an article that explain how create object from a .txt property file like this:CoreObject Class=HumanoidResource{  Name = Ramirez  Model = models/soldiers/ramirez  Speed = 5  …}It mean that use factory pattern for create the object.How is applyed the factory pattern in this case?I'm not understand if i must use factory method or abstract factory.Thanks   
  I'd say you should use a (meta) factory that understands the contents of the txt file.Depending on the language you are using you could register a concrete factory for each class name you want to support, get the appropriate factory and supply it with the other parameters in the file.Another other way (in languages that support runtime reflection, like Java) could be to set the fully qualified class name and create an instance via (Note: this is Java code) Class.forName(<className>).newInstance() and then set the parameters via reflection, too (get the field with the specified name from the class or its super classes, determine the type of the field and parse the parameter value accordingly and finally set the parameter).   ;  Parse the value pairs between { and } into std::map<string, string>.Define a base class. Then do something like this:CoreObject * create(fstream & f) {  std::string type = // parse the type  std::map<std::string, std::string> parameters; // parse parameters  if (type == "HumanoidResource") {    return new HumanoidResource(parameters);  }  if (type == "AlienResource") {    return new AlienResource(parameters);  }  ...};Each of your classes then parses parameters in constructor:class HumanoidResource : public CoreObject {public:  HumanoidResource(const std::map<std::string, std::string> & params) {    name = params["Name"];    model = params["Model"];    speed = params["Speed"];  }};;Quote:Original post by AntheusParse the value pairs between { and } into std::map<string, string>.Define a base class. Then do something like this:CoreObject * create(fstream & f) {  std::string type = // parse the type  std::map<std::string, std::string> parameters; // parse parameters  if (type == "HumanoidResource") {    return new HumanoidResource(parameters);  }  if (type == "AlienResource") {    return new AlienResource(parameters);  }  ...};Each of your classes then parses parameters in constructor:class HumanoidResource : public CoreObject {public:  HumanoidResource(const std::map<std::string, std::string> & params) {    name = params["Name"];    model = params["Model"];    speed = params["Speed"];  }};That would require the factory to know all possible classes, wouldn't it?If you registered a concrete factory for each "class name" you could extend the list later on.;  I guess you could have a container that maps strings to factory functions, and you could populate it at initialization. You could even have some global objects (like a static member in each class) whose constructors would take care of registering the factories for you.However, Antheus's code is easy to understand, and I have grown very fond of that type of code over the years.;Quote:Original post by Lord_EvilThat would require the factory to know all possible classes, wouldn't it?Yes, every factory needs to know all possible classes. In some languages, it is possible to construct the class code during run-time, but this is rarely done.In managed language, class loader (or related concept) is the one that "knows all possible classes", even if introspection is used.Quote:If you registered a concrete factory for each "class name" you could extend the list later on.Yes, you could. It depends on language as well. But my point was this:Quote:However, Antheus's code is easy to understand, and I have grown very fond of that type of code over the years.It's simple, it works, is easy to extend.If at some later point it becomes unwieldy, it's still factory pattern, and its implementation may be changed to use a table lookup.Quote:Class.forName(<className>).newInstance() I will tell you from practical experience of having built systems on top of this, that I am not a fan of such approach. It's generic, it's extensible, and it's an absolute pain in the ass to maintain.Things end up looking like this://some_config.txtfoo=com.baz.fubarbleh=com.etc.nexta= // <-- what goes here?There is no way to figure it out, especially not for non-coders and coders not involved in the project. Documentation gets out of sync, classes are added (just temporarily) or removed, there are multiple versions, etc...In practice it worked like this. Since classes were loaded when needed, no parsing was done before hand. So there you have your server running on saturday evening, when it decides to load a non-existing class. And bam... What follows is late night telephone call from sys admin, cursing the Java for spamming the logs with 268-line exceptions about incomprehensible nonsense full of dots and coms.Of course, the developer who was commiting the latest build missed that they typed com.baz,foo.ExceptionalyFlexibleClass.The problem was solved by spending dozens of hours writing unit tests that validated the configuration files.Best thing - even though this system was so flexible, there have only ever been three different instances that were implemented. To this day, incredible extensibility is touted as one of paramount features of this flagship product. Right - three (3) instances, and dozens of hours lost to administration.Don't over-design. The whole system above took probably over 100 hours to design, develop, debug, administer, repair, etc.... For what was a factory method that returns three (3) different instances and could be implemented in 8 lines.Long story short. I prefer compile-time checks wherever possible. In Java, there is no static initialization order problems, so just have your concrete classes register with factory.   ;  Back up a second from using language-based classes.A class, in the design patterns sense, is nothing more than a category of objects that share a certain set of properties.Many languages implemented this at compile time.  Doing things at compile time is really good, because you can isolate the points of "type failure" to runtime type transformation points (like create).  Otherwise, "type failure" can happen at any point in the code.On the other hand, depending on how your classes work, they might differ only in the values of some data.  If they differ only in data, then the name of the class can be nothing but another string of data that the in-language class stores.The entire factory could be implemented by a simple .clone() method on an instance of the CoreObject which registers itself with the factory under "HumanoidResource".  You create new HumanoidResources by calling "clone()" on the registered HumanoidResource.This depends if you want your config files to be describing "what a humanoid resource" is, or if you want the config files to be describing "this is a humanoid resource with these properties".If your config files are defining classes (like humanoid resource), you should probably go with the create/register/clone pattern.If your config files are just defining instances of classes (like Bob, the HumanoidResource), you should go with creating compile-time defined classes with parsed parameters.And you should be cautious about having your config files define classes.;Quote:Original post by giugioHy i read an article that explain how create object from a .txt property file like this:[...]In win32 you can use plugin dlls and load them in runtime, so you would have a HumanoidResource.dll with the class implementation and a factory function:CoreObject* Create(std::string sFile){    return new HumanoidResource(sFile);}And in the application:[...]    std::string sClassType = GetClassFromFile(sFile);    sClassType.append(".dll");    HMODULE hLibrary = LoadLibrary (sClassType.c_str());    FARPROC fp = GetProcAddress(hLibrary, "Create");   CoreObject* Obj = fp(sFile);Of course, this is not portable and i don't know how it would be done in other platforms.Hope this helps.EDIT: Make sure to check for errors if you go this way.   ;  You are probably better off abstracting the plug-in system a bit further (ie, not doing the DLL loading right there in the middle of the rest of the code -- rather, having a place where plug-ins are loaded and asked them to register factory functions, and then just talking to the registry).However, doing all of this falls into the "yPWNit" -- you probably won't need it -- category.Write the "create object by type and arguments" function.  It can be all hard coded.If this gets annoying to maintain, it can change to a call to "get creator function" then "call creator function".  This is a purely internal refactor that does not change your interface an iota.The "get creator function", if you start wanting to allow code to self-register, can expose a registration interface, after you need it.If you start wanting a dynamic loading module system, you can then write that completely independently.The point of all of this?  The code parsing the config file simply parses out the class name and the parameters, and calls "create object by type and arguments".  And you only improve "create object by type and arguments" function to do more _after you need it_, because yPWNit.Write a decent interface that allows for extension later.  Implement it in a simple way.  Move along.;Quote:Original post by giugioHy i read an article that explain how create object from a .txt property file like this:*** Source Snippet Removed ***It mean that use factory pattern for create the object.How is applyed the factory pattern in this case?I'm not understand if i must use factory method or abstract factory.ThanksThis looks like it expects an abstract factory. The 'Class' property tells the abstract factory which derived class to instantiate.   