Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I have the opportunity to rewrite a core piece of a project (C#) that is inherit

ID: 643889 • Letter: I

Question

I have the opportunity to rewrite a core piece of a project (C#) that is inheritance-heavy and feels increasingly restrictive in how it is designed. The scenario is pretty simple, imagine an application that is built to handle various small tasks. Every task is unique in it's functionality so it implements an ITask interface with a few simple methods that get implemented by each task class (e.g. Init(), Start(), Stop(), etc).

In addition to the ITask interface there is also an abstract BaseTask class that all tasks inherit from. This BaseTask class is sort of an 'everything but the kitchen sink' approach that contains useful pieces of functionality that the tasks often require. For example, all tasks record their status and progress the exact same way so this logic is defined in the BaseTask and available to all children through a protected method. Or to give another example, some tasks have to send email notifications out when certain conditions are met, so again, the BaseTask provides access to the core smtp functionality of the app for this purpose. There are many examples of these kind of 'helper' methods/properties

The problem of course is that this base class has already grown unwieldy and cluttered with properties and methods that are not universal to all tasks and it's starting to introduce more problems than it is solving. For example, anytime a change is required to the base class you find yourself in a position where you might wind up breaking some (or all) of the tasks. It also just seems like its breaking encapsulation and the single responsibility principal. It's also quite clear how this happened in the first place (and a common occurrence too). Initially this was a very small, specialized application but it blew up in terms of scope and size very quickly and what was initially probably not a bad decision architecturally has proven inflexible and awkward.

Where would you start with something like this? How would you approach the problem and what principals or design patters would you choose? Thank you very much

Explanation / Answer

Step 1: Make each of those methods in BaseTask static and pass any required private members as arguments. Now they can live, and breathe comfortably, outside of the class.

Step 2: Implement an IOC container. Resolve your tasks from there.

Step 3: Take all of those protected methods and move them to a service, make them public. Make them non-static. Don't use them yet.

Step 4: Find a related group of methods, delete them and create an interface that exposes all of those methods. Implement that interface on your service (should be easy, as you're deleting methods that exist here) and constructor-inject them into only the tasks that are no longer compiling.

Step 5: Repeat step 4 until all the methods have gone from BaseTask.

Step 6: Break the service up into smaller services that implement only one interface; let your IOC registration know.

Step 7: Refactor til you drop.