0

I want to achieve API to client to look like this: (modifying subcomponents by using fluent interface)

FluentMainComponent("|FluentMainComponent|")
            .setA()
                .SetText("fa2")
                .Activate()
            .fluentPrint();

Is it possible?

I tried returning MainComponent, it looks like it did its purpose, but looks like I'm modifying FluentSubComponent instead of SubComponent is there way to achieve what I want?

I want to change MainComponent::subComponent.text so that MainComponent wouldn't have to know about FluentSubComponent

there is full code :

#include <string>
#include <iostream>

using namespace std;

class FluentMainComponent;

class SubComponent
{
    public:
    SubComponent(string ttext) 
    : text(ttext)
    { };

    void SetText(string ttext)
    {
        text = ttext;
    };

    string text;
};

class MainComponent
{
    public:
    MainComponent(string ttext) 
    : text(ttext)
    , subComponent("|MainComponent subComponent|") 
    { };

    void print()
    { 
        cout << "| MainComponent print subComponent " << subComponent.text << " this |" << this->text; 
    }

    private:
    string text;
    SubComponent subComponent;
};

class FluentSubComponent : private SubComponent
{
    public:
    FluentSubComponent(FluentMainComponent* fmc, string ttext) 
    : SubComponent(ttext)
    , fluentMain(fmc) 
    { };

    FluentSubComponent& SetText(string ttext)
    {
        return *this;
    };

    FluentMainComponent& Activate() 
    { 
        cout << "|FluentMain Activate|\n"; 
        return *fluentMain; 
    };

    private:
    FluentMainComponent* fluentMain;
};

class FluentMainComponent : private MainComponent
{
    public:
    FluentMainComponent(string ttext) 
    : MainComponent(ttext)
    , fluentSubComponent(this, " |FluentMainComponent fluentSubComponent| ") 
    { };

    FluentSubComponent& setSubComponent()
    {
        return fluentSubComponent;
    }

    FluentMainComponent& fluentPrint()
    {
        print();
        return *this;
    }

    private:
    FluentSubComponent fluentSubComponent;
};

int main()
{
    FluentMainComponent("|FluentMain|")
                .setSubComponent()
                    .SetText("wanted fluentSubComponent")
                    .Activate()
                .fluentPrint();
}

and output (reduced):

| MainComponent print subComponent |MainComponent subComponent| this ||FluentMain|

as You can see subComponent text is still defined by non-fluent constructor

Asmozan
  • 125
  • 1
  • 8
  • 2
    The `MainComponent::print` function prints `MainComponent::subComponent.text`, not `FluentMainComponent::fluentSubComponent.text`. The two sub-components are two distinct objects. – Some programmer dude Jan 03 '20 at 11:47
  • Yeah, I know that, I want to change MainComponent::subComponent.text so that MainComponent wouldn't have to know about FluentSubComponent – Asmozan Jan 03 '20 at 11:49
  • 2
    @Asmozan Then you need something like a separate accessor for that object, or associate the `FluentSubComponent` with it. – molbdnilo Jan 03 '20 at 12:04
  • oh, thats an idea! but it will be good practice to create another class just to handle that? Isnt there better option? – Asmozan Jan 03 '20 at 12:09
  • 1
    Prior to C++17, a fluent style of C++ was problematic (due to unspecified evaluation order). That has now been specified and valid for C++17. Details at: https://stackoverflow.com/questions/38501587/what-are-the-evaluation-order-guarantees-introduced-by-c17 – Eljay Jan 03 '20 at 12:32

0 Answers0