templated Attorney-Client Idiom for more many classes

大憨熊 提交于 2019-12-24 10:37:34

问题


I was trying to apply the Attorney-Client Idiom (know as PassKey Idiom) and this for two classes.

I explain :

I have a class named Secret which contains name and age as private members. I have created a class Attorney which defines 2 getters for each memeber in class Secret.

I want to create 2 classes:

  1. showAge which only have access to 1 getter
  2. showAgeAndName which has access to both getters.

So far all works fine, but looking at the code, it not well maintainable : if I add new members to my Secret and want a specific access to new getters I have to add another class and end with lot of copy-paste.

So is there a better alternative like : using Factory design pattern / enhance the templated class ...

Below is my code:

#include <string>
#include <iostream>

using namespace std;

class Secret;
class showAge;
class showAgeAndName;

template<typename T>
class Attorney
{
private:
    friend T;
    Attorney(const Attorney&) {}
    Attorney() {}   
};

class Secret
{
public:
    std::string getAge(Attorney<showAge>) noexcept { return "Age is " + to_string((long long)age); }
    std::string getName(Attorney<showAgeAndName>) noexcept { return "Name is " + name; }
private:
    int age{36};
    std::string name{"Mike"};
};

class showAge
{
public:
    showAge() noexcept {};

    void showInfos(Secret& src)
    {
        std::cout << src.getAge(Attorney<showAge>()) << std::endl;
    }
};

class showAgeAndName
{
public:
    showAgeAndName() noexcept {};

    void showInfos(Secret& src)
    {
        std::cout << src.getName(Attorney<showAgeAndName>()) << std::endl;
    }
};

int main() {
    Secret s;
    showAge prA;    
    showAgeAndName prAn;
    prA.showInfos(s);
    prAn.showInfos(s);
}

Thank you


回答1:


In my opinion this pattern is more trouble than it's worth.

Instead, maybe you'd consider defining interfaces for each access role, then pass the object around by references to the appropriate interface type. This is likely to be far more readable and intuitive, although it still requires you to define and maintain interfaces for each role.

The interfaces and which member functions they expose should be chosen to suit the access roles. You do not necessarily need a separate interface for each function. If you think you do, I'd view that as a code smell and take it as a cue to reevaluate the design. This is true when using the Attorney-Client / PassKey pattern as well.

The only advantage the Attorney-Client / PassKey pattern has is that it doesn't require the member functions to be virtual. But it is very likely that the performance cost of virtual functions is not important to your application.

A disadvantage is that the Attorney-Client / PassKey pattern encourages you to design the "interfaces" based on specific users (as in specific classes that access the Secret). This creates coupling. It is better to think in terms of generic roles, which can be assigned as appropriate.



来源:https://stackoverflow.com/questions/53172759/templated-attorney-client-idiom-for-more-many-classes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!