c++ - 对基于 I/O 的对象执行一系列操作的设计模式

标签 c++ design-patterns

我发现自己经常按照以下顺序编写代码:

  1. 尝试打开基于 I/O 的资源(即来自数据库和/或文件)。这可能会失败。
  2. 如果成功,通过对象执行一系列操作。
    • 这些操作会根据用户输入而变化。比如:过滤数据,做A计算,做B计算,把结果写到某处。
    • 这些操作中的每一个都可能失败并返回一条错误消息。如果在任何时候发生故障,序列应该中止。
    • 有些操作必须先于其他操作完成:例如,写入结果不能发生在计算之前。
  3. 关闭资源。

有没有适合这种流程的设计模式?当我尝试将上述序列包装到一个类中时,我经常遇到的直接问题是:

  • 如何处理打开资源。理想情况下,我想在类构造期间打开它,但如果出现错误,那会变得困惑。否则,我必须在构造函数中传递对资源的引用,然后是 Open() 方法。
  • 如何使操作流程对对象的用户而言灵活,但又不会因为需要记住调用一堆中间方法和/或大量错误检查而给他们带来负担。

最佳答案

拒绝允许异常处理的组织往往是在一组错误的前提下工作。

话虽这么说,如果可以证明没有异常可以从相关代码块中逃脱,也许可以说服您的组织允许有限地使用异常:

#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>

struct exception_swallower
{
    void set_error(std::string msg)
    {
        success = false;
        message = std::move(msg);
    }
    bool success = true;
    std::string message;
};

std::ostream& operator <<(std::ostream& os, const exception_swallower& es)
{
    if (es.success) {
        return os << "success";
    }
    else {
        return os << "failure: " << es.message;
    }
}

// @pre stream shall be initialised with an r-value reference
// to a stream which has already had 'open' called on it.
//
template<class Stream, class Op>
exception_swallower perform_op_on_stream(Stream stream, Op op)
{
    // our non-exception return type
    exception_swallower ret;

    // catch all exceptions
    try {
        // check that stream did open
        if (!stream) {
            throw std::runtime_error("stream didn't open");
        }
        // perform the operations
        op(stream);
    }
    catch(const std::exception& e)
    {
        // reflect failures in the returned object
        ret.set_error(e.what());
    }
    return ret;
}

// some sample operations    
auto null_op = [](auto& ios)
{
    // do nothing
};

auto error_op = [](auto& ios)
{
    // throw an exception
    throw std::runtime_error("error in stream");
};


int main(int argc, char** argv)
{
    // note: the stream is created as a temporary, which
    // automatically yields an r-value reference.

    std::cout << perform_op_on_stream(std::ifstream(argv[0]), null_op) << std::endl;
    std::cout << perform_op_on_stream(std::ifstream(argv[0]), error_op) << std::endl;
}

预期输出:

success
failure: error in stream

关于c++ - 对基于 I/O 的对象执行一系列操作的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37467931/

相关文章:

python - Web 编程中的常见模式是什么?

ios - View 应该包含模型引用吗?

c++ - QuantLib C++ 库 - FixedRateBond 优惠券

c++ - 创建线程安全单例时的临界区初始化(C++)

c++ - 面向 C/C++ 程序员的数学资源

c++ - 在 C++ 中解析 RFC3339 日期

python - 如何删除这些 keras 指标定义的重复?

java - 我可以在同一版本的 Eclipse 中创建 C++ 和 Java 项目吗?

database - 数据库表的草稿版本

design-patterns - 观察者模式策略?