用于更多课程的模板化律师-客户惯用语

时间:2018-11-06 13:20:46

标签: c++ templates design-patterns idioms

我试图将“律师-客户”习语(称为PassKey习语)应用于这两个课程。

我解释:

我有一个名为Secret的类,其中包含nameage作为私有成员。我创建了一个类Attorney,它为类Secret中的每个成员定义了2个getter。

我想创建2个类:

  1. showAge,只能访问1个getter
  2. showAgeAndName可以访问两个getter。

到目前为止,一切正常,但是看代码,它的维护性很差:如果我将新成员添加到Secret中,并且想要对新的getter进行特定的访问,则必须添加另一个类并以很多结尾复制粘贴。

那么有没有更好的选择,例如:使用Factory设计模式/增强模板化类...

下面是我的代码:

#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);
}

谢谢

1 个答案:

答案 0 :(得分:1)

在我看来,这种模式比它值得的麻烦更多。

相反,也许您会考虑为每个访问角色定义接口,然后通过对适当接口类型的引用来传递对象。尽管可能仍然需要您为每个角色定义和维护界面,但这可能更易于阅读和直观。

应该选择接口以及它们公开的成员函数以适合访问角色。您不必为每个功能单独使用一个接口。如果您认为这样做的话,我会认为它是code smell,并以此作为重新评估设计的线索。同样也使用Attorney-Client / PassKey模式。

“律师-客户/密码”模式的唯一优点是不需要成员函数为virtual。但是虚拟功能的性能成本很有可能is not important to your application

缺点是Attorney-Client / PassKey模式会鼓励您根据特定用户(例如在访问Secret的特定类中)设计“接口”。这将创建coupling。最好考虑可以适当分配的通用角色。