一个具体的设计模式的问题
我写C++有一段时间。但是目前有一个问题总是感觉解决不好。我有一个函数,需要被调用几次,每次的过程都大致相同,但其中某些步骤的实现有区别,此外还和输入数据的两种属性有关系。如下:
我目前的实现如下:
class Builder {
build() {
step1();
step2();
...
stepN();
}
step1() {...};
virtual step3() {...}
};
class BuilderPhase1 {
step1() {...}
step3() {...}
};
class BuilderPhase2 {
step1() {...}
step3() {...}
};
class BuilderPhase3 {
step1() {...}
step3() {...}
};
class BuilderPhase1Attr1 {
step1_1() {...}
};
class BuilderPhase1Attr2 {
step1_1() {...}
};
class BuilderPhase2Attr1 {
step2_3() {...}
};
...
大致是这样,基本上类的继承关系是一个树状。而且每个phase分类下面都需要对attribute再分子类,看起来很罗嗦。而需要在相同的attribute但不同phase之间共享代码时,只能把他们放在最顶的基类里面。
我这个设计感觉有些别扭。虽然的确消除了大量的switch/if的条件判断问题。
我现在想了另外一个设计,但是不知道是否可行,请高手指点一下:
class Director {
BuilderPhase phase;
BuilderAttr attr;
Director(BuilderPhase p, BuilderAttr a) {
phase = p;
attr = a;
}
build() {
step1();
step2();
...
stepN();
}
step1() {
phase.step1_1();
attr.step2_2();
}
...
};
但是这样有个问题,可能BuilderPhase类中的方法需要调用BuilderAttr中的某些方法,或者反过来调用。这样我需要把Director的引用传给phase和attr对象,这样我担心会降低效率。因为多了不少间接引用,而有些函数调用是在两层以上的循环里面。
请高手指点一下我这个设计是否恰当。此外,是否有性能问题。
非常感谢!
我想这样可以避免增加很多
[解决办法]
没怎么看明白····
[解决办法]
好抽象,楼主你想干什么呢?
有空买本《设计模式》看看,反复钻研。继承别乱用。写出这种代码感觉就是师傅带的水平低。
[解决办法]
还是没有搞明白,哎
[解决办法]
看了半天也不是很明白,不过建议用类的聚集,如果继承的话这样会产生类的爆炸。
[解决办法]
"我有一个函数,需要被调用几次,每次的过程都大致相同,但其中某些步骤的实现有区别,此外还和输入数据的两种属性有关系."
断章取义一下,如果是这样的实现方法可以为:将相同的提取出来组成单独的函数,然后声明一个虚函数实现不同的地方,子类实现需函数(也就是可能这个函数要被拆成几个函数)
如果函数的执行步骤大致相同但是代码实现都不同,如类似(1)初始化,(2)计算 (3) 发布结果这样的流程类似的,都可以按照上面的方法:声明虚函数,在基类的函数里调用这些虚函数来规定执行的流程,子类实现虚函数,然后多态调用基类的函数执行函数就可以了,貌似叫Template模式
[解决办法]
但是这样有个问题,可能BuilderPhase类中的方法需要调用BuilderAttr中的某些方法,或者反过来调用。这样我需要把Director的引用传给phase和attr对象,这样我担心会降低效率。因为多了不少间接引用,而有些函数调用是在两层以上的循环里面。
在红色部分,感觉你的设计的正交性不够,可以试着做一个BuilderHelper.
[解决办法]
对phase和attr这两个概念的区分比较模糊,可以试着作出phase和attr共同基类...
[解决办法]
class BuilderPhase3 {
step1() {...}
step3() {...}
};
class BuilderPhase1Attr1 {
step1_1() {...}
};
class BuilderPhase1Attr2 {
step1_1() {...}
};
class BuilderPhase2Attr1 {
step2_3() {...}
};
这些类中的函数有共性吗?
[解决办法]
up
楼主好像自己有解决方法了
[解决办法]
学习了。。。
[解决办法]
继承并不是只能表示是一个is-a的关系.
private继承可以表示最赤裸裸的,直接的代码复用.
当然,是选用继承还是组合,要看你自己了.
[解决办法]
用builder模式没错。组合/聚合也不会成为性能瓶颈。
另外,如果两个类过分地对对方感兴趣,不如将它们合二为一,或者建立第三者,使用/组合/聚合它们。
[解决办法]
if (builder->phase == PHASE1) {
这个地方的工作交给PhaseHelper 的接口去做呀
} else if {builder->phase == PHASE2) {
这个地方的工作交给PhaseHelper 的接口去做呀
}
[解决办法]
google double dispatch模式。
[解决办法]
用模板类实现试试,对特殊要求的实现以模板特化对待~~嘿嘿,与参数属性相关则考虑用trait模板。只是个建议^_^
[解决办法]
学习,设计模式,我也要看。先看完primer