473,385 Members | 1,343 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Design problem: Factory pattern needs 'static virtual'?

I need a simple object serialization, where loading an object from
file looks like this:

Foo* foo1 = FooFactory::create("./saved/foo1.a321f23d");
Foo* foo2 = FooFactory::create("./saved/foo2.eb287ac8");

Now, Foo is an abstract base class, and FooFactory contains a static
function which again calls static create functions on Foo1 or Foo2
(see code for all classes below). The problem is that all these
functions are static, but I also want them to be part of the (virtual)
Foo interface. But virtual static functions are not allowed.

You might say that Foo1::create(...) should not be a member function,
but just a global function outside of Foo1. But I want classes derived
from Foo1 to be able to inherit or override create(...).

How should I design this properly?

Thanks! Markus

<code>

class Foo {
public:
// virtual static std::string type() const = 0; // not
allowed
// virtual static Foo* create(const std::string& dataLocation) =
0; // not allowed
// other functions that constiute the Foo
interface
};

class Foo1 : public Foo {
public:
static std::string type() {
static const std::string t = "Foo1";
return t;
}
static Foo* create(const std::string& dataLocation) {
return new Foo1(/* parameters according to data read from
dataLocation*/);
}
};
class Foo2 : public Foo1 {
public:
static std::string type() {
static const std::string t = "Foo2";
return t;
}
// function "create" is derived from
Foo1
};

namespace FooFactory {
Foo* create(const std::string& dataLocation) {
const std::string type =
getType(dataLocation);
if(type == Foo1::type()){
return Foo1::create(dataLocation);
}
else if(type == Foo2::type()){
return Foo2::create(dataLocation);
}
}
} // end namespace

</code>
Jan 3 '08 #1
2 2286
On Jan 3, 11:49*pm, Markus Dehmann <markus.dehm...@gmail.comwrote:
I need a simple object serialization, where loading an object from
file looks like this:

* Foo* foo1 = FooFactory::create("./saved/foo1.a321f23d");
* Foo* foo2 = FooFactory::create("./saved/foo2.eb287ac8");

Now, Foo is an abstract base class, and FooFactory contains a static
function which again calls static create functions on Foo1 or Foo2
(see code for all classes below). The problem is that all these
functions are static, but I also want them to be part of the (virtual)
Foo interface. But virtual static functions are not allowed.

You might say that Foo1::create(...) should not be a member function,
but just a global function outside of Foo1. But I want classes derived
from Foo1 to be able to inherit or override create(...).
How should I design this properly?
namespace FooFactory {
* Foo* create(const std::string& dataLocation) {
* * const std::string type =
getType(dataLocation);
* * if(type == Foo1::type()){
* * * return Foo1::create(dataLocation);
* * }
* * else if(type == Foo2::type()){
* * * return Foo2::create(dataLocation);
* * }
* }
look up "static polymorphism" or named conformance to an interface

Simply put , use a static create function and if a derived wishes to
override it adds its own static create function, which hides that in
the base class otherwise the compiler will find the base class
version, In fact there is no need for derivation, as any class with a
static create function , or whose base has a static create function
can be used, assuming the return type is viable.

regards
Andy Little

Jan 4 '08 #2
On Jan 4, 12:49 am, Markus Dehmann <markus.dehm...@gmail.comwrote:
I need a simple object serialization, where loading an object from
file looks like this:
Foo* foo1 = FooFactory::create("./saved/foo1.a321f23d");
Foo* foo2 = FooFactory::create("./saved/foo2.eb287ac8");
Now, Foo is an abstract base class, and FooFactory contains a
static function which again calls static create functions on
Foo1 or Foo2 (see code for all classes below). The problem is
that all these functions are static, but I also want them to
be part of the (virtual) Foo interface. But virtual static
functions are not allowed.
You might say that Foo1::create(...) should not be a member
function, but just a global function outside of Foo1. But I
want classes derived from Foo1 to be able to inherit or
override create(...).
I'm not sure I understand what you're asking for. You have
different derived classes of Foo, each with its own function
create. You want the compiler to somehow call the correct
instance of create, according to the dynamic type. But the
dynamic type of what? How do you determine which Foo??::create
should be called?
How should I design this properly?
<code>
class Foo {
public:
// virtual static std::string type() const = 0; // not
allowed
// virtual static Foo* create(const std::string& dataLocation) =
0; // not allowed
// other functions that constiute the Foo
interface
};
class Foo1 : public Foo {
public:
static std::string type() {
static const std::string t = "Foo1";
return t;
}
static Foo* create(const std::string& dataLocation) {
return new Foo1(/* parameters according to data read from
dataLocation*/);
}};
class Foo2 : public Foo1 {
public:
static std::string type() {
static const std::string t = "Foo2";
return t;
}
// function "create" is derived from
Foo1
};
namespace FooFactory {
Foo* create(const std::string& dataLocation) {
const std::string type =
getType(dataLocation);
if(type == Foo1::type()){
return Foo1::create(dataLocation);
}
else if(type == Foo2::type()){
return Foo2::create(dataLocation);
}
}
} // end namespace
</code>
Wouldn't some sort of table be more appropriate? Say an
std::map< std::string, Foo* (*)( std::string ) >. With:

typedef std::map< std::string, Foo* (*)( std::string ) >
FooFactoryMap ;
FooFactoryMap ourMap ;

Foo*
create(
std::string const& dataLocation )
{
FooFactoryMap::const_iterator
entry
= ourMap.find( getType( dataLocation ) ) ;
return entry == ourMap.end()
? NULL
: (*entry->second)() ;
}

You'll have to arrange to initialize the map somehow, but that
shouldn't be any more of a bother than maintaining all of your
if's.

James Kanze (GABI Software) mailto:ja*********@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

Jan 4 '08 #3

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

Similar topics

3
by: Omer van Kloeten | last post by:
The Top Level Design: The class Base is a factory class with a twist. It uses the Assembly/Type classes to extract all types that inherit from it and add them to the list of types that inherit...
0
by: ma740988 | last post by:
I've provided a stripped down version - as best I could - to get us by. That said, I'm in a quandry with respect to a design here. Consider: // stream.h #ifndef STREAM_H #define STREAM_H #...
0
by: ma740988 | last post by:
I'm going through modern C++ design looking for tips and while hi-tech I suspect one solution to my issue would involve the factory design pattern. // algorithms.h class Algorithms {...
31
by: cctv.star | last post by:
I was wondering, why you always have to remember to call bases' constructors explicitly from the derived class constructor? Why hasn't this been enforced by the language?
2
by: Mike | last post by:
Hello NG, i am just learning various Design Patterns and now i am not sure, if this design is correct (Builder) or if i should use an other pattern. I have various classes (here ChildA and...
10
by: sunny | last post by:
Does this following program implement the factory design.if not what are things that i have to change in order to make this following program to be designed to factory design pattern. ...
1
by: =?Utf-8?B?RXJpYw==?= | last post by:
I am using the factory method to solve a problem where a factory can produce product. I have a base factory class and a base product class. The problem that I am having is that for every product...
3
weaknessforcats
by: weaknessforcats | last post by:
Design Pattern: The Singleton Overview Use the Singleton Design Pattern when you want to have only one instance of a class. This single instance must have a single global point of access. That...
11
by: digz | last post by:
Hello, Apologies if this is the wrong group for this question. I want to design an interface , where for a custom functionality , the client writes a new class with the function implementation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.