Definition
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm‘s structure.
Participants
The classes and/or objects participating in this pattern are:
- AbstractClass (DataObject)
- Defines abstract primitive operations that concrete subclasses define to implement steps of an algorithm
- Implements a template method defining the skeleton of an algorithm. The template method calls primitive operations as well as operations defined in AbstractClass or those of other objects
- ConcreteClass (CustomerDataObject)
- Implements the primitive operations or carry out subclass-specific steps of the algorithm
Sample Code in C#
This structural code demonstrates the Template method which provides a skeleton calling sequence of methods. One or more steps can be deferred to subclasses which implement these steps without changing the overall calling sequence.
// Template Method pattern - Structural example
namespace CSharpLearning
{
using System;
/// <summary>
/// Startup class for Real-World Template Method design pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
AbstractClass aA = new ConcreteClassA();
aA.TemplateMethod();
AbstractClass aB = new ConcreteClassB();
aB.TemplateMethod();
// Wait for user.
Console.ReadKey();
}
}
/// <summary>
/// The ‘AbstractClass‘ abstract class.
/// </summary>
public abstract class AbstractClass
{
/// <summary>
/// The primitive operation 1.
/// </summary>
public abstract void PrimitiveOperation1();
/// <summary>
/// The primitive operation 2.
/// </summary>
public abstract void PrimitiveOperation2();
/// <summary>
/// The template method.
/// </summary>
public void TemplateMethod()
{
this.PrimitiveOperation1();
this.PrimitiveOperation2();
Console.WriteLine(string.Empty);
}
}
/// <summary>
/// A ‘ConcreteClass‘ class.
/// </summary>
public class ConcreteClassA : AbstractClass
{
/// <summary>
/// The primitive operation 1.
/// </summary>
public override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassA.PrimitiveOperation1()");
}
/// <summary>
/// The primitive operation 2.
/// </summary>
public override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassA.PrimitiveOperation2()");
}
}
/// <summary>
/// A ‘ConcreteClass‘ class.
/// </summary>
public class ConcreteClassB : AbstractClass
{
/// <summary>
/// The primitive operation 1.
/// </summary>
public override void PrimitiveOperation1()
{
Console.WriteLine("ConcreteClassB.PrimitiveOperation1()");
}
/// <summary>
/// The primitive operation 2.
/// </summary>
public override void PrimitiveOperation2()
{
Console.WriteLine("ConcreteClassB.PrimitiveOperation2()");
}
}
}
// Output:
/*
ConcreteClassA.PrimitiveOperation1()
ConcreteClassA.PrimitiveOperation2()
ConcreteClassB.PrimitiveOperation1()
ConcreteClassB.PrimitiveOperation2()
*/
This real-world code demonstrates a Template method named Run() which provides a skeleton calling sequence of methods. Implementation of these steps are deferred to the CustomerDataObject subclass which implements the Connect, Select, Process, and Disconnect methods.
// Template Method pattern - Real World example
namespace CSharpLearning
{
using System;
using System.Data;
using System.Data.OleDb;
/// <summary>
/// Startup class for Real-World Template Design Pattern.
/// </summary>
public class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
public static void Main()
{
DataAccessObject daoCategories = new Categories();
daoCategories.Run();
DataAccessObject daoProducts = new Products();
daoProducts.Run();
// Wait for user.
Console.ReadKey();
}
}
/// <summary>
/// The ‘AbstractClass‘ abstract class.
/// </summary>
public abstract class DataAccessObject
{
/// <summary>
/// The connection string.
/// </summary>
protected string ConnectionString;
/// <summary>
/// The data set.
/// </summary>
protected DataSet DataSet;
/// <summary>
/// The connect.
/// </summary>
public virtual void Connect()
{
// Make sure mdb is available to app.
this.ConnectionString = "provider=Microsoft.JET.OLEDB.4.0; data source=..\\..\\..\\db1.mdb";
}
/// <summary>
/// The select.
/// </summary>
public abstract void Select();
/// <summary>
/// The process.
/// </summary>
public abstract void Process();
/// <summary>
/// The disconnect.
/// </summary>
public virtual void Disconnect()
{
this.ConnectionString = string.Empty;
}
/// <summary>
/// The ‘Template Method‘.
/// </summary>
public void Run()
{
this.Connect();
this.Select();
this.Process();
this.Disconnect();
}
}
/// <summary>
/// A ‘ConcreteClass‘ class.
/// </summary>
public class Categories : DataAccessObject
{
/// <summary>
/// The select.
/// </summary>
public override void Select()
{
const string Sql = "select CategoryName from Categories";
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(Sql, this.ConnectionString);
this.DataSet = new DataSet();
dataAdapter.Fill(this.DataSet, "Categories");
}
/// <summary>
/// The process.
/// </summary>
public override void Process()
{
Console.WriteLine("Categories ---- ");
DataTable dataTable = this.DataSet.Tables["Categories"];
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine(row["CategoryName"]);
}
Console.WriteLine();
}
}
/// <summary>
/// A ‘ConcreteClass‘ class.
/// </summary>
public class Products : DataAccessObject
{
/// <summary>
/// The select.
/// </summary>
public override void Select()
{
const string Sql = "select ProductName from Products";
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(Sql, this.ConnectionString);
this.DataSet = new DataSet();
dataAdapter.Fill(this.DataSet, "Products");
}
/// <summary>
/// The process.
/// </summary>
public override void Process()
{
Console.WriteLine("Products ---- ");
DataTable dataTable = this.DataSet.Tables["Products"];
foreach (DataRow row in dataTable.Rows)
{
Console.WriteLine(row["ProductName"]);
}
Console.WriteLine();
}
}
}
// Output:
/*
Categories ----
Beverages
Condiments
Confections
Dairy Products
Grains/Cereals
Meat/Poultry
Produce
Seafood
Products ----
Chai
Chang
Aniseed Syrup
Chef Anton‘s Cajun Seasoning
Chef Anton‘s Gumbo Mix
Grandma‘s Boysenberry Spread
Uncle Bob‘s Organic Dried Pears
Northwoods Cranberry Sauce
Mishi Kobe Niku
*/
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net
原文地址:https://www.cnblogs.com/kwincaq/p/10113267.html
时间: 2024-11-05 14:43:28