所以我决定使用工厂设计模式和依赖注入。
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) {}
};
现在,问题是classB的构造函数的参数太多了。这是一个单继承层示例,但是当继承层开始变得更深,并且当每个层类需要构造更多对象时,顶层中的构造函数结束需要太多参数才能生成!
我知道我可以使用setter而不是构造函数,但还有其他方法吗?
答案 0 :(得分:6)
不推荐使用Setter进行此类操作,因为它们会导致部分构造的对象非常容易出错。构造需要许多参数的对象的常见模式是使用构建器。 ClassBBuilder的职责是创建ClassB对象。您将ClassB构造函数设为私有,并且仅允许构建器使用朋友关系调用它。现在,构建器可以看起来像这样
ClassBBuilder {
public:
ClassBBuilder& setPhoneNumber(const string&);
ClassBBuilder& setName(consg string&);
ClassBBuilder& setSurname(const string&);
ClassB* build();
}
你使用建筑师喜欢这个:
ClassB* b = ClassBBuilder().setName('alice').setSurname('Smith').build();
build()方法检查是否已设置所有必需参数,并返回正确构造的对象或NULL。创建部分构造的对象是不可能的。你仍然有一个带有许多参数的构造函数,但它是私有的,只在一个地方调用。客户不会看到它。 Builder方法也很好地记录了每个参数的含义(当你看到ClassB('foo','bar')时,你需要检查构造函数以确定哪个参数是名称,哪个是姓氏。)
答案 1 :(得分:1)
这是C ++问题之一(如果这可以称为问题)。除了试图保持ctor的参数数量最小化之外,它没有解决方案。
其中一种方法是使用道具结构,如:
struct PropsA
{
Object *a, *b, *c;
};
class ClassA
{
ClassA(PropsA &props, ... other params);
};
这似乎很明显,但我确实使用了好几次。在许多情况下,事实证明某些参数组是相关的。在这种情况下,为它们定义一个结构是有意义的。
这种最糟糕的噩梦是薄包装类。可以直接访问基础的方法和数据字段,同时必须复制所有ctors。当有10多个ctors时,创建一个包装器开始成为一个问题。
答案 2 :(得分:1)
我认为你所描述的不是C ++中的问题 - 实际上,C ++很好地反映了你的设计所表达的依赖关系:
ClassA
类型的对象,您需要有三个Object
个实例(a
,b
和c
)。ClassB
类型的对象,您还需要有三个Object
个实例(d
,e
和f
)。ClassB
类型的每个对象都可以被视为ClassA
类型的对象。这意味着要构造类型为ClassB
的对象,您需要提供实现Object
接口所需的三个ClassA
对象,然后再实现另外三个ClassB
对象ClassB
界面。
我相信这里的实际问题是你的设计。您可以考虑采用不同的方法来解决这个问题:
ClassA
继承ClassA*
。可能是也可能不是一个选项,具体取决于您是否需要对任何类型的对象进行同源访问(例如,因为您有ClassB
的集合,并且此集合还可以包含指向a
的指针。)b
和d
或e
和{{1}})的前两个对象代表某种对。可能是对象标识符等?在这种情况下,为此引入专用摘要(读取:类型)可能是有益的。