失败的抽象工厂构建的最佳实践
Best practices for abstract factory construction that fails
背景
假设我们有一个抽象工厂的实现,它被调用如下:
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输入的最惯用的方法。如果用户提供了无效的参数字符串,该怎么办?
我可以想到以下内容:
- 让对象的构造函数引发异常
- require对象提供了一个
bool Validate(std::string x)
方法,该方法检查x
是否是有效的参数字符串 - 让工厂使用默认的构造函数,然后调用初始化方法(这引出了一个问题:如果init方法失败了怎么办?(
- 设置一个
bool
成员变量,如果为true,则表示"此对象不处于正常状态"> - 其他一些我没有想过的选择
抛出异常。您正在构建一个对象(尽管方式与new
不同(,失败是一个例外,如果可能发生,则需要进行处理。
"解决方案2"与处理此问题无关,它更像是如何确定错误输入。因此,这可能是一个可以接受的解决方案,但这与手头的问题无关。
解决方案3在出现故障时使对象处于不确定状态,这是不可接受的。
解决方案4是另一种方法,也是唯一的方法,如果你的语言中没有异常支持,但我们有。在我看来,这种情况下的异常要好得多,因为未能构造对象是一种破坏性很强的行为,应该需要替代代码或程序终止。
第一个解决方案是构造函数失败的标准解决方案。解决方案#2和#4非常容易出错(用户可能会忘记检查(解决方案#3不能解决问题
如果您正在创建一个库,或者只是编写可能在"不允许异常"环境中重复使用的代码,则可以考虑返回std::unique_ptr{nullptr}。即使它也容易出错,这也是处理施工失败的另一种标准方法。
也许最简单的方法是返回一个nullptr。
无论做什么,都不要从构造函数抛出异常(根据更有效C++中的Item#10(,因为析构函数将不会被调用。它会导致新手内存泄漏,并迫使用户担心异常处理。
我只会断言并返回一个Null对象,使用伪工厂方法实现,或者返回nullptr。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在c代码之间共享数据的最佳方式
- 使用std::source_location报告错误的最佳实践
- 派生类销毁的最佳实践是什么
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用Unique_ptr确保工厂中的对象唯一
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 带有继承的C++工厂
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 检测win32服务创建和删除的最佳方法
- 扩展此C++工厂实现的最佳方法
- 工厂函数的最佳智能指针返回类型是什么
- 失败的抽象工厂构建的最佳实践