
Template Method em C#
O Template Method é um padrão de projeto comportamental que permite definir o esqueleto de um algoritmo em uma classe base e permitir que as subclasses substituam as etapas sem alterar a estrutura geral do algoritmo.
Complexidade:
Popularidade:
Exemplos de uso: O padrão Template Method é bastante comum nos frameworks C#. Os desenvolvedores costumam usá-lo para fornecer aos usuários do framework um meio simples de estender a funcionalidade padrão usando herança.
Identificação: O Template Method pode ser reconhecido por métodos comportamentais que já possuem um comportamento “padrão” definido pela classe base.
Exemplo conceitual
Este exemplo ilustra a estrutura do padrão de projeto Template Method. Ele se concentra em responder a estas perguntas:
- De quais classes ele consiste?
- Quais papéis essas classes desempenham?
- De que maneira os elementos do padrão estão relacionados?
Program.cs: Exemplo conceitual
using System; namespace RefactoringGuru.DesignPatterns.TemplateMethod.Conceptual { // The Abstract Class defines a template method that contains a skeleton of // some algorithm, composed of calls to (usually) abstract primitive // operations. // // Concrete subclasses should implement these operations, but leave the // template method itself intact. abstract class AbstractClass { // The template method defines the skeleton of an algorithm. public void TemplateMethod() { this.BaseOperation1(); this.RequiredOperations1(); this.BaseOperation2(); this.Hook1(); this.RequiredOperation2(); this.BaseOperation3(); this.Hook2(); } // These operations already have implementations. protected void BaseOperation1() { Console.WriteLine("AbstractClass says: I am doing the bulk of the work"); } protected void BaseOperation2() { Console.WriteLine("AbstractClass says: But I let subclasses override some operations"); } protected void BaseOperation3() { Console.WriteLine("AbstractClass says: But I am doing the bulk of the work anyway"); } // These operations have to be implemented in subclasses. protected abstract void RequiredOperations1(); protected abstract void RequiredOperation2(); // These are "hooks." Subclasses may override them, but it's not // mandatory since the hooks already have default (but empty) // implementation. Hooks provide additional extension points in some // crucial places of the algorithm. protected virtual void Hook1() { } protected virtual void Hook2() { } } // Concrete classes have to implement all abstract operations of the base // class. They can also override some operations with a default // implementation. class ConcreteClass1 : AbstractClass { protected override void RequiredOperations1() { Console.WriteLine("ConcreteClass1 says: Implemented Operation1"); } protected override void RequiredOperation2() { Console.WriteLine("ConcreteClass1 says: Implemented Operation2"); } } // Usually, concrete classes override only a fraction of base class' // operations. class ConcreteClass2 : AbstractClass { protected override void RequiredOperations1() { Console.WriteLine("ConcreteClass2 says: Implemented Operation1"); } protected override void RequiredOperation2() { Console.WriteLine("ConcreteClass2 says: Implemented Operation2"); } protected override void Hook1() { Console.WriteLine("ConcreteClass2 says: Overridden Hook1"); } } class Client { // The client code calls the template method to execute the algorithm. // Client code does not have to know the concrete class of an object it // works with, as long as it works with objects through the interface of // their base class. public static void ClientCode(AbstractClass abstractClass) { // ... abstractClass.TemplateMethod(); // ... } } class Program { static void Main(string[] args) { Console.WriteLine("Same client code can work with different subclasses:"); Client.ClientCode(new ConcreteClass1()); Console.Write("\n"); Console.WriteLine("Same client code can work with different subclasses:"); Client.ClientCode(new ConcreteClass2()); } } }
Output.txt: Resultados da execução
Same client code can work with different subclasses: AbstractClass says: I am doing the bulk of the work ConcreteClass1 says: Implemented Operation1 AbstractClass says: But I let subclasses override some operations ConcreteClass1 says: Implemented Operation2 AbstractClass says: But I am doing the bulk of the work anyway Same client code can work with different subclasses: AbstractClass says: I am doing the bulk of the work ConcreteClass2 says: Implemented Operation1 AbstractClass says: But I let subclasses override some operations ConcreteClass2 says: Overridden Hook1 ConcreteClass2 says: Implemented Operation2 AbstractClass says: But I am doing the bulk of the work anyway