Заставить программиста вызывать метод в его базе - PullRequest
3 голосов
/ 03 октября 2011

Я создал Async для выполнения задач, который выполняет задачи по внешнему запросу.

Каждая задача содержит функцию void run(),, поэтому любой программист, желающий добавить задачу в систему, должен наследовать от 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");
       }
    }

По внутренним причинам run() должен быть недействительным.

Можно ли заставить программиста, который хочет добавить задачу, вызвать Result в BaseTask и установить ее значение? Как вы думаете, это плохая практика?

Спасибо

Ответы [ 2 ]

12 голосов
/ 03 октября 2011

Да, этого следует избегать.Подобные правила должны быть такими, чтобы они применялись компилятором (а не соглашением), когда это возможно и практично.

В вашем случае вы должны сделать что-то вроде этого:

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

    public ResultContainer Result { get; set; }

    protected abstract ResultContainer RunInternal();
}

Это семантически выполнит то, что вы хотите (что внешний вызов функции Run всегда будет приводить к установке свойства Result), и заставит разработчика, который наследует от BaseTask, предоставить используемое значение.Единственное отличие состоит в том, что они будут переопределять (или, скорее, реализовывать) функцию RunInternal вместо Run.

1 голос
/ 03 октября 2011

Я не уверен, подходит ли это какой-то заранее заданному шаблону проектирования, но не могли бы вы добавить еще один метод к BaseTask, который имеет возвращаемое значение, и разработчики его реализовали?Например (извините, если код не на 100% правильный, не делайте этого в 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");
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...