473,383 Members | 1,818 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,383 software developers and data experts.

HOWTO use a Factory

Hi all,

i have some questions/problems about "Factories".

My origin is a constructor which needs a string in special format.

An example:

class Example_t {

public:
Example_t(std::string &aString);
...
}

My first idea was to check "aString" IN the constructor with
"boost::regex" AND to throw an exception if "aString" was bad.

Now I know it's bad to throw an exception in a constructor.

But what else?

How can I AVOID elegant a construction of an instance of "Example_t"
if "aString" is in bad format?

I've read a lot at the net but I'm still unhappy. At some other forum
I got the information to use something like that:

class Validator
{
public:
virtual bool validate(std::string) = 0;
};

class A
{
private:
A();
};

class Factory
{
public:
static A createA(std::string, *Validator);
static B createB(std::string, *Validator);
};

But I don't understand how to AVOID a construction with classes above
if the string is in bad format?

Thanks

Goran

Aug 22 '07 #1
8 1392
Goran wrote:
i have some questions/problems about "Factories".

My origin is a constructor which needs a string in special format.

An example:

class Example_t {

public:
Example_t(std::string &aString);
...
}

My first idea was to check "aString" IN the constructor with
"boost::regex" AND to throw an exception if "aString" was bad.

Now I know it's bad to throw an exception in a constructor.
No, it's not bad. It's the only way to let the caller know that
construction cannot be completed.
But what else?
Depends.
How can I AVOID elegant a construction of an instance of "Example_t"
if "aString" is in bad format?
Check before trying to construct it.
I've read a lot at the net but I'm still unhappy. At some other forum
I got the information to use something like that:

class Validator
{
public:
virtual bool validate(std::string) = 0;
Try to pass by reference to const wherever possible.
};

class A
{
private:
A();
};

class Factory
{
public:
static A createA(std::string, *Validator);
static B createB(std::string, *Validator);
};

But I don't understand how to AVOID a construction with classes above
if the string is in bad format?
The only "elegant" way that comes to mind is to return *a copy* of some
kind of "invalid" or "generic" object that can be inquired about its own
validity and discarded by the caller.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 22 '07 #2
On Aug 22, 11:52 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Goran wrote:
[...]
Now I know it's bad to throw an exception in a constructor.

No, it's not bad. It's the only way to let the caller know that
construction cannot be completed.
Ok, it's not bad :) but how could i use a try/catch with such a
constructor?

try {
Example_t myExample("fooBar");
}
// myExample is lost...
catch(...) {
cout << "Exception" << endl;
}
But what else?

Depends.

[...]

The only "elegant" way that comes to mind is to return *a copy* of some
kind of "invalid" or "generic" object that can be inquired about its own
validity and discarded by the caller.
How looks like such an object :) ?
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Greets

Goran

Aug 22 '07 #3
On Aug 23, 12:01 am, "Alf P. Steinbach" <al...@start.nowrote:
* Goran:
[...]

However, you might and should probably consider introducing a class
ValidXXX that represents valid strings of whatever the format is.

Then the failure to validate can be detected as near to the source of
the string as possibly (by having /that/ class' constructor throw), and
valid strings can then be passed around as ValidXXX instances with no
need to check them everywhere for validity: you know they're valid.

This general principle of not passing possibly invalid data around tends
to simplify code enormously, thus also reducing the number of bugs.

And it's very very closely tied in with the concept of throwing from
constructors, so that you know that if you have an object at hand, then
that is perforce a /valid/ object with some class invariant established.
Ahh, that's a good way I think...

Greets

Goran

Aug 22 '07 #4
Goran <po**********@gmail.comwrote in news:1187820543.379157.37740
@i13g2000prf.googlegroups.com:
On Aug 22, 11:52 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Goran wrote:
[...]
Now I know it's bad to throw an exception in a constructor.

No, it's not bad. It's the only way to let the caller know that
construction cannot be completed.
Ok, it's not bad :) but how could i use a try/catch with such a
constructor?

try {
Example_t myExample("fooBar");
}
// myExample is lost...
Yes, and why is that bad? A valid Example_t was unable to be created.
catch(...) {
cout << "Exception" << endl;
}
Aug 22 '07 #5
Goran wrote:
On Aug 22, 11:52 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Goran wrote:
[...]
>>Now I know it's bad to throw an exception in a constructor.

No, it's not bad. It's the only way to let the caller know that
construction cannot be completed.
Ok, it's not bad :) but how could i use a try/catch with such a
constructor?

try {
Example_t myExample("fooBar");
}
// myExample is lost...
Yes, here it's lost. Put all your code inside the 'try' clause.
catch(...) {
cout << "Exception" << endl;
}
>>But what else?

Depends.

[...]

The only "elegant" way that comes to mind is to return *a copy* of
some kind of "invalid" or "generic" object that can be inquired
about its own validity and discarded by the caller.
How looks like such an object :) ?
If you meant to ask, "what does such an object look like?", then
I have no idea since it's *your* object, *your* problem domain,
*your* model.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 23 '07 #6
Hi!

Goran schrieb:
How looks like such an object :) ?
The easiest would be a "bool" to indicate success:

class MayFail
{
bool failed;
public:
MayFail(string const& input);
bool isGood() const throw() { return !failed; }
bool isBad() const throw() { return failed; }
};
MayFail::MayFail(string const& input)
: failed(true)
{
if(input.empty())
return; //failed
if( (input.length() & 1) == 0 )
return; //failed
...
failed = false; //success
}

MayFail mf("Hello");
if(mf.isBad())
reportError("MayFail failed");

HTH,
Frank
Aug 23 '07 #7
"Alf P. Steinbach" <al***@start.nowrote in
news:13*************@corp.supernews.com:
>
However, you might and should probably consider introducing a class
ValidXXX that represents valid strings of whatever the format is.

Then the failure to validate can be detected as near to the source of
the string as possibly (by having /that/ class' constructor throw),
and valid strings can then be passed around as ValidXXX instances with
no need to check them everywhere for validity: you know they're valid.

This general principle of not passing possibly invalid data around
tends to simplify code enormously, thus also reducing the number of
bugs.

And it's very very closely tied in with the concept of throwing from
constructors, so that you know that if you have an object at hand,
then that is perforce a /valid/ object with some class invariant
established.
I have to strongly agree with this. :) I find it best to validate data
coming into the application as early as possible. For one thing, it
makes it easier to pinpoint where the problem originates and reprompt
the user if necessary for valid data. It also allows you to assume
correctness for the rest of the application (at least in release builds,
you might want some asserts here and there to validate assumptions about
the data that are active in debug/development builds.).

Another thing that comes to mind... You didn't mention whether this
data comes from the user or another programmer on the team. If it's the
later, then you may just want to validate in debug builds and make the
programmer fix his erroneous code rather than go through a possibly
expensive validation process all the time. In other words, some design
choices vary depending upon the target audience. For example, we would
all hate it if the STL did too much parameter validation each time we
tried to use it.

joe
Aug 23 '07 #8
Now I know it's bad to throw an exception in a constructor.
It is bad to throw an exception from a destructor since the
destructors are used for stack unwinding (destroying objects on the
stack) after an exception.
Throwing an exception from a constructor is not so much a problem.

Best regards,
Tobias

Aug 23 '07 #9

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

Similar topics

17
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....
2
by: Ryan Mitchley | last post by:
Hi all I have code for an object factory, heavily based on an article by Jim Hyslop (although I've made minor modifications). The factory was working fine using g++, but since switching to the...
4
by: Eric | last post by:
Perhaps this question has been posed before (I'd be surprised if it hasn't) but I just gotta know... Is it possible to combine the Singleton and Factory Method design patterns in the same class?...
10
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...
6
by: Dave | last post by:
Hello all, Please see my question embedded in comment form below. Thanks, Dave #include <iostream> #include <boost/shared_ptr.hpp>
8
by: deko | last post by:
Which layer should a Factory class go in? DA - Data Access BL - Business Logic UI - User Interface ??
4
by: Rainer Queck | last post by:
Hi NG, I am looking for a good way to dynamically generate a bunch of TabPages. I have a list of more or less identical object. For each of these objects I need a user interface. My thought...
4
by: Bernd Muent | last post by:
Hi together, I made a DLL in the following way (simplified example just to explain what is the problem) using devcpp and gcc compiler on Windows XP: dll.h: #ifndef _DLL_H_ #define _DLL_H_ #if...
6
by: Nindi | last post by:
5 Files Singleton.h The Singleton Factory.h The factory creating new objects. The Base class of the hierachy stores a typelist identifying the signature of the constructors to be called...
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
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: 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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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.