diff --git a/Program.cs b/Program.cs index 70e206d..b09cc41 100644 --- a/Program.cs +++ b/Program.cs @@ -22,6 +22,7 @@ using design_patterns.behavioral.memento; using design_patterns.behavioral.observer; using design_patterns.behavioral.state; using design_patterns.behavioral.strategy; +using design_patterns.behavioral.template; namespace design_patterns { @@ -57,7 +58,8 @@ namespace design_patterns // await MementoSample.Run(); // await ObserverSample.Run(); // await StateSample.Run(); - await StrategySample.Run(); + // await StrategySample.Run(); + await TemplateSample.Run(); } catch (System.Exception ex) { diff --git a/behavioral/template/TemplateSample.cs b/behavioral/template/TemplateSample.cs new file mode 100644 index 0000000..6fb76b6 --- /dev/null +++ b/behavioral/template/TemplateSample.cs @@ -0,0 +1,98 @@ +using System; +using System.Threading.Tasks; + +namespace design_patterns.behavioral.template +{ + /// + /// Template Method is a behavioral design pattern that defines + /// the skeleton of an algorithm in the superclass but lets + /// subclasses override specific steps of the algorithm + /// without changing its structure. + /// + /// Use it when: + /// - you want to let clients extend only particular steps + /// of an algorithm, but not the whole algorithm or its structure. + /// - you have several classes that contain almost identical algorithms + /// with some minor differences. As a result, you might need to modify + /// all classes when the algorithm changes. + /// + public class TemplateSample + { + public static async Task Run() + { + Console.WriteLine("Behavioral - Template"); + System.Console.WriteLine("Execute Service1"); + var service1 = new Service1(); + service1.RunService(); + System.Console.WriteLine("Execute Service2"); + var service2 = new Service2(); + service2.RunService(); + } + + // template + public abstract class AbstractService { + public void RunService(){ + this.BaseOperation1(); + this.Operation1(); + this.Operation2(); + this.Operation3(); + this.Operation4(); + this.BaseOperation2(); + } + + protected void BaseOperation1() { + // some base implementation + System.Console.WriteLine("Base implementation for BaseOperation1"); + } + protected void BaseOperation2() { + // some base implementation + System.Console.WriteLine("Base implementation for BaseOperation2"); + } + + // abstract methods that needs to be implemented by subclasses + public abstract void Operation1(); + public abstract void Operation2(); + + // virtual methods that can be overriden by subclasses + public virtual void Operation3() { + System.Console.WriteLine("Base implementation for Operation3"); + } + public virtual void Operation4() { + System.Console.WriteLine("Base implementation for Operation4"); + } + } + + public class Service1 : AbstractService + { + public override void Operation1() + { + System.Console.WriteLine("Service1 override for Operation1"); + } + + public override void Operation2() + { + System.Console.WriteLine("Service1 override for Operation2"); + } + + public override void Operation4() + { + System.Console.WriteLine("Service1 override for Operation4"); + // can call eventually the base implementation + base.Operation4(); + } + } + + public class Service2 : AbstractService + { + public override void Operation1() + { + System.Console.WriteLine("Service2 override for Operation1"); + } + + public override void Operation2() + { + System.Console.WriteLine("Service2 override for Operation2"); + } + } + } +} \ No newline at end of file