Fir*_*cer 6 language-agnostic oop design-patterns
我什么时候应该继续创建派生类,何时应该在我的代码中添加条件?例如导弹
class Object;
class Projectile : public Object;
class Missile : public Projectile;
class MissileGuided : public Missile;
Run Code Online (Sandbox Code Playgroud)
或者我应该在导弹的代码中实现最后一个?
void Missile::Update()
{
if(homing && ObjectExists(Target))
TurnTowards(Target.Pos)
Pos += Motion;
}
Run Code Online (Sandbox Code Playgroud)
我认为,对于所有更精细的细节,第二个更好,因为你开始获得事物的组合(例如,一些导弹可能不会在雷达上显示,一些可能是可破坏的,一些可能会获得新目标,如果原件被破坏或超出范围等)
然而,对于在某些情况下共用导弹属性的常规射弹也是如此(例如可能是可破坏的,大型射弹可能在雷达上显示等)
然后我可以说弹丸与船只共享属性(移动,碰撞它们会造成损坏,可能在雷达上显示,可能是可破坏的......)
然后一切都像3个类一样回归:
class Entity;
class Object : public Entity;
class Effect : public Entity;
Run Code Online (Sandbox Code Playgroud)
在创建派生类和使用标志或其他东西实现方法中的功能之间划清界线的好处在哪里?
您可能需要考虑使用策略模式而不是两种方法,并将行为封装在外部类中.然后可以将行为注入到Missile类中,使其成为GuidedMissile或SpaceRocket或您需要的任何其他内容.
这样可以避免Missile类中逻辑的过度分支,并且您不需要进入与深度继承相关的逻辑复杂性.
维基百科有几种语言的模式使用样本集合:http: //en.wikipedia.org/wiki/Strategy_pattern
interface INavigable {
Course calcCourse (Position current, Destination dest);
}
Class GeoStationaryRocketCPU implements INavigable {
Course calcCourse (Position current, Destination dest) {
return dest.getShortestRouteTo (current).getCourse();
};
}
Class GuidedMissileCPU implements INavigable {
Course calcCourse (Position current, Destination dest) {
return dest.getLowestAltRouteTo (current).getCourse();
};
}
class Missile {
INavigable CPU;
void setCPU (INavigable CPU) {
this.CPU = CPU;
}
void fly ()
{
...
course = this.CPU.calcCourse (pos, dest);
...
}
}
Run Code Online (Sandbox Code Playgroud)
正如另一位同事所建议的那样,您也可以考虑使用Decorator模式.只是为了突出显示在您的上下文中可能很重要的几个设计问题,如果您采取这种方式:
尽管如此,当提供现成的导弹装饰的不可变实施时,可能是"解锁"它并实施战略模式的关键,为导弹提供各种所需的行为.