POV-Ray : Newsgroups : povray.off-topic : The "Factory" Pattern Server Time
4 Sep 2024 07:19:10 EDT (-0400)
  The "Factory" Pattern (Message 1 to 5 of 5)  
From: Darren New
Subject: The "Factory" Pattern
Date: 25 Apr 2010 17:53:51
Message: <4bd4b9ef$1@news.povray.org>
I have noticed that whenever I wind up using the Factory pattern, I wind up 
with a listing of all the classes somewhere in a central place, namely the 
factory method that instantiates the appropriate class.  It seems to me this 
kind of defeats the entire purpose of the method.

I would suggest a language feature to overcome this.

A class can be marked "factory" and if it has no parent classes that are 
marked factory, then it is abstract, but one is allowed to invoke "new" on 
the class.

If "new XYZ(alpha, beta)" is invoked and XYZ is a factory class, then all 
other (loaded) classes marked "factory" with a parent of "XYZ" are 
inspected. They are inspected in a breadth-first manner (with individual 
nodes at the same level being invoked in an undefined order), except that 
the most-derived classes are invoked before the less-derived classes. I.e., 
breadth-first, but starting from the leaves. Each compatible constructor is 
invoked, and the first one that doesn't throw an exception is the one used. 
If all throw an exception, then the original "new" statement throws an 
exception.

Potential problems: Getting the order right. The overhead of throwing 
exceptions (would be better if they could return a null, for example). 
Defining how this might work for languages without metadata. Figuring out 
the right semantics if one of the child classes is in a dynamically-loaded 
library that's not currently in a state in which its elements can be invoked 
(i.e., not loaded from disk yet, uninitialized, etc). Do we have to allocate 
enough memory for the biggest child class to be filled in? Do we reallocate 
memory each time we try a child?

Benefits: You can extend an abstract class without needing to have a static 
factory method. There would be no need for a central list of subclasses of a 
particular class (which is what dynamic dispatch was supposed to avoid in 
the first place).

Thoughts?

-- 
Darren New, San Diego CA, USA (PST)
   Linux: Now bringing the quality and usability of
   open source desktop apps to your personal electronics.


Post a reply to this message

From: Fredrik Eriksson
Subject: Re: The "Factory" Pattern
Date: 26 Apr 2010 04:52:40
Message: <op.vbrhl2kp7bxctx@toad.bredbandsbolaget.se>
On Sun, 25 Apr 2010 23:53:50 +0200, Darren New <dne### [at] sanrrcom> wrote:
> I have noticed that whenever I wind up using the Factory pattern, I wind  
> up with a listing of all the classes somewhere in a central place,  
> namely the factory method that instantiates the appropriate class.  It  
> seems to me this kind of defeats the entire purpose of the method.

Decentralization is not the purpose of the Factory pattern. Still, it is  
sometimes useful to decouple even the factory from knowledge about the  
specific concrete classes, especially if there are many of them.


> Thoughts?

Another way is to make the factory store a dictionary of construction  
methods/functors/prototypes, and register classes/objects into the factory  
 from elsewhere. This also lets you add new classes/objects to the factory  
at runtime. In C++, the registration part can be set up to happen  
automatically with minimal effort; I am not sure about other languages.

In languages with reflection, you could have the factory look up a class  
name, check if the class belongs to the right hierarchy for that factory,  
and then simply call a static factory method (or just the default  
constructor) defined in that class.



-- 
FE


Post a reply to this message

From: Darren New
Subject: Re: The "Factory" Pattern
Date: 26 Apr 2010 13:10:21
Message: <4bd5c8fd$1@news.povray.org>
Fredrik Eriksson wrote:
> Decentralization is not the purpose of the Factory pattern.

Uh, sure it is, in the same sense that inheritance is decentralization. What 
do *you* think it's for?  Maybe it's good for something else too.

> Still, it is 
> sometimes useful to decouple even the factory from knowledge about the 
> specific concrete classes, especially if there are many of them.

Right.

>> Thoughts?
> 
> Another way is to make the factory store a dictionary of construction 
> methods/functors/prototypes, and register classes/objects into the 
> factory from elsewhere. This also lets you add new classes/objects to 
> the factory at runtime. In C++, the registration part can be set up to 
> happen automatically with minimal effort; I am not sure about other 
> languages.
> 
> In languages with reflection, you could have the factory look up a class 
> name, check if the class belongs to the right hierarchy for that 
> factory, and then simply call a static factory method (or just the 
> default constructor) defined in that class.


Ah, now you're talking about implementations in current languages. I was 
talking about a language feature for future languages that would basically 
automate this whole process. Working with a language where it isn't built 
in, thinking about the ways I've used it and seen it used, and trying to 
come up with a way to eliminate the "registration" aspect and basically make 
it seamless, in the same way that exceptions and OO are seamless in C++ but 
you have to do them manually in C.

Plus, that's no longer "New". It's a separate method that returns a pointer. 
I.e., you're still calling a factory method instead of just instantiating a 
class and having it automatically instantiate the right subclass.

Of course, in some languages like Smalltalk (and Python, I think?) "new" is 
just a method that returns a reference, and that reference doesn't have to 
be the same class you invoked "new" on, so in that sense much of the hard 
work is done. The base class would just implement "look up the right 
subclass" process in its constructor and do the factory work there.

Altho, I suppose with MI (so you can inherit the "Factory" methods anywhere) 
and static library initialization (so you can invoke those implicitly to do 
registration when the class gets loaded) you could come very close to doing 
this with nothing but a library.


-- 
Darren New, San Diego CA, USA (PST)
   Linux: Now bringing the quality and usability of
   open source desktop apps to your personal electronics.


Post a reply to this message

From: Fredrik Eriksson
Subject: Re: The "Factory" Pattern
Date: 26 Apr 2010 14:43:01
Message: <op.vbr8xzue7bxctx@toad.bredbandsbolaget.se>
On Mon, 26 Apr 2010 19:10:18 +0200, Darren New <dne### [at] sanrrcom> wrote:
> Fredrik Eriksson wrote:
>> Decentralization is not the purpose of the Factory pattern.
>
> Uh, sure it is, in the same sense that inheritance is decentralization.  
> What do *you* think it's for?  Maybe it's good for something else too.

Perhaps a poor choice of words on my part. I would say that the Factory  
pattern is about decoupling/abstraction, but I suppose you could call that  
decentralization.

My point was that the issue of having to lump information about all the  
concrete classes together in one place is orthogonal; the Factory pattern  
is not intended to decentralize that part, even if you *can* sometimes do  
it.



> Altho, I suppose with MI (so you can inherit the "Factory" methods  
> anywhere) and static library initialization (so you can invoke those  
> implicitly to do registration when the class gets loaded) you could come  
> very close to doing this with nothing but a library.

MI is not necessary -- nor even helpful -- for this.



-- 
FE


Post a reply to this message

From: Darren New
Subject: Re: The "Factory" Pattern
Date: 26 Apr 2010 15:45:48
Message: <4bd5ed6c$1@news.povray.org>
Fredrik Eriksson wrote:
> On Mon, 26 Apr 2010 19:10:18 +0200, Darren New <dne### [at] sanrrcom> wrote:
>> Fredrik Eriksson wrote:
>>> Decentralization is not the purpose of the Factory pattern.
>>
>> Uh, sure it is, in the same sense that inheritance is 
>> decentralization. What do *you* think it's for?  Maybe it's good for 
>> something else too.
> 
> Perhaps a poor choice of words on my part. I would say that the Factory 
> pattern is about decoupling/abstraction, but I suppose you could call 
> that decentralization.

Yeah. My thought was that the factory pattern is there to support the basic 
idea of multiple implementations of the same concept. You have a class 
called "data connection", and depending on the parsing of the URL you pass 
at instantiation, you either get back a subclass that's "http connect" or 
"ftp connection" or "https connection" or whatever.

Decentralizing which of those subclasses is chosen is something that's not 
automated in any language I know of. Decentralizing the method dispatch to 
the appropriate methods of the subclass once instantiated *is* automated.

> My point was that the issue of having to lump information about all the 
> concrete classes together in one place is orthogonal; the Factory 
> pattern is not intended to decentralize that part, even if you *can* 
> sometimes do it.

Right. And that's just my point. I'm saying "the factory pattern could be 
made more useful if there were explicit language support for it", just like 
dyanmic dispatch or Singleton pattern is more useful when there's explicit 
language support.

>> Altho, I suppose with MI (so you can inherit the "Factory" methods 
>> anywhere) and static library initialization (so you can invoke those 
>> implicitly to do registration when the class gets loaded) you could 
>> come very close to doing this with nothing but a library.
> 
> MI is not necessary -- nor even helpful -- for this.

My thought was that you could have a "Factory" mix-in that during 
initialization would register itself with the appropriate subclass, and then 
the "Factory" base class would invoke the routine it knew was in each 
factory subclass because it knows it's in the factory mix-in. I.e., you 
could automate it much better by having a lump of routines and data that 
with a simple declaration get incorporated into your class without you 
having to worry about it. Then all you'd have to do is (for example) parse 
the URL and see if the scheme is one you handle, rather than writing the 
same code to register yourself in the superclass' list of classes to try, etc.

You could do the same thing at runtime with a sufficiently powerful 
reflection library, I suppose, but that would seem to be overhead that you 
could cure at either compile time or load time (if you wanted to dynamically 
load new libraries for new schemas as necessary).

Remember, subroutines are a design pattern. Stacks are a design pattern. OOP 
is a design pattern. Exceptions are a design pattern. It's all design 
patterns until your language builds it in.

-- 
Darren New, San Diego CA, USA (PST)
   Linux: Now bringing the quality and usability of
   open source desktop apps to your personal electronics.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.