Non c'è nulla che ti impedisca di chiamare due cose dal metodo template. Nel tuo caso potresti farlo in questo modo:
public abstract class ContextObject {
// The template method
public void PerformDraw() {
Draw();
Calculate();
}
public abstract void Draw();
public abstract void Calculate();
}
// The implementation is rather obvious:
public class ConcreteObject : ContextObject {
public void Draw() { ... }
public void Calculate() { ... }
}
// For all the concrete objects you only need to call
// the template method, regardless of the implementation
for (ContextObject context : contextObjectList) {
context.PerformDraw();
}
L'unico svantaggio di questa classe di oggetti modello è che tutti devono implementare i metodi Draw
e Calculate
. Quindi, se tutte le sottoclassi hanno bisogno di mescolare tra disegnare e calcolare in diverse combinazioni, potresti usare un modello di strategia in questo modo:
// Strategy #1
public interface IDrawable {
void Draw();
}
// Strategy #2
public interface ICalculatable {
void Calculate();
}
// the previous class needs to use the interfaces above:
public abstract class ContextObject {
private IDrawable drawable;
private ICalculatable calculatable;
public ContextObject(IDrawable drawable, ICalculatable calculatable) {
this.calculatable = calculatable;
this.drawable = drawable;
}
public void PerformDraw() {
drawable.Draw();
calculatable.Calculate();
}
}
// The implementations
public class DrawUno : IDrawable { ... }
public class CalcUno : ICalculatable { ... }
public class ConcreteObject : ContextObject {
// call the base class's constructor with the implementations
public ConcreteObject() :
base(
new DrawUno(),
// can be mixed with any other of type IDrawable
new CalcUno()
// can be mixed with any other type of ICalculatable
)
{
// no-op, the base constructor does the stuff you need...
}
}
Puoi anche mescolare e abbinare, tutto dipende da cosa devi effettivamente fare.