首页 > 解决方案 > 如何从注入的策略模式中调用 IMPL 的成员函数

问题描述

因此,我的任务是在现有代码库上实施策略模式。下面的代码是我用于演示目的的代码的一个非常简化的版本。我没有太多的余地来重新设计 WorldTraversal 类。所以我遇到的问题是我对 PIMPL 习语不太熟悉,这让我对如何处理这个问题产生了一层疑问。

策略中的 apply 方法将需要执行 impl 中定义的两个方法。但我不确定如何在不将它们暴露于公共界面的情况下访问它们。我曾尝试使用 std::function,并将方法作为参数传递,但我不确定在 impl 上绑定方法的语法(即使应该尝试这样做)。

任何援助将不胜感激。

// The main class/object that will need to execute different strategies based on the situation
class WorldTraversal
{
public:
    void setStrategy(ITraversalStrategy&& strategy) { m_impl->strategy = std::move(strategy); }
    void execute()
    {
        // Apply needs access to methods in the impl but they are not static
        m_impl->traversalStrategy->apply(std::bind(&m_impl->processPath, *m_impl), std::bind(&m_impl->executePath, *m_impl)); // Can I even do this given the impl is a unique_ptr??
    }

private:
    struct Impl;
    std::unique_ptr<Impl> m_impl;
}

// The IMPL which contains (at least) two methods I would need to call
struct WorldTraversal::Impl
{
    Impl() {}

    void processPath();
    void executePath();

    std::unique_ptr<ITraversalStrategy> traversalStrategy;
}

WorldTraversal::Impl::processPath() {}
WorldTraversal::Impl::executePath() {}

// The strategy (I left the interface out for brevity)
class GroundTraversal : public ITraversalStrategy
{
public:
    using ProcessPath = std::function<void()>;
    using ExecutePath = std::function<void()>;

    virtual void apply(ProcessPath processPath, ExecutePath executePath) override
    {
        // Implementation of the actual strategy goes here
        // I need to be able to call processPath and executePath in here
        // Different strategies may need to call these differently etc.
        processPath();
        executePath();
    }
}

int main()
{
    WorldTraversal worldTraversal;

    // Could be ground, air, water etc.
    worldTraversal.setStrategy(std::make_unique<GroundTraversal>());
    worldTraversal.execute();

    return 0;
}

标签: c++design-patternsstrategy-patternpimpl-idiom

解决方案


推荐阅读