Arlo Belshee on 8 Jul 2003 16:03:01 -0000 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Re: [ALACPP] chapter 8 |
> I would never use the factory template in my code. It is a degenerate > abstraction over a map template. I would always just use a map > directly. I am calling it degenerate because it does not add any > additional functionality or abstract away any of the details of a map. All > it does is rename the interface methods: map::insert becomes > Factory::Register, map::erase become Factory::Unregister, and map::find > becomes Factory::CreateObject. What's the point? In and of itself, not much. However, it provides a good base to which you can easily attach some very useful functionality. For example, I typically add a nested class that can be used for autoregistration: each factory-constructable class automatically registers itself with the correct factory at static initialization time. This means that there is no central location containing a list of all the classes that 1) has to be kept up to date, and 2) has a physical dependency on everything. Also, I pull CreateObject into a policy. The most common implementation of the policy is PrototypePolicy, which clones (deep copy) a registered instance to make a new class. However, I also often create NewPolicy, which provides a set of overrides for CreateObject that accept constructor args. If I'm using non-default heaps, factory is extremely useful for controlling what objects get created on what heaps, without burying that information in a hundred places throughout the code base. Finally, I have CreateObject always return a smart pointer, rather than a basic pointer. The factory provides a type computer that gives the pointer type for any type that it can construct. That way, no object ever appears in the real system (even for a short while) as a basic pointer. Then, if I need to change anything about its memory management (garbage collection, etc), I just change it in one place: the type computer. Everyone else uses that type computer when determining how to store the ponter, so they are all automagically updated if I change my memory model. (Note: if the factory becomes a central part of the system, I usually refactor the type computer out into a traits implementation. That way, the factory and everyone else can depend on the traits class, and nothing has to depend on the factory unless it actually creates objects. However, this adds complexity to the system, so I only do it once "several" unrelated things are depending on factory, just to get the pointer type.) Basically, Factory is a useful abstraction of your memory model(s). You can put all the design decisions about memory management into one place, and then all of the rest of your code is immune to changes in your memory managment policies. If you suddenly note that performace blows and you want to use a pooled allocation system to improve locality of reference, you write one new policy, change the typedef for the active factory, and poof. Everything else adapts. Arlo _______________________________________________ alacpp mailing list alacpp@xxxxxxxxxxx http://lists.ellipsis.cx/mailman/listinfo/alacpp