您的位置:首页 > 编程语言 > C#

C#设计模式之23——模板方法模式

2012-03-05 15:19 369 查看
模板方法模式是非常简单的一个模式。任何时候只要你编写了一个父类,并在类中留有一个或者多个方法给派生类实现,实质上就是在使用模板模式。模板模式形式化了在类中定义算法但是把算法的实现细节留个子类实现这一想法。

模板方法模式有四种可能在派生类中使用的方法:

1. 完整的方法,这些方法可以被派生类继承。

2.完全没有填写的方法,方法主体为空。

3. 包含某些操作的默认实现的方法,但是有可能在派生类中被重写。这种方法被称为钩子。

4. 其本身使用了抽象,钩子和具体方法的任意组合的方法。

 

假设我们有一个程序,在用户界面绘制三角形。

用户界面如图:



 

我们有一个抽象类Triangle类说明模式:

using System;
using System.Drawing ;

namespace Template
{
/// <summary>
/// Summary description for Triangle.
/// </summary>
public abstract class Triangle 	{
private Point p1, p2, p3;
protected Pen pen;
//-----
public Triangle(Point a, Point b, Point c) 	{
p1 = a;
p2 =  b;
p3 = c;
pen = new Pen(Color.Black , 1);
}
//-----
public virtual void draw(Graphics g) {
g.DrawLine (pen, p1, p2);
Point c = draw2ndLine(g, p2, p3);
closeTriangle(g, c);
}
//-----
public abstract Point draw2ndLine(Graphics g, Point a, Point b);
//-----
public void closeTriangle(Graphics g, Point c) {
g.DrawLine (pen, c, p1);
}
}
}


 

这里有个函数留给了派生类来实现,不同的派生类根据需要可以绘制不同的三角形。

两个派生类的实现,一个是普通的三角形,一个是等腰三角形类。

using System;
using System.Drawing ;
namespace Template
{
/// <summary>
/// Summary description for StdTriangle.
/// </summary>
public class StdTriangle :Triangle 	{
public StdTriangle(Point a, Point b, Point c) : base(a, b, c) {}
//------
public override Point draw2ndLine(Graphics g, Point a, Point b) {
g.DrawLine (pen, a, b);
return b;
}
}
}


 

using System;
using System.Drawing;
namespace Template
{
/// <summary>
/// Summary description for IsocelesTriangle.
/// </summary>
public class IsocelesTriangle : Triangle 	{
private Point newc;
private int newcx, newcy;
//-----
public IsocelesTriangle(Point a, Point b, Point c) :base(a, b, c) {
float dx1, dy1, dx2, dy2, side1, side2;
float slope, intercept;
int incr;
dx1 = b.X - a.X;
dy1 = b.Y - a.Y;
dx2 = c.X  - b.X;
dy2 = c.Y - b.Y;

side1 = calcSide(dx1, dy1);
side2 = calcSide(dx2, dy2);

if (side2 < side1)
incr = -1;
else
incr = 1;
slope = dy2 / dx2;
intercept = c.Y - slope * c.X;

//move point c so that this is an isoceles triangle
newcx = c.X;
newcy = c.Y;
while (Math.Abs (side1 - side2) > 1) {
newcx = newcx + incr;    //iterate a pixel at a time until close
newcy = (int)(slope * newcx + intercept);
dx2 = newcx - b.X;
dy2 = newcy - b.Y;
side2 = calcSide(dx2, dy2);
}
newc = new Point(newcx, newcy);
}
//-----
private float calcSide(float a, float b) {
return (float)Math.Sqrt (a*a +  b*b);
}
//-----
public override Point draw2ndLine(Graphics g, Point b, Point  c) {
g.DrawLine (pen, b, newc);
return newc;
}

}
}


 

然后就是主程序的调用:

private ArrayList triangles;
public Form1()
{
InitializeComponent();
init();

}
private void init() {
triangles = new ArrayList();
StdTriangle t1 = new StdTriangle(new Point(10, 10),
new Point(150, 50),
new Point(100, 75));
IsocelesTriangle t2 = new IsocelesTriangle(
new Point(150, 100), new Point(240, 40),
new Point(175, 150));
triangles.Add(t1);
triangles.Add(t2);
Pic.Paint+= new PaintEventHandler (TPaint);
}


 

private void TPaint (object sender,  System.Windows.Forms.PaintEventArgs e ) {
Graphics g = e.Graphics;
for (int i = 0; i<  triangles.Count ; i++) {
Triangle t = (Triangle)triangles[i];
t.draw(g);
}
}


模板模式始终在OO软件中存在,他们就是OO编程的普通组成部分。基类只能定义某些它将要用到的方法,而把其余部分留给派生类来实现。

这个设计模式更多的是面向对象编程的思想基础,比较简单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息