Imagine that I have a job to do, which can be done in three different ways: a slow and painful, but failsafe way; the way with moderate suffering, given you have Resource1
; and a quick and easy way, which requires both Resource1
and Resource2
. Now, those resources are precious so I wrap them up into RAII-implementing ResNHolder
s and write something like this:
void DoTheJob(Logger& log/*, some other params */) {
try {
Res1Holder r1(/* arguments for creating resource #1 */);
try {
Res2Holder r2(/* arguments */);
DoTheJobQuicklyAndEasily(log, r1, r2);
}
catch (Res2InitializationException& e) {
log.log("Can't obtain resource 2, that'll slowdown us a bit");
DoTheJobWithModerateSuffering(log, r1);
}
}
catch (Res1InitializationException& e) {
log.log("Can't obtain resource 1, using fallback");
DoTheJobTheSlowAndPainfulWay(log);
}
}
"DoTheJobXxx()" take references to Logger
/ResNHolder
, because they are non-copyable. Am I doing it too clumsily? Is there any other clever way to structurize the function?
I think your code would be just fine, but here is an alternative to consider:
void DoTheJob(Logger &log/*,args*/)
{
std::unique_ptr<Res1Holder> r1 = acquireRes1(/*args*/);
if (!r1) {
log.log("Can't acquire resource 1, using fallback");
DoTheJobTheSlowAndPainfulWay(log);
return;
}
std::unique_ptr<Res2Holder> r2 = acquireRes2(/*args*/);
if (!r2) {
log.log("Can't acquire resource 2, that'll slow us down a bit.");
DoTheJobWithModerateSuffering(log,*r1);
return;
}
DoTheJobQuicklyAndEasily(log,*r1,*r2);
}
Where the acquireRes functions return a null unique_ptr when the resource fails to initialize:
std::unique_ptr<Res1Holder> acquireRes1()
{
try {
return std::unique_ptr<Res1Holder>(new Res1Holder());
}
catch (Res1InitializationException& e) {
return std::unique_ptr<Res1Holder>();
}
}
std::unique_ptr<Res2Holder> acquireRes2()
{
try {
return std::unique_ptr<Res2Holder>(new Res2Holder());
}
catch (Res2InitializationException& e) {
return std::unique_ptr<Res2Holder>();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With