具有多种表示形式的项目的 C++ 设计模式

C++ design pattern for an item with multiple representations

我有一个 "item",其数据可以用 3 种方式表示。我可以以运行时成本从一种表示形式转换为任何其他表示形式。完成转换后,我想保留新的表示形式。任何数据表示都可以在没有 "modifying" 核心数据的情况下转换为任何其他数据。由于运行时成本,我想要一个包含 3 个数据表示的 class。在任何时候,其中 1 到 3 将是有效的。

真正的意义在于它还有访问方法,用户可以在其中请求一些东西。这个东西可以从 1 个或多个表示中获得。例如,您可以从表示 1 中获取 "range",从表示 2 或 3 中获取 "volume"。

我的解决方案是创建 class,将 3 个表示作为成员数据(以及一种了解它们是否有效的方法)。然后我创建了一个 getRange() 方法,它在内部知道它需要哪种表示形式,并在必要时创建它。这工作正常并解决了我所有的问题,除了 get 方法不能是常量。

所以这个解决方案的真正问题是,即使这个 class 的 "constant" 实例也不是真正的 const,因为它在内部可能会创建其他表示。然而,它确实是 "constant",因为更改表示不会修改核心数据。

是否有 C++ 设计模式可以对此有所帮助 class?有什么建议吗?

My solution was to create class with the 3 representations as member data (and a way to know if they are valid). Then I created a getRange() method that internally knows which representation it needs and creates that if necessary. This works fine and solves all my issues except that the get method cannot be const.

这就是指定 mutable 类型的目的!为了能够在仍然具有 const 方法的同时更新内部表示,使表示属性 mutable:

struct A {

    int get_range() const {
        if (!_repr2.is_valid()) {
            _repr2 = Repr2(_repr1); // I am in a const method, but still
                                    // I can update a mutable attribute
        }
        return _repr2.get_range();
    }    

private:
    mutable Repr1 _repr1;
    mutable Repr2 _repr2;
};

Here is a full example with two representations that uses std::unique_ptr 存储表示,以便您可以轻松检查一个是否已实例化。

根据 Holt 的回答,可变是这里需要的主要内容。您还可以受益于 boost::optional<ReprX> 来存储表示。这有助于解决您问题的 'a way to know if they are valid' 部分:

struct A {

    int get_range() const {
        if (!_repr2) {
            _repr2 = Repr2(*_repr1); 
        }
        return _repr2->get_range();
    }    

private:
    mutable boost::optional<Repr1> _repr1;
    mutable boost::optional<Repr2> _repr2;
};