According to Why define a Java object using interface (e.g. Map) rather than implementation (HashMap), I know I should declare the most abstract type as possible. However, I found that a situation that declare the exact type instead of the most abstract type may help me to write more maintainable code, for example, I'm using a game engine, cocos2d-x, which has Sprite
and Label
, both of them are the child class of Node
. First start with code that written with most concrete type, which is a UI scene that shows an image and a welcome text:
Non most abstract type version:
Sprite* sprite = new Sprite("welcome.png");
this->addChild(sprite);
// ...
Label* label = new Label("Welcome, "+playerInfo.username,"",32);
this->addChild(label);
LabelAnimationHelper::showFirstAppearAnimation(label);
...
class LabelAnimationHelper{
public:
static void showFirstAppearAnimation(Label* label){
label->setOpacity(0);
label->setScale(2);
label->runAction(FadeIn::create(1));
label->runAction(ScaleTo::create(1,1));
}
static void showMarqueeAnimation(Label* label){
// ...
}
}
which LabelAnimationHelper
is a class that suppose to set different animations for Label
only, but not for Sprite or other UI types. However, according to "declare most abstract type" rule, I should modify the code above to:
Most abstract type version:
Node* sprite = new Sprite("welcome.png");
this->addChild(sprite);
// ...
Node* label = new Label("Welcome, "+playerInfo.username,"",32);
this->addChild(label);
LabelAnimationHelper::showFirstAppearAnimation(label);
...
class LabelAnimationHelper{
public:
static void showFirstAppearAnimation(Node* label) {
label->setOpacity(0);
label->setScale(2);
label->runAction(FadeIn::create(1));
label->runAction(ScaleTo::create(1,1));
}
static void showMarqueeAnimation(Node* label) {
// ...
}
}
I found the "Most abstract type version" may have a problem that the "Non most abstract type version" hasn't: I may call
LabelAnimationHelper::showFirstAppearAnimation(sprite);
wrongly, which LabelAnimationHelper
is supposed to work with Label
only. So I would rather keep the exact type to avoid this situation. Also I found declaring the most concrete type version is more readable: In game development, I usually need to find specific UI (eg: welcome Label) in a method to change. Showing the exact type in left hand side helps me to filter other irrelevant UI (eg: Sprite) quickly and hence faster to find the part of code that I need to change.
So my question is, is the reason above rationale to declare the exact type instead of most abstract type?
Object
showFirstAppearAnimation
?Helper
is generally a code smell.