Search code examples
c#ooppolymorphismsolid-principles

Using polymorphism instead of a conditional when the responsibility doesn't belong in the class


Something I'm running into working on a very simple application that's part of a school project.

It's a very basic console based employee management system where you can add 4 types of employees (full time, part time, contract, seasonal, all with a couple different attributes.)

The problem I'm having is when displaying a menu for modifying a specific employee type.

Doing a switch statement on the employee type is obviously quite bad design, but adding "DisplayModificationMenu" to each employee class so that it can display its own menu also seems terrible, because displaying a menu doesn't seem like an appropriate responsibility for an employee object itself.

What's the best approach to solving this design issue? I have considered creating a Menu class and subtype every menu so each one can display itself, but even then I feel like a switch on the type would still occur somewhere to decide which menu to instantiate.

The workflow to modify an employee is select an employee by their ID, and then the correct menu for that employee type should display. So even with the subtyped menus, it seems you'd have to check the employee type before you knew which menu to instantiate.

Thanks in advance for any advice.


Solution

  • I think doing switch on type of an object is not a problem, as long as it is encapsulated, documented and understood properly.

    In your case, you could make DisplayMenuFactory, that would accept abstract employee object and return abstract Menu class. And inside, it would switch based on employee type and return concrete Menu class for each type. And, if you end up having different factories, that have same switching mechanism, you can merge them together and this switching will happen always in single class. So responsibility for creating different UIs for different employees will be in this single class.

    The second option is to have Employee class that has GetMenu method, that would return concrete Menu type for each employee type. But this is mixing model and UI, which is not something I think is acceptable in this case.