2013-07-17 110 views
3

如何实现模板方法模式的变体,使具体类不会从基类继承,但模式的整体特征得到维护。它无法继承的原因是它被迫从另一个类继承,并且多重继承不可用。无继承的模板方法模式

例如,假设下面的Tempate Method模式:

public abstract class BaseClass { 
    public void Alpha() { 
     Beta(); 
    } 

    public abstract void Beta(); 

    public void Gamma() { 
     Delta(); 
    } 

    public abstract void Delta(); 

} 

public ConcreteClass : BaseClass { 
    public override void Beta() { 
     Gamma(); 
    } 

    public override void Delta() { 
     Console.WriteLine("Delta"); 
    } 
} 

... 
var object = new ConcreteClass(); 
object.Alpha(); // will outout "Delta" 

我怎么能实现无具体类继承BaseClass的同样的结果?

+0

如果这是C#,那么你不能做'BaseClass的对象=新的具体类()'没有具体类继承的BaseClass。你现在究竟有什么和你想要达到的目标? –

+0

更改为'var'。 –

+0

仍然不清楚你有什么课 –

回答

2

您的基类可能依赖于通过构造函数注入的接口(或其他类型)。您的模板方法(一个或多个),然后可以使用这个接口/类型的方法来实现模式的期望的结果:

public class BaseClass 
{ 
    IDependent _dependent; 

    public BaseClass(IDependent dependent) 
    { 
     _dependent = dependent; 
    } 

    public void Alpha() { 
     _depdendent.Beta(); 
    } 

    public void Gamma() { 
     _depdendent.Delta(); 
    } 

} 

有效使用组成,而不是继承。

+0

这解决了一半的问题。另一半是我需要从IDependent对象调用BaseClass方法。可以使用其他界面,但有更好的解决方案吗? –

+1

你可以给依赖者一个对基类的引用。虽然开始有点臭。 OOD不安的水平正在上升,这表明这不是正确的解决方案... –

+0

我复制了MVP模式(减去'Model'),并使'View'类具有触发的事件。 –

0

如果我理解正确的(你的代码是不是对我来说很清楚),你有一个ConcreteClass目前从SomeOtherClass继承,到模板方法添加到ConcreteClass,你可以扩展你的ConcreteClassabstract类:

public abstract class TplConcreteClass : ConcreteClass{ 

    public void Alpha() { 
     Beta(); 
    } 

    public abstract void Beta(); 

    public void Gamma() { 
     Delta(); 
    } 

    public abstract void Delta(); 

} 

比你创建新的具体类来实现的模板方法:

public NewConcreteClass : TplConcreteClass { 
    public override void Beta() { 
     Gamma(); 
    } 

    public override void Delta() { 
     Console.WriteLine("Delta"); 
    } 
} 

这样你的客户端代码应该工作...

+0

这没有解决这个问题。该问题询问如何实现Template Method模式的变体,从而ConcreteClass不会从BaseClass继承。 –

+0

@HermanSchoenfeld在你原来的问题中说你对你的限制是多重继承......试着更清楚你是否问了一些问题 – davioooh

+0

这是不正确的,我没有改变关于多重继承的措辞。 –

0

可以通过提供在方法调用一个参照基类实现这一点:

public ConcreteClass { 
    public void Beta(BaseClass baseClass) { 
     baseClass.Gamma(); 
    } 

    public void Delta() { 
     Console.WriteLine("Delta"); 
     } 
}