失败的抽象工厂建设的最佳实践

时间:2015-05-25 13:02:52

标签: c++ c++11

背景

假设我们有一个抽象工厂的实现,它被调用如下:

std::string ObjectName = "An Object Name";
std::string Args = "Argument passed directly to constructor by the factory";

std::unique_ptr<MyBaseClass> MyPtr(ObjectFactory::Instance().Construct(ObjectName,Args));

工厂使用std::map"An Object Name"转换为构造函数,构造函数本身将std::string作为参数。这个想法是用户比我更了解构造的对象,所以我应该让路,并让用户将他们想要的任何信息传递给构造函数。

问题

Args完全符合预期时,这种方法很有效,但我不知道处理duff输入的最常用的方法。如果用户提供无效的参数字符串会发生什么?

我能想到以下几点:

  • 让对象的构造函数抛出异常
  • 要求对象提供bool Validate(std::string x)方法,检查x是否为有效参数字符串
  • 让工厂使用默认构造函数,然后调用初始化方法(提出问题:如果init方法失败怎么办?)
  • 设置bool成员变量,如果为真,则表示&#34;此对象未处于合理状态&#34;
  • 其他一些我没有想到的选择

4 个答案:

答案 0 :(得分:6)

抛出异常。您构建一个对象(虽然方式与new不同),但失败是一个异常,如果可能发生则需要处理。

&#34;解决方案2&#34;与处理此问题无关,它更多的是如何来确定错误的输入。为此,它可以是一个可接受的解决方案,但它再次与手头的问题无关。

解决方案3在发生故障时使对象处于不确定状态,这是不可接受的。

解决方案4是另一种方法,如果你没有用你的语言提供异常支持,这是唯一的方法,但我们这样做。在我看来,这种情况下的例外情况严格要好,因为未能构造一个对象是一个非常具有破坏性的行为,它应该要求替代代码或程序死亡。

答案 1 :(得分:2)

第一个解决方案是构造函数失败的标准解决方案。 解决方案#2和#4非常容易出错(用户可能忘记检查) 解决方案#3无法解决问题

如果您正在创建库或只编写可能在“无异常允许”环境中重用的代码,您可以考虑返回std :: unique_ptr {nullptr}。即使它也容易出错,这是处理施工失败的另一种标准方法。

答案 2 :(得分:0)

也许最简单的方法是返回nullptr。

答案 3 :(得分:-3)

你做什么,不要从构造函数中抛出异常(按照更有效的C ++中的第10项),因为不会调用析构函数。它导致新手内存泄漏并迫使用户担心异常处理。

我只是断言并返回一个Null对象,使用虚拟工厂方法实现,或者返回nullptr。