Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force a programmer to invoke a method in its Base

I built an Async task service executor that execute tasks by external request.

Each task contains the function void run(), so any programmer who want's to add a task to the system needs to inherit From BaseTask.

    interface ITask{
       void run();
    }
    abstract BaseTask : ITask{
       //force "run()" to set Result
       public ResultContainer Result {set; get;}
       void run();
    }

    class SomeTask : BaseTask {
       void run(){
           ////run the operation here, in the end, set the result.
           //force the programmer to set the Result;
           this.Result = new ResultContainer("task ok");
       }
    }

For internal reasons, the run() must be void.

Is there any way that I can force a programmer who wants to add a task to invoke Result in BaseTask and set its value? Do you think it is a bad practice?

Thanks

like image 634
fatnjazzy Avatar asked Dec 28 '25 06:12

fatnjazzy


2 Answers

Yes, this is something to be avoided. Rules like this should be in place such that they're enforced by the compiler (rather than convention) when possible and practical.

In your case, you should do something like this:

public abstract class BaseTask
{
    public void Run()
    {
        Result = RunInternal();
    }

    public ResultContainer Result { get; set; }

    protected abstract ResultContainer RunInternal();
}

This will accomplish what you want semantically (that invoking the Run function externally will always cause the Result property to be set), and it forces the developer who inherits from BaseTask to supply the value that's being used. The only difference is that they will override (or, rather, implement) the RunInternal function instead of Run.

like image 103
Adam Robinson Avatar answered Dec 30 '25 18:12

Adam Robinson


I'm not sure if this fits some pre-imagined design pattern, but could you add another method to BaseTask that does have a return value,a nd have the developers implement that? For example (sorry if the code isn't 100% correct, not doing this in VS):

interface ITask{
   void run();
}

abstract BaseTask : ITask{
   //force "run()" to set Result
   public ResultContainer Result{set;get;}

   void run() {
       Result = runInternal();
   }

   protected abstract ResultContainer runInternal();

}

class SomeTask : BaseTask {
   protected override ResultContainer runInternal(){
       return new ResultContainer("task ok");
   }
}
like image 30
CodingWithSpike Avatar answered Dec 30 '25 20:12

CodingWithSpike



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!