A Factory is an object that creates other Objects. One might rightfully ask why a language such as VB needs a separate factory mechanism. After all, VB already has a universal factory mechanism. Whenever you are using CreateObject, you are in fact using a factory. That’s a factory VB makes available to you and you hardly have to do anything for it. Then why be so stubborn to implement one’s own factory mechanism ? The reason is simple. In order to let your class participate in the ‘VB factory dance’, you have to make it Public (or GlobalMultiUse). In certain cases this is not a problem. In other cases, however it certainly is. The central motivation for creating private classes is to have a private interface for the class. Since the implementation is completely private, it doesn’t stand in the way when you want to change it. You don’t have to think about binary compatibility or any of such other VB miracles. Just change the class in each and every way you want. I have found for myself that creating stable classes is very difficult. The impossibility for removing or changing existing methods is certainly a lot of weight on any architect wanting to cope with change. If the class is private you don’t have these constraints at all. You aren’t as free as bird but you can do so much more with private classes. But then again, what is the use of a private class ? The answer is simple. It’s is not because the primary interface of the class is private that the class cannot implement a public secundary interface and ‘leave the server’ masked in another interface. It’s a principle I use all the time. P.e. I have a class cOutputStreamFile which implements the interface iOutputStream. The only thing a user of this class should be interested in, is the iOutputStream interface. The cOutputStreamFile is completely hidden from him. But how is he able to create an instance of that class ? The answers is once again simple : I created a Facade method CreateOutputStreamFile (which takes the necessary parameters to initialize the object). Internally this creates an instance of the private class, but it returns it masked as iOutputStream. The slightly more complicated solution for the creation of private classes is the subject of this chapter. IObjectFactoryIn order to be able to create private objects, I need a register of factories. This register keeps a mapping between UniqueSignatures and factories. Therefore I need to define what such a factory looks like : Interface iObjectFactory VB persistence makes use of the registry for this. I had to define my own register. The register is a singleton. I have created the following facade methods for it : Sub RegisterClass (byval strSignature as string, byval objFactory as iObjectFactory) Any class that wants to participate in the creation game has to register itself first. Here is some code that registers the class : RegisterClass "com.wvdd.myClass", new myClassFactory I always register my factories in the sub Main of any component. This makes sure that the factory is registered before I start using any of the components in the ActiveX. Now, it is clear that factories allow you to ‘bypass’ the normal ‘new’ or ‘CreateObject’ mechanisms, thereby making it possible to have private classes participate in the creation game. However, it might be plain overkill to do this for public classes. We therefore create a standard ObjectFactory that is able to create public classes based on their ProgID. The code goes like this : class cObjectFactoryByProgID With the appropriate facade methods, this allows you to write code like this RegisterClass “cMyClass.cMyServer.Wvdd.com”, createObjectFactoryByProgID(“MyServer.myClass”1) This is not exactly short code, but it IS code that allows you to reuse the existing COM instance creation process. With the simple adapter class you never have to write an object Factory for a public class thereby dramatically reducing the number of hand-written factories. There is little sense in defining many other predefined factories. I can only come up with a decorator that logs the access to a factory, another decorator that times the accesses and a chain of responsibility that will walk a set of factories to see which one returns a valid object. Since I classify all of these in the esoteric area, I have not (yet) implemented them. Finally, we can use the object register to create an instance by using the facade method CreateTypedObject. A sample snippet of code is below : Dim objVal as Object [Now don’t be fooled by the return type (Object). There is no late binding here. there will only be late binding when we start calling methods on something as Object.] This concludes the chpater on Object Creation. Object Creation is crucial for the next topic : persistence. | ||||||||||||||||||||||||||||||||||
Subitems : | ||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||
| Site updated : Monday, February 17, 2003
| ||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||