在基础和派生类上应用相同的模板方法接口

时间:2013-12-12 18:59:41

标签: c# design-patterns

我有点难以用文字清楚地解释这个问题所以我会立即从代码开始:

public interface ITemplate
{
    bool DoSomething(string a);
}

public class Worker
{
    public void DoSomeWork(ITemplate subcontractor)
    {
        try {
            //Do some work...
            if(subcontractor.DoSomething("hello"))
            {
                //Do some more work
            }
        }
        catch(InvalidOperationException) {/*...*/}
        //catch(Exception2) {/*...*/}
        //catch(Exception3) {/*...*/}
        //catch(Exception4) {/*...*/}
    }
}

public class BaseClass : ITemplate
{
    public void myFunction1()
    {
        Worker worker = new Worker();
        worker.DoSomeWork(this);   
    }

    public bool DoSomething(string a)
    {
        //Some code here
        return true;
    }
}

public class DerivedClass : BaseClass, ITemplate
{
    public void myFunction2()
    {
        Worker worker = new Worker();
        worker.DoSomeWork(this);   
    }

    public bool DoSomething(string a)
    {
        //Some other code here
        return true;
    }
}

使用此结构,如果我调用myDerivedClass.myFunction1()worker.DoSomeWork()函数将执行DerivedClass.DoSomething(),但我希望在该上下文中执行BaseClass.DoSomething(),我该怎么办? ?

使用模板方法设计模式可能无法实现我在该环境中尝试做的事情。

最初的问题是我需要一个方法来执行代码,但是这段代码的某些部分是代码是根据什么对象调用方法而变化的。 是否有另一种方法可以在没有if(typeOf(subcontractor) == ...)的情况下做到这一点,这不是一个很好的做法,我希望代码的变量部分在调用者对象中存储和执行。

我可以在参数中传递委托或其他内容而不是发送整个调用者对象吗?我不是很习惯和委托/等人一起工作,但我认为这可能对我的问题很有帮助,我是对的吗?

感谢 乔纳森

2 个答案:

答案 0 :(得分:1)

这是正确的行为,是多态如何工作的。如果你有一个派生类DerivedClass的实例并且你覆盖了一个方法,比如DoSomething,那么对基类代码中方法DoSomething的所有调用都将通过如果处理派生类型的实例,则在派生类中重写方法。

如果希望执行基类中的代码,则需要不覆盖该方法,或者从派生类调用基类方法:

public class BaseClass
{
    public virtual void MyMethod() 
    { 
        // Do some stuff...
    }
}

public class DerivedClass : BaseClass
{
    public override void MyMethod()
    {
        // Do something new...

        // Do the stuff in BaseClass.MyMethod()
        base.MyMethod(); 
    }
}

答案 1 :(得分:0)

DerivedClassITemplate,因为它继承自BaseClass ITemplate。您无需DerivedClass直接实施ITemplate

另外,如上所述,您发布的代码将无法编译。

public interface ITemplate
{
    bool DoSomething(string a);
}

public class Worker
{
    public void DoSomeWork(ITemplate subcontractor)
    {
        //Do some work...
        if(subcontractor.DoSomething("hello"))
        {
            //Do some more work
        }
    }
}

public BaseClass : ITemplate
{
    public void myFunction1()
    {
        Worker worker = new Worker();
        worker.DoSomeWork(this);   
    }

    public bool DoSomething(string a)
    {
        //Some code here
    }
}

public DerivedClass : BaseClass
{
    public void myFunction2()
    {
        Worker worker = new Worker();
        worker.DoSomeWork(this);   
    }
}