依赖注入/继承设计模式的构造函数参数太多

nah*_*hpr 6 c++ inheritance design-patterns dependency-injection

所以我决定使用工厂设计模式和依赖注入.

class ClassA
{        
    Object *a, *b, *c;
    public:
    ClassA(Object *a, Object *b, Object *c) :
    a(a), b(b), c(c) {}
};

class ClassB : public ClassA
{        
    Object *d, *e, *f;
    public:
    ClassB(Object *a, Object *b, Object *c, Object *d, Object *e, Object *f) :
    ClassA(a, b, c), d(d), e(e), f(f) {}
};
Run Code Online (Sandbox Code Playgroud)

现在,问题是classB有太多的构造函数参数.这是一个单继承层示例,但是当继承层开始变深时,并且当每个层类需要构造更多对象时,顶层中的构造函数结束时需要太多参数才能生成!

我知道我可以使用setter而不是构造函数,但还有其他方法吗?

Jan*_*bel 6

建议不要使用Setter,因为它们会导致部分构造的对象非常容易出错.构造需要许多参数的对象的常见模式是使用构建器.ClassBBuilder的职责是创建ClassB对象.您将ClassB构造函数设为私有,并且仅允许构建器使用朋友关系调用它.现在,构建器可以看起来像这样

ClassBBuilder {
  public:
    ClassBBuilder& setPhoneNumber(const string&);
    ClassBBuilder& setName(consg string&);
    ClassBBuilder& setSurname(const string&);
    ClassB* build(); 
} 
Run Code Online (Sandbox Code Playgroud)

你使用建设者喜欢这个:

ClassB* b = ClassBBuilder().setName('alice').setSurname('Smith').build();
Run Code Online (Sandbox Code Playgroud)

build()方法检查是否已设置所有必需参数,并返回正确构造的对象或NULL.创建部分构造的对象是不可能的.你仍然有一个带有许多参数的构造函数,但它是私有的,只在一个地方调用.客户不会看到它.Builder方法也很好地记录了每个参数的含义(当你看到ClassB('foo','bar')时,你需要检查构造函数以确定哪个参数是名称,哪个是姓氏).


Kir*_*lev 1

这是 C++ 问题之一(如果这可以称为问题的话)。除了尝试将构造函数的参数数量保持最少之外,它没有其他解决方案。

其中一种方法是使用 props 结构,例如:

struct PropsA
{
    Object *a, *b, *c;
};

class ClassA
{
    ClassA(PropsA &props, ... other params);
};
Run Code Online (Sandbox Code Playgroud)

这似乎是显而易见的,但我确实使用过几次。在许多情况下,事实证明某些参数组是相关的。在这种情况下,为它们定义一个结构是有意义的。

我最糟糕的噩梦就是薄包装类。基础的方法和数据字段可以直接访问,而所有的构造函数都必须复制。当有 10 多个 ctor 时,创建包装器就开始成为问题。