Skip to content

Commit 9a220af

Browse files
committed
Add Template Method pattern with demo and tests
Implemented the Template Method design pattern, including: - Abstract `Report` class and concrete implementations (`SalesReport` and `InventoryReport`) in `Report.cs`. - Console demo showcasing the pattern in `Program.cs`. - Updated `README.md` with documentation, usage examples, and test references. - Added unit tests in `TemplateMethodTests.cs` to verify correct behavior of `SalesReport` and `InventoryReport`.
1 parent 2ba53ec commit 9a220af

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

DesignPatterns/Program.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using DesignPatterns.Observer;
1818
using DesignPatterns.State;
1919
using DesignPatterns.Strategy;
20+
using DesignPatterns.TemplateMethod;
2021

2122
Console.WriteLine("Factory pattern demo:");
2223

@@ -222,6 +223,14 @@
222223
sorted = sorter.Sort(data);
223224
Console.WriteLine("Sorted: " + string.Join(", ", sorted));
224225

226+
// Template Method demo
227+
Console.WriteLine();
228+
Console.WriteLine("Template Method pattern demo:");
229+
var salesReport = new SalesReport();
230+
Console.WriteLine(salesReport.GenerateReport());
231+
var inventoryReport = new InventoryReport();
232+
Console.WriteLine(inventoryReport.GenerateReport());
233+
225234
// Memento demo
226235
Console.WriteLine();
227236
Console.WriteLine("Memento pattern demo:");
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
namespace DesignPatterns.TemplateMethod;
2+
3+
// Template Method pattern: defines skeleton of an algorithm in base class and lets subclasses override specific steps.
4+
public abstract class Report
5+
{
6+
// Template method
7+
public string GenerateReport()
8+
{
9+
var data = CollectData();
10+
var analysis = AnalyzeData(data);
11+
var formatted = FormatReport(data, analysis);
12+
return formatted;
13+
}
14+
15+
protected abstract string CollectData();
16+
protected abstract string AnalyzeData(string data);
17+
protected abstract string FormatReport(string data, string analysis);
18+
}
19+
20+
public class SalesReport : Report
21+
{
22+
protected override string CollectData()
23+
{
24+
// simulate data collection
25+
return "Sales:100,200,150";
26+
}
27+
28+
protected override string AnalyzeData(string data)
29+
{
30+
// simple analysis: compute total
31+
var parts = data.Split(':')[1].Split(',');
32+
int total = 0;
33+
foreach (var p in parts) total += int.Parse(p);
34+
return $"Total={total}";
35+
}
36+
37+
protected override string FormatReport(string data, string analysis)
38+
{
39+
return $"SalesReport\nData: {data}\nAnalysis: {analysis}";
40+
}
41+
}
42+
43+
public class InventoryReport : Report
44+
{
45+
protected override string CollectData()
46+
{
47+
return "Items:A:10,B:5,C:20";
48+
}
49+
50+
protected override string AnalyzeData(string data)
51+
{
52+
// count total items
53+
var parts = data.Split(':', ',');
54+
int total = 0;
55+
for (int i = 2; i < parts.Length; i += 2)
56+
{
57+
total += int.Parse(parts[i]);
58+
}
59+
return $"TotalItems={total}";
60+
}
61+
62+
protected override string FormatReport(string data, string analysis)
63+
{
64+
return $"InventoryReport\nData: {data}\nAnalysis: {analysis}";
65+
}
66+
}

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Design Patterns Examples
33
This solution demonstrates simple design pattern examples in C# targeting .NET 10 (C# 14).
44

55
Projects
6-
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Chain of Responsibility, Command, Iterator, Mediator, Observer, State, Strategy, and Memento patterns.
6+
- `DesignPatterns` - Console demo showing Factory, Singleton, Builder, Prototype, Abstract Factory, Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Chain of Responsibility, Command, Iterator, Mediator, Observer, State, Strategy, Template Method, and Memento patterns.
77
- Factory implementation: `DesignPatterns/Factories`
88
- Singleton implementation: `DesignPatterns/Singleton/Logger.cs`
99
- Builder implementation: `DesignPatterns/Builder/HouseBuilder.cs` and `DesignPatterns/Builder/House.cs`
@@ -23,6 +23,7 @@ Projects
2323
- Observer implementation: `DesignPatterns/Observer/*`
2424
- State implementation: `DesignPatterns/State/*`
2525
- Strategy implementation: `DesignPatterns/Strategy/*`
26+
- Template Method implementation: `DesignPatterns/TemplateMethod/*`
2627
- Memento implementation: `DesignPatterns/Memento/*`
2728
- `Tests` - xUnit tests covering the examples.
2829

@@ -277,6 +278,19 @@ Included patterns and brief docs
277278
editor.Restore(caretaker.PopState());
278279
```
279280
281+
- Template Method Pattern
282+
- Purpose: Define the skeleton of an algorithm in a base class and let subclasses override specific steps without changing the algorithm's structure.
283+
- Example: `DesignPatterns/TemplateMethod/*` contains `Report` (base class) and concrete reports `SalesReport` and `InventoryReport` that implement the specific steps.
284+
- Usage snippet:
285+
286+
```csharp
287+
var sales = new SalesReport();
288+
Console.WriteLine(sales.GenerateReport());
289+
290+
var inv = new InventoryReport();
291+
Console.WriteLine(inv.GenerateReport());
292+
```
293+
280294
Tests
281295
- Tests are written with xUnit in the `Tests` project.
282296
- Factory tests: `Tests/ShapeFactoryTests.cs`
@@ -299,6 +313,7 @@ Tests
299313
- State tests: `Tests/StateTests.cs`
300314
- Strategy tests: `Tests/StrategyTests.cs`
301315
- Memento tests: `Tests/MementoTests.cs`
316+
- Template Method tests: `Tests/TemplateMethodTests.cs`
302317
303318
Common commands
304319
- Build solution: `dotnet build`

Tests/TemplateMethodTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using DesignPatterns.TemplateMethod;
2+
using Xunit;
3+
4+
namespace Tests
5+
{
6+
public class TemplateMethodTests
7+
{
8+
[Fact]
9+
public void SalesReport_Generates_Correctly()
10+
{
11+
var r = new SalesReport();
12+
var output = r.GenerateReport();
13+
Assert.Contains("SalesReport", output);
14+
Assert.Contains("Total=450", output);
15+
}
16+
17+
[Fact]
18+
public void InventoryReport_Generates_Correctly()
19+
{
20+
var r = new InventoryReport();
21+
var output = r.GenerateReport();
22+
Assert.Contains("InventoryReport", output);
23+
Assert.Contains("TotalItems=35", output);
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)