Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Abstract Factory or Factory Method pattern question....

Reply
Thread Tools

Abstract Factory or Factory Method pattern question....

 
 
Medi Montaseri
Guest
Posts: n/a
 
      08-21-2003
Hi,

Given a collection of similar but not exact entities (or products)
Toyota, Ford, Buick, etc; I am contemplating using the Abstraction pattern
to provide a common interface to these products. So I shall have an
Abstract Base called 'Car' implemented by Toyota, Ford, and Buick.

Further I'd like to enable to client to say

Car *factory;
Car *mycar = factory->make ( "Ford" );

However note how 'mycar' is of type 'Car' and although make() will
return (new Ford ), an up-cast will take place and what client now has
is an instance of Car (abstract) and not Ford (concrete).

True that with Virtual Methods, the appropriate method will be called,
but I now have a data-member problem as the newly created and returned
object will only have access to Base data members. Again I don't want the
client to be aware of what type of 'Car' he/she will be using, ie I don't want
(if possible) to force the client to say

Ford *mycar = factory->make ( "Ford" )

Because client is now becomming aware of 'Car' vs 'Ford'.

One answer would be to have the Base have all the data members (superset)
of any Car-type. But now Ford has to know what is needed for it and have code
that guard against under usage or over usage. ie Ford would say, I don't need this
data member, why is it here...

Another answer would be, sorry can't do. Your client has to provide the
correct lval type during the object creation to reach the exact object.

If the client is to be aware, then I'm loosing part of Abstraction , ie who cares
wether its a Toyota or Ford, to my client its just a Car.

By the way I know my people who actually think that way about cars....
 
Reply With Quote
 
 
 
 
Buster Copley
Guest
Posts: n/a
 
      08-21-2003
Attila Feher wrote:
> Medi Montaseri wrote:
>
>>Hi,
>>
>>Given a collection of similar but not exact entities (or products)
>>Toyota, Ford, Buick, etc; I am contemplating using the Abstraction
>>pattern
>>to provide a common interface to these products. So I shall have an
>>Abstract Base called 'Car' implemented by Toyota, Ford, and Buick.
>>
>>Further I'd like to enable to client to say
>>
>>Car *factory;
>>Car *mycar = factory->make ( "Ford" );


Really? I don't think that will work. Dereferencing an uninitialized
pointer leads to undefined behaviour.

>>However note how 'mycar' is of type 'Car' and although make() will
>>return (new Ford ), an up-cast will take place and what client now has
>>is an instance of Car (abstract) and not Ford (concrete).


No, 'mycar' is of type 'Car *'. The pointer the client gets points to an
instance of Ford. There is no such thing as an instance of Car.

>>True that with Virtual Methods, the appropriate method will be called,
>>but I now have a data-member problem as the newly created and returned
>>object will only have access to Base data members.


The object has access to all its members. It's the client who only has
access to public members defined in the base class, Car, and that's the
way it's supposed to be. Since the caller isn't supposed to care what
kind of car he's got, he can only ask the car to do what any Car can do.
If he wants to do model-specific stuff, he first has to find out what
car he's driving, and once he's done that he can get a derived class
pointer.

By the way, it's unusual for an abstract base class to have any public
data members. The important thing is what information you can ask for
and what actions you can request. How the information is stored is as
much an implementation detail as how the actions are to be performed.

> [SNIP]
>
> Could you elaborate what is this "data member problem"? I cannot see it.
> It is a frequently used method to create an absolutely pure abstract class
> (no data members), provide a factory (even such, which can be extended by
> the concrete classes registering themselves), possibly provide some
> handle-body class to manage the returned pointer and tada, it is there,
> working. All you need (IMHO) to overcome any inconvenience regarding
> different data members is to have a virtual clone member function to be able
> to copy a Car - which is Ford - and still have a Ford, not just a dataless
> Car.
>
> BTW, IMHO this approach to describe cars is not the best design. I would go
> for a solution where the type of the car is just an attribute. AFAIS the
> whole Car concept is rather a concept of data (describing the car) rather
> than a hierarchy. Also if I think about the maintenance it sounds really
> bad that with every new car the programmer has to write a new class.
> Somehow it does not sound right.


Think on. I'd rather define a whole new car in one place than go round
every part of my program that depends on the type of car I'm using and
add an extra 'case' statement. I think of polymorphism as a way to
transform code full of switch statements into something more readable
and modular.

Regards,
Buster.

 
Reply With Quote
 
 
 
 
Attila Feher
Guest
Posts: n/a
 
      08-21-2003
Buster Copley wrote:
> Attila Feher wrote:

[SNIP]
>>> Car *factory;
>>> Car *mycar = factory->make ( "Ford" );

>
> Really? I don't think that will work. Dereferencing an uninitialized
> pointer leads to undefined behaviour.


Yes, and no. (I have missed that one.) In real life static functions
(like make) do not make any use of the pointer itself, they are resolved at
compile time. I have no idea what the standard says about this specific
case. Here the pointer is not really dereferenced - since factory functions
are static.

>>> However note how 'mycar' is of type 'Car' and although make() will
>>> return (new Ford ), an up-cast will take place and what client now
>>> has
>>> is an instance of Car (abstract) and not Ford (concrete).

>
> No, 'mycar' is of type 'Car *'. The pointer the client gets points to
> an instance of Ford. There is no such thing as an instance of Car.


IMHO that is what he meant. But the correction is absolutely valid.

[SNIP]
>>
>> Could you elaborate what is this "data member problem"? I cannot
>> see it. It is a frequently used method to create an absolutely pure
>> abstract class (no data members), provide a factory (even such,
>> which can be extended by the concrete classes registering
>> themselves), possibly provide some handle-body class to manage the
>> returned pointer and tada, it is there, working. All you need
>> (IMHO) to overcome any inconvenience regarding different data
>> members is to have a virtual clone member function to be able to
>> copy a Car - which is Ford - and still have a Ford, not just a
>> dataless Car.
>>
>> BTW, IMHO this approach to describe cars is not the best design. I
>> would go for a solution where the type of the car is just an
>> attribute. AFAIS the whole Car concept is rather a concept of data
>> (describing the car) rather than a hierarchy. Also if I think about
>> the maintenance it sounds really bad that with every new car the
>> programmer has to write a new class. Somehow it does not sound right.

>
> Think on. I'd rather define a whole new car in one place than go round
> every part of my program that depends on the type of car I'm using and
> add an extra 'case' statement. I think of polymorphism as a way to
> transform code full of switch statements into something more readable
> and modular.


To whom did you write that? You have replied to me, and my suggestion did
not contain switch statements at all.
--
Attila aka WW


 
Reply With Quote
 
Buster Copley
Guest
Posts: n/a
 
      08-21-2003
Attila Feher wrote:
> Buster Copley wrote:
>>Attila Feher wrote:

>
> [SNIP]
>
>>>>Car *factory;
>>>>Car *mycar = factory->make ( "Ford" );

>>
>>Really? I don't think that will work. Dereferencing an uninitialized
>>pointer leads to undefined behaviour.

>
> Yes, and no. (I have missed that one.) In real life static functions
> (like make) do not make any use of the pointer itself, they are resolved at
> compile time. I have no idea what the standard says about this specific
> case. Here the pointer is not really dereferenced - since factory functions
> are static.


Indeed, but that's not the syntax to call a static member function.
[snip]

>>>BTW, IMHO this approach to describe cars is not the best design. I
>>>would go for a solution where the type of the car is just an
>>>attribute. AFAIS the whole Car concept is rather a concept of data
>>>(describing the car) rather than a hierarchy. Also if I think about
>>>the maintenance it sounds really bad that with every new car the
>>>programmer has to write a new class. Somehow it does not sound right.

>>
>>Think on. I'd rather define a whole new car in one place than go round
>>every part of my program that depends on the type of car I'm using and
>>add an extra 'case' statement. I think of polymorphism as a way to
>>transform code full of switch statements into something more readable
>>and modular.

>
> To whom did you write that? You have replied to me, and my suggestion did
> not contain switch statements at all.


To you. Your suggestion didn't contain any C++ at all. Whether it's
else-if ladders, switch statements, associative arrays or whatever,
somehow you have to decide what to do based on an "attribute" (private
data member?) of your object.

> --
> Attila aka WW


 
Reply With Quote
 
Attila Feher
Guest
Posts: n/a
 
      08-21-2003
Buster Copley wrote:
> Attila Feher wrote:

[SNIP]
>>>> BTW, IMHO this approach to describe cars is not the best design. I
>>>> would go for a solution where the type of the car is just an
>>>> attribute. AFAIS the whole Car concept is rather a concept of data
>>>> (describing the car) rather than a hierarchy. Also if I think
>>>> about
>>>> the maintenance it sounds really bad that with every new car the
>>>> programmer has to write a new class. Somehow it does not sound
>>>> right.

[SNIP]
> To you. Your suggestion didn't contain any C++ at all. Whether it's
> else-if ladders, switch statements, associative arrays or whatever,
> somehow you have to decide what to do based on an "attribute" (private
> data member?) of your object.


Please read what I wrote. I said in there that I do not think that a class
hierarchy is a good idea. Car seems to consist of nothing else, but data.
Meaning: there is a Car class having all possible data for a car (number of
doors, colors etc.). If you would ever need some algorithm difference you
can use the Strategy pattern.

--
Attila aka WW


 
Reply With Quote
 
Medi Montaseri
Guest
Posts: n/a
 
      08-21-2003
"Attila Feher" <> wrote in message news:<bi1okm$jun$>. ..
> Medi Montaseri wrote:
> > Hi,
> >
> > Given a collection of similar but not exact entities (or products)
> > Toyota, Ford, Buick, etc; I am contemplating using the Abstraction
> > pattern
> > to provide a common interface to these products. So I shall have an
> > Abstract Base called 'Car' implemented by Toyota, Ford, and Buick.
> >
> > Further I'd like to enable to client to say
> >
> > Car *factory;
> > Car *mycar = factory->make ( "Ford" );
> >
> > However note how 'mycar' is of type 'Car' and although make() will
> > return (new Ford ), an up-cast will take place and what client now has
> > is an instance of Car (abstract) and not Ford (concrete).
> >
> > True that with Virtual Methods, the appropriate method will be called,
> > but I now have a data-member problem as the newly created and returned
> > object will only have access to Base data members.

> [SNIP]
>
> Could you elaborate what is this "data member problem"? I cannot see it.
> It is a frequently used method to create an absolutely pure abstract class
> (no data members), provide a factory (even such, which can be extended by
> the concrete classes registering themselves), possibly provide some
> handle-body class to manage the returned pointer and tada, it is there,
> working. All you need (IMHO) to overcome any inconvenience regarding
> different data members is to have a virtual clone member function to be able
> to copy a Car - which is Ford - and still have a Ford, not just a dataless
> Car.

I'm not following the "Virtual Cloen member function"...
if you mean a factory method, then Car::Make() is that...

>
> BTW, IMHO this approach to describe cars is not the best design. I would go
> for a solution where the type of the car is just an attribute. AFAIS the
> whole Car concept is rather a concept of data (describing the car) rather
> than a hierarchy. Also if I think about the maintenance it sounds really
> bad that with every new car the programmer has to write a new class.
> Somehow it does not sound right.


So what I want to achieve is to have a common interface so that I as the
author of that interface can mandate that N number of methods should be
implemented. These services (or methods) fall in two (or more) categories;

cat-1) Methods that are specific to a particular car.
Implemented by concrete classes.
cat-2) Methods that are common (reusability).
Implemented in the abstract base class (Car).

My data-member problem surfaces at compile time where a "common" method
defined in base is referencing a data-member. A Data-Less Base class
as you recommended would have problem with this.

This is also due to the desirable feature that client should be able
to say

Car *mycar = factory->Make( "Ford" );
....
mycar->getColor();

At compile time since mycar is an object of type Car will try to look for
Car::_color and not Ford::_color.

Hence having a data-less base class will yield compile time error...
 
Reply With Quote
 
Attila Feher
Guest
Posts: n/a
 
      08-22-2003
Medi Montaseri wrote:
> "Attila Feher" <> wrote in message

[SNIP]
> I'm not following the "Virtual Cloen member function"...
> if you mean a factory method, then Car::Make() is that...


I meant clone(). If you have a pointer to a Car object (which might as well
point to a Ford) you will not be able to copy that Ford unless you ask it to
copy itself. Since you have no idea what it is. That clone is a simple
virtual function returning a (poiter to a) newly allocated copy of the
object itself. {return new Ford(*this);} Since it is virtual a Ford will
return a Ford, a Toyota a Toyota etc.

[SNIP]
> So what I want to achieve is to have a common interface so that I as
> the
> author of that interface can mandate that N number of methods should
> be
> implemented. These services (or methods) fall in two (or more)
> categories;
>
> cat-1) Methods that are specific to a particular car.
> Implemented by concrete classes.
> cat-2) Methods that are common (reusability).
> Implemented in the abstract base class (Car).
>
> My data-member problem surfaces at compile time where a "common"
> method
> defined in base is referencing a data-member. A Data-Less Base class
> as you recommended would have problem with this.
>
> This is also due to the desirable feature that client should be able
> to say
>
> Car *mycar = factory->Make( "Ford" );
> ...
> mycar->getColor();
>
> At compile time since mycar is an object of type Car will try to look
> for
> Car::_color and not Ford::_color.
>
> Hence having a data-less base class will yield compile time error...


I understood that. If you look closely to what I have suggested was that
look at your design again, since I do not believe that Ford, Toyota etc.
should ever be separate classes. I think those belong to an std::string
member called manufacturer_. I also think that this Car object is rather a
collection of data then behavior, so I do not see any need for a class
hierarchy (inheritance). I might be wrong of course.

--
Attila aka WW


 
Reply With Quote
 
Medi Montaseri
Guest
Posts: n/a
 
      08-22-2003
Buster Copley <> wrote in message news:<bi1sou$934$>...
> Attila Feher wrote:
> > Medi Montaseri wrote:
> >
> >>Hi,
> >>
> >>Given a collection of similar but not exact entities (or products)
> >>Toyota, Ford, Buick, etc; I am contemplating using the Abstraction
> >>pattern
> >>to provide a common interface to these products. So I shall have an
> >>Abstract Base called 'Car' implemented by Toyota, Ford, and Buick.
> >>
> >>Further I'd like to enable to client to say
> >>
> >>Car *factory;
> >>Car *mycar = factory->make ( "Ford" );

>
> Really? I don't think that will work. Dereferencing an uninitialized
> pointer leads to undefined behaviour.
>

Yes I think this is allowed for abstract classes. ie you can invoke the
method via pointer and references. But not an instance of it, as in

Car factoryr; factory.make( "Ford" ); // this will not work
Car *factory; factory->make( "Ford" ); // this will work
Car &factory; factory.make( "Ford" ) ; // this will work

> >>However note how 'mycar' is of type 'Car' and although make() will
> >>return (new Ford ), an up-cast will take place and what client now has
> >>is an instance of Car (abstract) and not Ford (concrete).

>
> No, 'mycar' is of type 'Car *'. The pointer the client gets points to an
> instance of Ford. There is no such thing as an instance of Car.
>

Purely speaking you are correct, there is no instance. mycar is of type "Car *".

> >>True that with Virtual Methods, the appropriate method will be called,
> >>but I now have a data-member problem as the newly created and returned
> >>object will only have access to Base data members.

>


> If he wants to do model-specific stuff, he first has to find out what
> car he's driving, and once he's done that he can get a derived class
> pointer.


Exactly, so the question is ... can we even hide that so that all common
features of Car and specific features of a particular car are provided to
the client from one single object. Call it Single Point of Service (or Interface).

>
> By the way, it's unusual for an abstract base class to have any public
> data members. The important thing is what information you can ask for
> and what actions you can request. How the information is stored is as
> much an implementation detail as how the actions are to be performed.
>

Yes but if our model is house all common methods in the base and specific
methods in their respective concrete classes, then at compile time, a common
method (which is defined in base) will try to reach a data member that thinks
should be available in the class where method is defined. and of course a
dataless base will not have any methods.....

So perhaps the issue is how I'm trying to hit two birds with this approach;
I want reusability (by having common methods in base) and I also want
Interfacing. Maybe this is not a good mix...


>
> Regards,
> Buster.

 
Reply With Quote
 
Buster Copley
Guest
Posts: n/a
 
      08-22-2003
Medi Montaseri wrote:
> Yes I think this is allowed for abstract classes. ie you can invoke the
> method via pointer and references. But not an instance of it, as in
>
> Car factoryr; factory.make( "Ford" ); // this will not work
> Car *factory; factory->make( "Ford" ); // this will work
> Car &factory; factory.make( "Ford" ) ; // this will work


I think you're correct. (make () is not a virtual function, right?)

>>If he wants to do model-specific stuff, he first has to find out what
>>car he's driving, and once he's done that he can get a derived class
>>pointer.

>
> Exactly, so the question is ... can we even hide that so that all common
> features of Car and specific features of a particular car are provided to
> the client from one single object. Call it Single Point of Service (or Interface).


I'm not sure what you mean. Doesn't a derived class pointer give you
access to all common features of car and specific features of a
particular car?

If you provide a way to access all possible features of any specific car
from a base class pointer, then you have constrained what features are
possible in future cars. As my friend Atilla has said, it doesn't seem
unreasonable to impose such constraints ["there is a Car class having
all possible data for a car (number of doors, colors etc.)"]. But I
don't think you are coming from the same angle, because there would be
no "data member problem" then.

May I say that it's not correct that "the newly created and returned
object will only have access to Base class data members". The object has
access to derived class data members through its virtual functions. Does
that help you at all? (Don't take offense if I'm pointing out the
obvious - I don't know your level, that's all.)

>>By the way, it's unusual for an abstract base class to have any public
>>data members. The important thing is what information you can ask for
>>and what actions you can request. How the information is stored is as
>>much an implementation detail as how the actions are to be performed.

>
> Yes but if our model is house all common methods in the base and specific
> methods in their respective concrete classes, then at compile time, a common
> method (which is defined in base) will try to reach a data member that thinks
> should be available in the class where method is defined. and of course a
> dataless base will not have any methods.....


I find this hard to follow. If a base class method depends on data
members, that data should be in the base class (or the method should be
in the derived class). As a compromise, perhaps you could solve your
problem by providing virtual helper functions for your base class
method, so that the information about derived data members is
'translated' to a form useful to the base class method in the correct
way for each derived class.

Tell me if you think I've missed the point.

> So perhaps the issue is how I'm trying to hit two birds with this approach;
> I want reusability (by having common methods in base) and I also want
> Interfacing. Maybe this is not a good mix...
>
>>Regards,
>>Buster.


 
Reply With Quote
 
Big Brian
Guest
Posts: n/a
 
      08-26-2003
> Perhaps I should include some code, maybe I'm failing to express my
> problems...I'll present a Car.cc, Sedan.cc and Pickup.cc. Which is
> a small change from Car, Ford, Toyota...but I wanted to show how
> some cars might have different functionalities such as a Pickup truck
> has openTailGate() where Sedan has openRearDoor()...
>
> // -------------------- here is Car.h -----------------
> #ifndef _CAR_H_
> #define _CAR_H_
> #include <iostream>
> #include <string>
>
> using namespace std;
>
> class Car
> {
> public:
> // a factory method
> Car * make(const string& carType = "" );
>
> // a mandatory method for derived classes to implement
> virtual void Drive() = 0;
>
> // a common method without any data access...works
> void greetDriver() { cout << "Hello driver." << endl ; }
>
> // a common method with instance data access...don't work
> void getColor() { cout << "Color=" << _color << endl; }


This is a compiler error. There is no _color defined in this class.


> // car model specific methods
> //virtual void openRearDoor();
> //virtual void openTailGate();
> };
>
> #endif
> // --------------------- here is Sedan.h ---------------------
> #ifndef _SEDAN_H_
> #define _SEDAN_H_
>
> #include <string>
> #include "Car.h"
>
> using namespace std;
>
> class Sedan: public Car
> {
> public:
> Sedan();
> virtual ~Sedan() {};
> void Drive();
> void openRearDoor();
>
> private:
> string _color;
> string _RearDoorState;
> };
>
> #endif
> // -------------------- here is Pickup.h -----------------
> #ifndef _PICKUP_H_
> #define _PICKUP_H_
>
> #include <string>
> #include "Car.h"
>
> using namespace std;
>
> class Pickup: public Car
> {
> public:
> Pickup();
> virtual ~Pickup() {};
> void openTailGate();
> void Drive();
>
> private:
> string _color;
> string _TailGateState;
> };


Yuck, why are you storing the state in a string? This is inefficient.

>
> #endif
> // ------------------- here is Car.cpp --------------
> #include <iostream>
> #include "Car.h"
> #include "Sedan.h"
> #include "Pickup.h"
>
> using namespace std;
>
> // ---------------- make() ------------
> Car* Car::make(const string& carType /* = "" */ )
> {
> if ( carType == "Sedan" )
> {
> return( new Sedan() );
> }
> else if ( carType == "Pickup" )
> {
> return( new Pickup() );
> }
> else
> {
> cerr << "Error: You need to specify a car type" << endl;
> return(NULL);
> }
> }
> // ----------------------
> // ------------------------ here is Sedan.cpp -------------
> #include <iostream>
> #include "Sedan.h"
>
> using namespace std;
>
> // ------------------------ Sedan() -----------------
> Sedan::Sedan(): _color("White"), _RearDoorState("closed")
> {
> }
> // --------------------- openRearDoor() -----------
> void Sedan:penRearDoor()
> {
> _RearDoorState = "open";
> cout << "Ok...Rear door is now open." << endl;
> }
> // --------------------- Drive() -----------
> void Sedan:rive()
> {
> cout << "Ok...I'm driving." << endl;
> }
> // ----------------
> // ----------------- here is Pickup.cpp ----------------
> #include <iostream>
> #include "Pickup.h"
>
> using namespace std;
>
> // ------------------------ Pickup() -----------------
> Pickup:ickup(): _color("Black"), _TailGateState("closed")
> {
> }
> // --------------------- openTailGate() -------------
> void Pickup:penTailGate()
> {
> _TailGateState = "open";
> cout << "Ok...Tail gate is now open." << endl;
> }
> // --------------------- Drive() -------------
> void Pickup:rive()
> {
> cout << "Ok...i'm driving." << endl;
> }
> // ---------------------
> // ----------------------- here is the client foo.cpp -------------
> #include <iostream>
> #include "Car.h"
> #include "Sedan.h"
>
>
> using namespace std;
>
> int main (int argc, char **argv)
> {
> cout << "Starting.... " << endl;
>
> Car *factory ;
> Car *mySedan = factory->make( "Sedan" );
> Car *myPickup = factory->make( "Pickup" );
>
> mySedan->greetDriver() ;
> //mySedan->openRearDoor();
>
> myPickup->greetDriver() ;
> //myPickup->openTailGate() ;
>
> delete ( mySedan );
> delete ( myPickup );
> }
> // ----------------------- here is the compiler error --------
> medi@medi:~/cpp/car> make foo
> g++ -c foo.cpp Car.cpp Sedan.cpp Pickup.cpp
> In file included from foo.cpp:2:
> Car.h: In member function `void Car::getColor()':
> Car.h:21: `_color' undeclared (first use this function)
> Car.h:21: (Each undeclared identifier is reported only once for each function
> it appears in.)
> In file included from Car.cpp:2:
> Car.h: In member function `void Car::getColor()':
> Car.h:21: `_color' undeclared (first use this function)
> Car.h:21: (Each undeclared identifier is reported only once for each function
> it appears in.)
> In file included from Sedan.h:5,
> from Sedan.cpp:2:
> Car.h: In member function `void Car::getColor()':
> Car.h:21: `_color' undeclared (first use this function)
> Car.h:21: (Each undeclared identifier is reported only once for each function
> it appears in.)
> In file included from Pickup.h:5,
> from Pickup.cpp:2:
> Car.h: In member function `void Car::getColor()':
> Car.h:21: `_color' undeclared (first use this function)
> Car.h:21: (Each undeclared identifier is reported only once for each function
> it appears in.)
> make: *** [foo] Error 1
> medi@medi:~/cpp/car>



> Note how Car::getColor() is failing to access Sedan::_color data member.
> showing that


Yes, that's right because _color is a member of Sedan not Car. Car
cannot access Sedan's data member directly because Sedan is derived
from Car and not the other way around. ( but you could use a virtual
function that's overridden in Sedan to return Sedan::_color )

> mySedan->getColor() is sending a message to object of type Car and not
> a Sedan. At least at compile time...


No, you have a compiler error ( which appears to be from your
mis-understanding of C++ ). Also, you really aren't "sending a
message", your just dereferencing a pointer to a class ( who's type
can be determined at run time ) and calling a member function.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[OT] Non-abstract factory design pattern versus using constructordirectory marlow.andrew@googlemail.com Java 26 12-05-2008 02:54 PM
Abstract factory and Factory pattern C# ASP .Net 4 07-31-2008 03:22 PM
Abstract Factory DAO Pattern in JSP Page Dave Java 1 01-26-2007 11:24 PM
documents related to factory design pattern and Abstract foctory pattern. sunny C++ 1 12-07-2006 04:26 AM
Design Pattern - Abstract Factory =?Utf-8?B?bWF4?= ASP .Net 2 10-18-2005 05:05 PM



Advertisments