C++ Decorator模式

Dug*_*las 5 c++ inheritance design-patterns stl decorator

我有一个向量和几个类(位于不同的文件中)来修改它.
我希望全局访问std::vector,但只有在派生类中,当每个调用存储前一个结果时,最后一个对象应该返回总结果

你能解释一下如何使用Decorator模式构建高性能接口std::vector吗?
我可能错了,可能需要其他模式.

// A.h
class A () {
      public : 
           vector<int> set(vector<int> &vec);

            //return total result
           vector<int> get() {
               return vector;
           }
};

// B.h
class B () {
    //add new elements into vector
    //for example, add 2,3,4
};

// C.h
class C () {
    //remove some elements from vector
    //for example, remove last element
};

//...

// main.cpp
#include "A.h"
#include "B.h"
#include "C.h"

int main () {

    vector<int> set;
    set.push_back(1); //1

    C obj(new B(new A()));
    obj.set(set);
    obj.get(); // stores 1,2,3 (added by classes A, B, C)
}
Run Code Online (Sandbox Code Playgroud)

所以,我不想这样做:

vector<int> set1;
set1.push_back(1);

A *A_init;
A_init->set(set1); //add 1

vector<int> set2 = A_init->get();

B *B_init;
B_init->set(set2); //add 2, stores 1,2

vector<int> set3 = B_init->get();

C *C_init;
C_init->set(set3); //add 3, stores 1,2,3

vector<int> set4 = C_init->get();

/..
Run Code Online (Sandbox Code Playgroud)

我想这样做:

vector<int> set;
set.push_back(1);

C obj(new B(new A()));
obj.set(set);
obj.get(); // stores 1,2,3
Run Code Online (Sandbox Code Playgroud)

我有一个模式装饰器的简单实现.
但这不是我需要的((

#include <iostream>
#include <memory>

class A {
    public:
        virtual void operation() = 0;
    };

class Component : public A {
    public:
        virtual void operation() {
            std::cout<<"World!"<<std::endl;
        }
};

class B : public A {
    std::unique_ptr<A> add;

public:
    B(A *component): add(component) {}

    virtual void operation() {
        std::cout << ", ";
        add->operation();
    }
};

class C : public A {
    std::unique_ptr<A> add;

public:
    C(A *component): add(component) {}

    virtual void operation() {
            std::cout << "Hello";
            add->operation();
    }
};

int main() {
    C obj(new B(new Component()));
    obj.operation(); // prints "Hello, World!\n"

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

PS:对不太清楚解释,因为我不太懂英语

Owe*_* S. 4

根据你的描述,装饰器不是要考虑的模式。

\n\n

在我看来,您只是想设置一个变压器链来对公共向量 \xe2\x80\x93 进行操作,即一个简单的函数组合。这与装饰器的不同之处在于与核心对象的关系——您不是构建一些东西来代替向量,而是构建一些东西来对其进行操作。现在,当您使用多个变压器时,理论上您可以将第二个及以后的变压器想象为装饰器,但考虑到所涉及的对象的简单性,尝试将 GoF 装饰器实现应用于您的情况可能会有点矫枉过正。

\n\n

你可以通过做这样的事情来接吻:

\n\n
#include <vector>\n\nusing namespace std;\ntypedef vector<int> ivec;\n\nivec& a(ivec& v) {\n    v.push_back(1);\n    return v;\n}\n\nivec& b(ivec& v) {\n    v.push_back(2);\n    v.push_back(3);\n    v.push_back(4);\n    return v;\n}\n\nivec& c(ivec& v) {\n     v.pop_back();\n     return v;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

共有三个简单的转换函数,每个函数的编写都是为了将​​一个函数的输出直接输入到下一个函数的输入中。然后你可以做类似的事情:

\n\n
ivec& xform(ivec& v) {\n    return c(b(a(v)));\n}\n\nivec v;\nxform(v);\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您只想静态构建最终转换并应用它。

\n\n

作为替代实现,假设您想动态构建一组变压器构建一组变压器。在这种情况下,您可以将函数推入变压器向量中并一一应用它们:

\n\n
#include <vector>\nusing namespace std;\n\ntypedef ivec& (*ivec_xformer)(ivec&);\ntypedef vector<ivec_xformer> xform_vec;\nxform_vec xforms;\nxforms.add(&a);\nxforms.add(&b);\nxforms.add(&c);\n\nivec v;\nfor (xform_vec::iterator i = xforms.begin(); i != xforms.end(); ++i) {\n   (*i)(v);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

顺便说一句,最后的循环可以使用boost::bindand进一步“简化”std::for_each顺便说一句,如果您愿意

\n\n

动态变压器链与责任链有一些相似之处,除了没有让特定对象通过“处理”请求来停止链的概念,即没有真正的责任此解决方案相关的\ xe2\x80\x93 每个函数在向量上获得相同的裂纹。我建议这种模式需要一个更好的名称 \xe2\x80\x93 ,这个名称可能已经存在,因为面向对象编程中的这种函数组合并不罕见,但目前我无法理解。

\n