Your lecturer is teaching you best practices by teaching you software design patterns, in this case The Strategy Pattern known in simpler languages like C as function pointers. You can follow your lecturer's guidelines AND be elegant / efficient at the same time:
enum EffectType
{
EXPLODE,
GAIN_HEALTH,
LOSE_SCORE
}
public interface Effect //strategy pattern: class encapsulates function pointer
{
EffectType type; //optional - see hashtable below
public void execute(object args = null);
}
public class ExplodeEffect implements Effect
{
public override execute(object args = null)
{
Body body = (Body)args;
body.Fragment(); //or whatever
}
}
//...etc. for all types
public class EffectManager //or whatever you call yours
{
Hashtable<int, Effect> effectsByType =
new Hashtable<int, Effect>();
void Initialise() //could also do in constructor?
{
effectsByType.put(EXPLODE, ExplodeEffect);
//...etc. for all types
}
void RunEffects()
{
//do for each effect here or whatever
EffectType type = ...; //get the effect enum value / ordinal somewhere
Effect effect = effectsByType.get(type.ordinal()); //no if / switch block - efficient!
effect.execute(); //you can also pass args in here if req'd
}
}
You are not wrong to question bringing in additional classes each just to handle a couple of lines of code for each implementation of Effect. This is one pet hate of mine in languages like Java, where everything is broken down into classes, and functions aren't first-class citizens. In C or JS, I'd just have another function in the same or another module / namespace, instead of having to implement a whole new class like you will have to, just to wrap execute's implementation.
As for the model/controller separation, I personally have spent a LOT of time on MVC for games and separating model from controller for the same concept (in your case, Effect) is, in my humble opinion, overkill and makes matters nigh unmanageable, especially as a codebase grows. (Then again, I'm the kind of guy that couldn't care less about public, private etc. either.) MC+V archtecture is much simpler than M+V+C... but if you do this, you must be very careful about which functions you allow your View to run on the ModelController.
I would say that in your case, efficiency should not be the primary concern. Writing code in a good architectural form comes first at your level. So listen and learn from your teacher.