473,782 Members | 2,393 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Factory method -- best practices for portability

Hi,

I'm a long-time C programmer, I've started making the transition to "real
C++" recently. I am puzzled about how to write a factory method. Any
suggestions, pointers or references to documentation would be appreciated.

Here is some background information about what I'm doing: I have written a
large body of code that makes extensive use of mutexes. Most of my code is
portable, except for the mutexes, which are platform specific. I've
abstracted the notion of mutex with an abstract class "mutex", with pure
virtual functions get() and release() to obtain and release the mutex,
respectively. The large body of code uses pointers to these mutexes.

I am deriving "implementa tion classes" from mutex, for example win32Mutex,
linuxMutex, and posixMutex, on a per-platform basis and implementing get()
and release() accordingly.

Everything seems to be working OK with my simple tests, but I want to use a
"factory method" to cleanly produce (pointers to) mutexes. I can't grok how
to do this at a high-level, and I can't quite "seal off" the
platform-specific code from the large body of platform-independent code.

The idea is that I want to minimize platform-specific things in the large
body of code by calling a factory method when a mutex is needed, as opposed
to calling the (platform specific) constructors in the implementation
classes directly.

Should I:
1) Try to make the factory method a static member function of class mutex?
2) Create another class mutexMaker with member function makeNewMutex(), and
derive classes like win32MutexMaker and linuxMutexMaker from it?
3) Write a non-member function?
4) Use #IFDEF and #INCLUDE and #3 above?
5) Something else that I haven't thought of?

Thanks in advance for any insight.

ed
Jul 22 '05 #1
8 2068
"Ed Fair" <ed*****@mindsp ring.com> wrote:
I am deriving "implementa tion classes" from mutex, for example win32Mutex,
linuxMutex, and posixMutex, on a per-platform basis and implementing get()
and release() accordingly.

Everything seems to be working OK with my simple tests, but I want to use a "factory method" to cleanly produce (pointers to) mutexes. I can't grok how to do this at a high-level, and I can't quite "seal off" the
platform-specific code from the large body of platform-independent code. .... Should I:
1) Try to make the factory method a static member function of class mutex?
2) Create another class mutexMaker with member function makeNewMutex(), and derive classes like win32MutexMaker and linuxMutexMaker from it?
3) Write a non-member function?
4) Use #IFDEF and #INCLUDE and #3 above?
5) Something else that I haven't thought of?


Here are some appropriate "design patterns" for this problem:

Abstract Factory (#2 above) -
http://home.earthlink.net/~huston2/dp/factory.html

- particularly used for "families" of class objects, eg. win32Mutex,
win32Socket, linuxMutex, linuxSocket ...

Factory Method - http://home.earthlink.net/~huston2/d...oryMethod.html

- add a virtual newMutex() function to class Mutex, and derive win32Mutex,
linuxMutex etc. from Mutex.

Prototype - http://home.earthlink.net/~huston2/dp/prototype.html

- copy a prototypical example of a mutex (which is created at the beginning
of the program) whenever a new one is needed.
David F


Jul 22 '05 #2
"Ed Fair" <ed*****@mindsp ring.com> wrote:
I'm a long-time C programmer, I've started making the transition to "real
C++" recently. I am puzzled about how to write a factory method. Any
suggestions, pointers or references to documentation would be appreciated.

Here is some background information about what I'm doing: I have written a
large body of code that makes extensive use of mutexes. Most of my code is
portable, except for the mutexes, which are platform specific. I've
abstracted the notion of mutex with an abstract class "mutex", with pure
virtual functions get() and release() to obtain and release the mutex,
respectively. The large body of code uses pointers to these mutexes.

I am deriving "implementa tion classes" from mutex, for example win32Mutex,
linuxMutex, and posixMutex, on a per-platform basis and implementing get()
and release() accordingly.

Everything seems to be working OK with my simple tests, but I want to use a
"factory method" to cleanly produce (pointers to) mutexes. I can't grok how
to do this at a high-level, and I can't quite "seal off" the
platform-specific code from the large body of platform-independent code.

The idea is that I want to minimize platform-specific things in the large
body of code by calling a factory method when a mutex is needed, as opposed
to calling the (platform specific) constructors in the implementation
classes directly.

Should I:
1) Try to make the factory method a static member function of class mutex?
2) Create another class mutexMaker with member function makeNewMutex(), and
derive classes like win32MutexMaker and linuxMutexMaker from it?
3) Write a non-member function?
4) Use #IFDEF and #INCLUDE and #3 above?
5) Something else that I haven't thought of?


Your trying too hard Ed. :-) Factory methods are good for runtime
polymorphism, but you don't have any of that in this case. The linux
program will always use linux mutexes for example. You simply need to
create H and CPP files for each mutex type, but give them all the same
interface and class name, then link in the one you want for the version
you are compiling.
Jul 22 '05 #3
Thanks, David, these made for good reading.

ed

"David Fisher" <no****@nospam. nospam.nospam> wrote in message
news:Pl******** **********@nasa l.pacific.net.a u...
"Ed Fair" <ed*****@mindsp ring.com> wrote:
I am deriving "implementa tion classes" from mutex, for example win32Mutex, linuxMutex, and posixMutex, on a per-platform basis and implementing get() and release() accordingly.

Everything seems to be working OK with my simple tests, but I want to use
a
"factory method" to cleanly produce (pointers to) mutexes. I can't grok how
to do this at a high-level, and I can't quite "seal off" the
platform-specific code from the large body of platform-independent code.

...
Should I:
1) Try to make the factory method a static member function of class

mutex? 2) Create another class mutexMaker with member function makeNewMutex(),

and
derive classes like win32MutexMaker and linuxMutexMaker from it?
3) Write a non-member function?
4) Use #IFDEF and #INCLUDE and #3 above?
5) Something else that I haven't thought of?


Here are some appropriate "design patterns" for this problem:

Abstract Factory (#2 above) -
http://home.earthlink.net/~huston2/dp/factory.html

- particularly used for "families" of class objects, eg. win32Mutex,
win32Socket, linuxMutex, linuxSocket ...

Factory Method - http://home.earthlink.net/~huston2/d...oryMethod.html

- add a virtual newMutex() function to class Mutex, and derive win32Mutex,
linuxMutex etc. from Mutex.

Prototype - http://home.earthlink.net/~huston2/dp/prototype.html

- copy a prototypical example of a mutex (which is created at the

beginning of the program) whenever a new one is needed.
David F

Jul 22 '05 #4
Thanks, Daniel.

ed

"Daniel T." <po********@eat hlink.net> wrote in message
news:po******** *************** *******@news06. east.earthlink. net...
"Ed Fair" <ed*****@mindsp ring.com> wrote:
I'm a long-time C programmer, I've started making the transition to "real C++" recently. I am puzzled about how to write a factory method. Any
suggestions, pointers or references to documentation would be appreciated.
Here is some background information about what I'm doing: I have written a large body of code that makes extensive use of mutexes. Most of my code is portable, except for the mutexes, which are platform specific. I've
abstracted the notion of mutex with an abstract class "mutex", with pure
virtual functions get() and release() to obtain and release the mutex,
respectively. The large body of code uses pointers to these mutexes.

I am deriving "implementa tion classes" from mutex, for example win32Mutex, linuxMutex, and posixMutex, on a per-platform basis and implementing get() and release() accordingly.

Everything seems to be working OK with my simple tests, but I want to use a "factory method" to cleanly produce (pointers to) mutexes. I can't grok how to do this at a high-level, and I can't quite "seal off" the
platform-specific code from the large body of platform-independent code.

The idea is that I want to minimize platform-specific things in the large body of code by calling a factory method when a mutex is needed, as opposed to calling the (platform specific) constructors in the implementation
classes directly.

Should I:
1) Try to make the factory method a static member function of class mutex? 2) Create another class mutexMaker with member function makeNewMutex(), and derive classes like win32MutexMaker and linuxMutexMaker from it?
3) Write a non-member function?
4) Use #IFDEF and #INCLUDE and #3 above?
5) Something else that I haven't thought of?


Your trying too hard Ed. :-) Factory methods are good for runtime
polymorphism, but you don't have any of that in this case. The linux
program will always use linux mutexes for example. You simply need to
create H and CPP files for each mutex type, but give them all the same
interface and class name, then link in the one you want for the version
you are compiling.

Jul 22 '05 #5

"Ed Fair" <ed*****@mindsp ring.com> wrote in message
news:vO******** ********@newsre ad1.news.atl.ea rthlink.net...
Hi,

I'm a long-time C programmer, I've started making the transition to "real
C++" recently. I am puzzled about how to write a factory method. Any
suggestions, pointers or references to documentation would be appreciated.

Here is some background information about what I'm doing: I have written a large body of code that makes extensive use of mutexes. Most of my code is portable, except for the mutexes, which are platform specific. I've
abstracted the notion of mutex with an abstract class "mutex", with pure
virtual functions get() and release() to obtain and release the mutex,
respectively. The large body of code uses pointers to these mutexes.


This will significantly slow your code compared to native mutex calls which
are often just macros with
no function call at all if there is no contention.

One responder suggested just linking to different versions which is fine but
still not very efficient.

To get maximum speed the answer is templates
- parameterize everything with a class required to contain all the types and
methods that you need. Default this parameter to ThreadUtil or some such.
- Have a Thread.h header that conditionally includes the appropriate system
header, your platform specific thread class header and which typedefs the
platform specfic classes to ThreadUtil
- Make all the methods of your classes inline

e.g.

PosixThreadUtil .h

#include <pthread.h>
struct PosixThreadUtil
{
struct Mutex
{
pthread_mutex_t m_mutex;
void lock() { pthread_mutex_l ock(&m_mutex); }
//etc
};
// threads, condvars etc
};

ThreadUtil.h

#ifdef POSIX_SOURCE
#include "PosixThreadUti l.h"
typedef PosixThreadUtil ThreadUtil;
#elif defined(WIN32)
#include "WindowsThreadU til.h"
typedef WindowsThreadUt il ThreadUtil;
#else
#error no thread class available
#endif

stuff.cpp

#include "ThreadUtil .h"

template <class THREAD=ThreadUt il>
void unrealistic()
{
typename ThreadUtill::Mu tex mutex;
mutex.lock(); // should be inlined to pthread_mutexlo ck for POSIX
}

This mechanism works and is efficient but be warned - different systems
model threads and their control very differently - mutex/critical section is
easy but there is apparently no simple equivalent to pthread cond in
Windows.
There is a book (sorry - I can't remember the title) that spends several
hundred pages developing an interface that can be implemented reasonably in
both windows and posix

P.S. A good use for the library substitution approach is where your code is
supposed to be thread safe but doesn't actually use threads itself (it is
obviously part of a library) - In this case you can provide a dummy for
applications that don't actually use threads. Alternatively you could use
the templates and have a dummy and have no overhead - it depends on whether
you are delivering source or a library.

I think DEC used to use library substitution for single/multi threaded apps.

Jul 22 '05 #6
Nick,
This will significantly slow your code compared to native mutex calls which are often just macros with
no function call at all if there is no contention.
Are you saying that the overhead of the virtual member function call will
add significant overhead? Presumably the implementation member function
will contain such a native mutex call...
One responder suggested just linking to different versions which is fine but still not very efficient.
Because it still contains the above overhead? I've about ruled out this
approach, because it taints the abstraction with implementation details.
To get maximum speed the answer is templates
- parameterize everything with a class required to contain all the types and methods that you need. Default this parameter to ThreadUtil or some such.
- Have a Thread.h header that conditionally includes the appropriate system header, your platform specific thread class header and which typedefs the
platform specfic classes to ThreadUtil
- Make all the methods of your classes inline
I originally started to use templates, but after consulting the Mozilla
"Portabilit y Guide" I decided to avoid templates and inline functions -- do
you have any comments about this, or other comments on "extreme
portability"?
This mechanism works and is efficient but be warned - different systems
model threads and their control very differently - mutex/critical section is easy but there is apparently no simple equivalent to pthread cond in
Windows.
I'm just after mutex/critical section, that's all.
P.S. A good use for the library substitution approach is where your code is supposed to be thread safe but doesn't actually use threads itself (it is
obviously part of a library) - In this case you can provide a dummy for
applications that don't actually use threads. Alternatively you could use
the templates and have a dummy and have no overhead - it depends on whether you are delivering source or a library.

I think DEC used to use library substitution for single/multi threaded apps.

Jul 22 '05 #7

"Ed Fair" <ed*****@mindsp ring.com> wrote in message
news:pv******** ******@newsread 3.news.atl.eart hlink.net...
Nick,
This will significantly slow your code compared to native mutex calls which
are often just macros with
no function call at all if there is no contention.


Are you saying that the overhead of the virtual member function call will
add significant overhead? Presumably the implementation member function
will contain such a native mutex call...


Whether the overhead is significant can only really depend on your app but
since a lot of people use threads because they
want to be as fast as possible the overhead may be significant - it all
depend on the app and the granularity of the locking.

The implementation of lock and unlock may not invoke a function call at all
(I'm not guessing - I've looked at some headers).
The lock call only needs to make a call if the lock is already owned. The
unlock call only needs to make a call if something another thread is
waiting.
One responder suggested just linking to different versions which is fine but
still not very efficient.


Because it still contains the above overhead? I've about ruled out this
approach, because it taints the abstraction with implementation details.


I don't see how. It makes for a messy build but the abstraction is still
clean.
To get maximum speed the answer is templates
- parameterize everything with a class required to contain all the types and
methods that you need. Default this parameter to ThreadUtil or some such. - Have a Thread.h header that conditionally includes the appropriate

system
header, your platform specific thread class header and which typedefs the platform specfic classes to ThreadUtil
- Make all the methods of your classes inline


I originally started to use templates, but after consulting the Mozilla
"Portabilit y Guide" I decided to avoid templates and inline functions --

do you have any comments about this, or other comments on "extreme
portability"?

I cannot think of any reason to avoid these - were not talking anything
exotic here - no partial specializations - no defaults.

I don't know of any reason at all not to use inline functions. Code bloat is
a possibility but that isn't a portability issue.
This mechanism works and is efficient but be warned - different systems
model threads and their control very differently - mutex/critical section is
easy but there is apparently no simple equivalent to pthread cond in
Windows.
I'm just after mutex/critical section, that's all.


So you are creating a thread safe library of some sort?
P.S. A good use for the library substitution approach is where your code

is
supposed to be thread safe but doesn't actually use threads itself (it

is obviously part of a library) - In this case you can provide a dummy for
applications that don't actually use threads. Alternatively you could use the templates and have a dummy and have no overhead - it depends on

whether
you are delivering source or a library.

I think DEC used to use library substitution for single/multi threaded

apps.



Jul 22 '05 #8
Nick,
So you are creating a thread safe library of some sort?


Yes, it is a small static library I'm creating, for use within my
multi-threaded application only. I will apply what I learn here to a few
other static libraries that abstract other platform specific things (such as
logFile, tapeDrive, etc).

I'm maximizing my dogma here (and showing my ignorance too) because I'm "in
my first rewrite", having learned the hard way how *not* to write portable
code; my stated goal for the next version is platform independence and ease
of portability. That's why I'm trying so hard to minimize the source code
changes required upon each port. I have many source files that make up
this project, the biggest ones are becoming "platform independent", meaning
that they will not need to be "rewritten" for each port. However, they will
still at least need some tweaking... I'm guessing at least the factory
classes will have to be changed at each port, and some different includes
will be required at the top of each source file that is "platform
independent".

I've looked pretty hard for insight into this, without luck; including the
GNU Goat Book.

ed
Jul 22 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
6646
by: Medi Montaseri | last post by:
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;
6
5474
by: Boogie El Aceitoso | last post by:
Hi, I'd like to have a function factory that returns objects of a class hierarchy. What's the best way to deal with the fact that different subclasses will have different constructor arguments? How do you keep the factory interface as clean as possible? O:-) TIA
10
1898
by: Chris Croughton | last post by:
What do people call their factory functions? 'new' is not an option (yes, it can be overloaded but has to return void*). The context is: class MyClass { public: // Factory functions static MyClass* new(int);
4
2527
by: max | last post by:
Hello, I analyze this design pattern for a long time but I do not understand how this pattern work and what the purpose is? (I looked a this site http://www.dofactory.com/Patterns/PatternAbstract.aspx). Could anybody try to explain me in his own words how this pattern work and what the purpose is? thanks in advance
10
5142
by: Mark | last post by:
I have an abstract class, and a set of classes that inherit from my abstract class. The fact that it is abstract is likely irrelevant. I have a static factory method in my abstract class that creates subclasses. The constructor in my subclasses must be able to call the constructor in my base class. For the factory method in my abstract class to call the constructor on my subclasses, the constructor in the subclass MUST be public (or...
2
1716
by: Stig Nielsson | last post by:
I am wondering what is the most efficient way to make a parameterized factory method, and before I start spending time on performance measurements myself, I would like to hear the NG's opinion: I want my parameterized factory method to create either an object of type A or an object of type B, depending on the type of the Input parameter in the factory method. The type can be tested using the 'is' operator, but alternatively, the input...
5
4580
by: Anders Borum | last post by:
Hello! Whilst refactoring an application, I was looking at optimizing a ModelFactory with generics. Unfortunately, the business objects created by the ModelFactory doesn't provide public constructors (because we do not allow developers to instantiate them directly). Because our business objects are instantiated very frequently, the idea of using reflection sounds like a performance killer (I haven't done any tests on this, but the...
8
1769
by: googlegroups | last post by:
Hi, I need to parse a binary file produced by an embedded system, whose content consists in a set of events laid-out like this: <event 1<data 1<event 2<data 2... <event n<data n> Every "event" is a single byte in size, and it indicates how long is the associated "data". Thus, to parse all events in the file, I need to take it like a stream and read one event at a time, consuming bytes
8
1736
by: Steven D'Aprano | last post by:
I'm writing a factory function that needs to use keywords in the produced function, not the factory. Here's a toy example: def factory(flag): def foo(obj, arg): if flag: # use the spam keyword to method() return obj.method(spam=arg) else: # use the ham keyword
0
10313
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10147
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10081
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8968
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7494
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6735
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5378
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3643
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.