【问题标题】:Understanding the strategy pattern了解策略模式
【发布时间】:2014-10-27 01:32:48
【问题描述】:

我已经在网上寻找策略模式的好例子,但我发现的例子都是简化的方法。

我想实现 MyMatrix 类。 为此,我使用了策略模式,即我创建了一个 Matrix 类和两个继承类:RegMatrix 和 SparseMatrix,它们的实现不同。

我知道 MyMatrix 应该持有一个指向 Matrix 的指针(我们称之为 *_matrix),然后如果我想实现 MyMatrix 的“打印”函数,我应该这样做:_matrix->print() 然后它选择适当的实现。

唯一我不明白的是: 在获取数组和矩阵大小的 MyMatrix 的构造函数中,是否需要选择 某个 Matrix 类型的对象并对其进行初始化? 我的意思是,我应该这样做吗:

MyMatrix::MyMatrix(double arr[], unsigned int colSize, unsigned int rowSize)
{
    _colSize = colSize;
    _rowSize = rowSize;
    _matrix = new RegMatrix(arr, colSize, rowSize);
}

【问题讨论】:

  • 由于前导下划线保留在全局命名空间中并且对于各种名称的主机,使用下划线后缀比使用下划线前缀更安全

标签: c++ inheritance design-patterns polymorphism strategy-pattern


【解决方案1】:

常见的变体是将接口(矩阵)的实例传递给构造函数。

MyMatrix::MyMatrix(const Matrix& behaviour):
  colSize(behaviour.getCols()), rowSize(behaviour.getRows()), matrix(behaviour)
{
}

// creation
MyMatrix m(SparseMatrix(4, 2, arr));

使用初始化器。不要使用多余的下划线。见阿尔夫的评论。 colSize 和 rowSize 可能不需要,因为它们在 Matrix 实现中是重复的。

【讨论】:

    【解决方案2】:

    在C++中std::function可以看作是策略模式的通用实现。 “模式”这个词意味着不可能有具体的通用实现,但处理这种矛盾并不难。例如。直接忽略它。


    在我看来,C++ 中策略模式的一个很好的例子是一个通用的清理工具,一个作用域保护。在 C++03 中,实现范围保护涉及处理策略模式的内部方面,例如指向实现的指针,Petru Marginean 为此发明了an ingenious way 来利用临时绑定到引用的生命周期扩展。在 C++11 中,作用域保护类用std::function 的形式简单地表达:

    class Scope_guard
    {
    private:
        function<void()> cleanup_;
    
        Scope_guard( Scope_guard const& ) = delete;
        Scope_guard& operator=( Scope_guard const& ) = delete;
    
    public:
        void dismiss() { cleanup_ = []{}; }
    
        ~Scope_guard() { cleanup_(); }
    
        Scope_guard( function<void()> const& cleanup )
            : cleanup_( cleanup )
        {}
    };
    

    和使用一样

    void foo()
    {
        Handle const       h = createThingy();
        Scope_guard const  h_cleanup( [=]{ destroyThingy( h ); } );
    
        // Using h here.
    }
    

    为了直接使用 C 风格的接口,使用 C++ 风格的编码。

    免责声明 1:编译器未触及的代码。

    免责声明 2:尽管这与策略模式共享实现方面,但简单清理(即单个操作)是否是“算法”的问题并不完全清楚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多