我构建了一个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
并设置其值?
您认为这是一种不好的做法吗?
由于
答案 0 :(得分:12)
是的,这是值得避免的。这样的规则应该在适当的位置,以便在可能和实际的情况下由编译器(而不是约定)强制执行。
在你的情况下,你应该这样做:
public abstract class BaseTask
{
public void Run()
{
Result = RunInternal();
}
public ResultContainer Result { get; set; }
protected abstract ResultContainer RunInternal();
}
这将完成您想要的语义(从外部调用Run
函数将始终导致Result
属性设置),并强制从BaseTask
继承的开发人员提供正在使用的价值。唯一的区别是他们将覆盖(或者更确切地说)实现RunInternal
函数而不是Run
。
答案 1 :(得分:1)
我不确定这是否适合某些预先想象的设计模式,但是你能否为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");
}
}