Search code examples
c++oopfortranstrategy-pattern

Can we dynamically insert operations to our function?


In this thread link, concerns the discussion on real example of using the strategy design pattern. The second answer which shows an example of dynamically inserting rules to whether approve/decline the assignment of products to people with the RuleAgent. This set of rules is invoked using the function IsApproved.

The example shows what if we wanted to add two more rules, like an intern rule and overtime rule. My question relates to how do we ensure that our polymorphic call to IsApproved would call ALL the added rules. The question has also been asked in the comment to that answer but no replies.

Could you please comment on how to do this on C++ and/or (if possible) Fortran.


Solution

  • This example sidesteps polymorphism, where the agent is a vector of function pointers that can be dynamically added to and removed from :

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    class Person
    {
    public:
        int _timesheet = 50;    
        std::string _title = "Intern";
    };
    
    class Assignment
    {
    public:
        Person _person;
    };
    
    namespace OvertimeRule
    {
    bool IsApproved(Assignment const& assignment)
    {
        return assignment._person._timesheet >= 40;
    }   
    }
    
    namespace InternRule
    {
    bool IsApproved(Assignment const& assignment)
    {
        return assignment._person._title == "Intern";
    }   
    }
    
    int main()
    {
        Assignment testAssignment;
    
        std::vector<bool(*)(Assignment const&)> assignmentAgent;
        assignmentAgent.push_back(&OvertimeRule::IsApproved);
        assignmentAgent.push_back(&InternRule::IsApproved);
    
        bool const testSuccess = std::all_of(assignmentAgent.begin(), assignmentAgent.end(), 
            [&testAssignment] (auto const& Func)
        {
            return Func(testAssignment);
        });
    
        if(testSuccess)
        {
            std::cout << "Requirements Met!";
        }
        else
        {
            std::cout << "Requirements Not Met!";
        }
    }