0

There's quite a bit of info on this topic. This is more of a design question, but I will give examples.

Let's say that I literally want to pass around a profile class, that dictates policies of a user.

struct ApplicationAllowedPolicy
{
public:
    bool hasAccess() { return true; }
}

struct ApplicationProhibitedPolicy
{
public:
    bool hasAccess() { return false; }
}

template<typename ApplicationPolicy>
class Profile : private ApplicationPolicy
{
    bool hasAccess() { return ApplicationPolicy::access(); }
}

int main()
{
    Profile<ApplicationAllowedPolicy> allowed;
    Profile<ApplicationProhibitedPolicy> prohibited;

    // do something with allowed & prohibited
}

The above is all fine and dandy, but let's assume there are a lot of policies that need to be read in. 5 Seems like a realistic real world number, although it could be more. Then, let's assume that this profile will be applied to hundreds of instances, with the 5 policies varying greatly. To boot, the policy behavior would only be known at run time (read from file, db, whatever). This quickly becomes unscalable, unless I'm totally missing something.

I thought of doing a non-type template class as a policy.

template<int N>
struct ApplicationPolicy
{
    int policy = N;
};

Profile<ApplicationPolicy<1>> allowed;
Profile<ApplicationPolicy<0>> prohibited;

I think this would indeed work for my situation, but I'm wondering if this is missing the point of policy based design. I'm having problems seeing the pros of this over just have Profile be a normal struct, and just set it's data members to true/false as needed.

Thoughts?

kiss-o-matic
  • 1,111
  • 16
  • 32
  • Is this all there is to your policy? Does it contain more information/specific behavior? As it is now, you can templatize your `Profile` class on a single boolean and be done with it. Also, I didn't get the part on policy behavior being known at runtime... templates are instantiated at compile time. – JorenHeit Aug 04 '15 at 21:41
  • Sorry if I was unclear. Yes, there is more to it, but this was a simple example. Imagine a handful of boolean policies, plus a few that might return vectors of viewable objects. Etc. As for the runtime, that was bad jargon. From a lot of the examples I see, ultimate class that uses the policies seems rather static - created in a main with a single idea in mind. I need something a lot more dynamic. Heading out the door but will edit later if need be. – kiss-o-matic Aug 05 '15 at 00:49

2 Answers2

0

Policy-based design is very useful when the behaviour of the class changes significantly depending on a policy. For example, say you want your class to be used both in multithreaded and regular context. Then you could implement this as a threading policy:

class SingleThreadedPolicy { /* ... */ }; // lock() does nothing
class MultiThreadedPolicy { /* ... */ }; // lock() actually locks

template<class T, class ThreadingPolicy>
class Queue {
    ThreadingPolicy threadPol_;
    // ...
    T pop() {
       threadPol_.lock();
       // remove an element from the queue
       threadPol_.unlock();
       return element;
    }
};

Now, two other ways to achieve the same result is to use (multiple?) inheritance or to set a flag in the object and write a lot of ifs. The first option quickly breaks down if you have several policies, such as storage, ownership, etc. The second leads to unmaintainable code.

So, if your class needs many orthogonal moving parts, policy-based design is a good choice, and it will be much more scalable than other approaches.

However, your example does not really seem to need this approach. Access seems to be integral to it: if you are going to call hasAccess() in your code anyway, you can safely replace it with a boolean variable.

Maksim Solovjov
  • 3,147
  • 18
  • 28
  • As per the comment above, this was just a simple illustration. Instead of a boolean for an application, a policy might return some type of container of data the client is allowed to view/edit. If they have no access, it might return an empty container, or something along these lines. The part I'm not wrapping my head around for implementation, is imagine I've got a DB record of multiple users and each one will use multiple policies depending on the user. How do I instantiate my class w/o a ton of if statements? – kiss-o-matic Aug 05 '15 at 00:55
  • I think you are on the wrong lead. To answer your question, you would employ the Builder pattern, building the information about the object in stages and then instantiating a proper object based on that information (i.e. by mapping input set to a factory function). It would return a smart pointer to the abstract base class, from which you derive your policy template. However, for the profile class, you are choosing the wrong design. – Maksim Solovjov Aug 05 '15 at 08:05
  • I can't quite see how you would decompose Profile into proper policies. A class should preferably have single responsibility, just like a function. So, again, if different people have different access to some data, provide a non-member function that takes your profile as a parameter and returns whatever they can see. Maybe I am wrong -- could you provide a list of all the policies you are thinking about? – Maksim Solovjov Aug 05 '15 at 08:10
  • 1
    The more I think of it, the more I think you're right. Kind of why I wanted to think out loud on this one. As for a list of policies, the other reason I'm trying to figure this out before getting too long into it might grow into something quite large. (Project is still in it's infancy). Realistically, it could be an all-encompassing mechanism that dictates how something behaves. Where it connects, read permissions, write permissions, and maybe even some other settings. Cheers for your help. I'll go ahead and mark this as answered as it did pretty much answer my question. – kiss-o-matic Aug 05 '15 at 12:14
0

If you want to vary the behaviour at runtime, use the strategy pattern instead of a policy based design.

dangerousdave
  • 6,331
  • 8
  • 45
  • 62