作为B类成员的A类对象,B要求A的对象初始化自身

时间:2016-11-20 16:28:04

标签: c++ design-patterns

RequestStreamer只想帮助请求流式传输。有没有更好的方法来实现它,而不是你在下面看到的?

这种代码适合哪种设计模式?它会是所有者模式还是帮助模式?

此示例有助于显示A和B之间的关系。

var item1 = Path.Circle(new Point(180, 100), 20);
item1.fillColor = "black";

var item2 = Path.Rectangle(new Point(150, 180), new Size(50, 50));
item2.fillColor = "black";

var selection = new Path([
    new Point(50, 50),
    new Point(50, 250),
    new Point(250, 250),
    new Point(250, 150),
    new Point(150, 150)
]);
selection.closed = true;

selection.strokeColor = "blue";
selection.fillColor = new Color(0, 0, 50, 0.5);

function selectionContains(item) {
    // does not work as expected
    return selection.intersects(item);
}

// should be false
console.log(selectionContains(item1));

// should be true but is false
console.log(selectionContains(item2));

3 个答案:

答案 0 :(得分:1)

根据你的代码:A还要求B的对象初始化自己。 这意味着存在关联1< - >。两个班级之间有1个。 这两个类都需要一个指向彼此的指针(这不是" B帮助A",因为类之间存在很强的相关性)。 但是为了确保RequestStreamer只能来自Request,将其构造函数变为private,并使Request成为朋友类。

答案 1 :(得分:1)

这里有很多模式 - 但它们并不清楚,而且这些课程似乎对他们的角色感到困惑。

我将这些类拆分了一些并使用了一剂策略模式 - 并将策略/数据作为Request构造函数参数传递。所有这些都会给这样的东西带来更多。 (这里还有很多潜在的清理......但我认为关注点的意图和分离更加清晰)

// What I'm sending
class IRequestContent {
   virtual int getContentLen() = 0;
   int getBytes (int nBytes) = 0;
};

// How I'm sending it
class IRequestStreamerStrategy {
   virtual bool initialize(IRequestContent * content, IRequest * req) = 0;
   virtual bool streamReq(IRequestContent * content) = 0;
};

// The combination of what I'm sending and how I'm sending it
class Request : public IRequest {
    shared_ptr<IRequestStreamerStrategy> streamer;
    shared_ptr<IRequestContent> content;

public:
    Request(
        shared_ptr<IRequestStreamerStrategy> streamer,
        shared_ptr<IRequestContent> content
    ) : streamer(streamer), content(content)
    {}

    bool initialize () {
        streamer->initialize(content, this);
    }

    bool sendReq() {
        return streamer->streamReq(content);
    }
};

class RequestStreamer : public IRequestStreamerStrategy {

    bool bEnabled;
    int chunkSize;

public:
    RequestStreamer() { chunkSize = 1024*1024; }

    bool initialize(IRequestContent * content) {
        if ( content->getContentLen() > chunkSize )
            bEnabled = true;
    }

    bool streamReq(IRequestContent * content) {
        if (!req) return false;

        // Assume that there exists socket object implementation already
        if (bEnabled) {
            while (content->getBytes(chunkSize) != -1)
                socket->send(content->getBytes(chunkSize));
        } else {
            socket->send(content->getBytes(content->getContentLen()));
        }
    }
};

答案 2 :(得分:0)

您在类Request中声明构造函数和析构函数私有,因此您无法实例化您的类(访问私有成员数据)。

  • 你也让类Request包含一个指向RequestStreamer类的指针,所以你必须forward declare类RequestStreamer。

  • 您使类RequestStreamer contains成为类Request的指针,因此每个两个类都有一个指向彼此的指针,因此each class must be implemented before the other因为您不能使用不完整的对象。结果你无法以这种方式解决它。

  • 解决它考虑使用模板: 这是模板的一个例子:

    #include <iostream>
    using namespace std;
    
    template <class T> class A;
    template <class T> class B;
    
    template <class T>
    class A
    {
        public:
            A();
            ~A();
        private:
            B<T>* ptrB;
    };
    
    template <class T>
    class B
    {
        public:
            B();
            ~B();
        private:
            A<T>* ptrA;
    };
    
    template <class T>
    B<T>::B() : ptrA(new A<T>)
    {}
    
    template <class T>
    B<T>::~B()
    {
        delete ptrA;
    }
    
    template <class T>
    A<T>::A() : ptrB(new B<T>){}
    template <class T>
    A<T>::~A() { delete ptrB;}
    
    int main()
    {
        A<int> a;
        B<char> b;
    
        return 0;
    }