CSharp: Strategy Pattern
/// <summary>
/// A simple file handlng class
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public class csFile
{
private string fileName;
StreamReader ts;
StreamWriter ws;
/// <summary>
///
/// </summary>
private bool opened, writeOpened;
/// <summary>
///
/// </summary>
public csFile()
{
init();
}
/// <summary>
///
/// </summary>
private void init()
{
opened = false;
writeOpened = false;
}
/// <summary>
///
/// </summary>
/// <param name="file_name"></param>
public csFile(string file_name)
{
fileName = file_name;
init();
}
/// <summary>
///
/// </summary>
/// <param name="file_name"></param>
/// <returns></returns>
public bool OpenForRead(string file_name)
{
fileName = file_name;
try
{
ts = new StreamReader(fileName);
opened = true;
}
catch (FileNotFoundException)
{
return false;
}
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool OpenForRead()
{
return OpenForRead(fileName);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public string readLine()
{
return ts.ReadLine();
}
/// <summary>
///
/// </summary>
/// <param name="s"></param>
public void writeLine(string s)
{
ws.WriteLine(s);
}
/// <summary>
///
/// </summary>
public void close()
{
if (opened)
ts.Close();
if (writeOpened)
ws.Close();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool OpenForWrite()
{
return OpenForWrite(fileName);
}
/// <summary>
///
/// </summary>
/// <param name="file_name"></param>
/// <returns></returns>
public bool OpenForWrite(string file_name)
{
try
{
ws = new StreamWriter(file_name);
fileName = file_name;
writeOpened = true;
return true;
}
catch (FileNotFoundException)
{
return false;
}
}
}
/// <summary>
/// String Tokenizer class
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public class StringTokenizer
{
private string data, delimiter;
private string[] tokens;
private int index;
/// <summary>
///
/// </summary>
/// <param name="dataLine"></param>
public StringTokenizer(string dataLine)
{
init(dataLine, " ");
}
/// <summary>
///
/// </summary>
/// <param name="dataLine"></param>
/// <param name="delim"></param>
private void init(String dataLine, string delim)
{
delimiter = delim;
data = dataLine;
tokens = data.Split(delimiter.ToCharArray());
index = 0;
}
/// <summary>
///
/// </summary>
/// <param name="dataLine"></param>
/// <param name="delim"></param>
public StringTokenizer(string dataLine, string delim)
{
init(dataLine, delim);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public bool hasMoreElements()
{
return (index < (tokens.Length));
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public string nextToken()
{
return nextElement();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public string nextElement()
{
string s = tokens[index++];
while ((s.Length <= 0) && (index < tokens.Length))
s = tokens[index++];
return s;
}
}
/// <summary>
/// Command interface
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public interface Command
{
void Execute();
}
/// <summary>
/// Selects which plot strategy to carry out
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public class Context
{
float[] x, y;
PlotStrategy plts; //strategy selected goes here
/// <summary>
/// -----
/// </summary>
public void plot()
{
readFile(); //read in data
plts.plot(x, y);
}
/// <summary>
/// select bar plot
/// </summary>
public void setBarPlot()
{
plts = new BarPlotStrategy();
}
/// <summary>
/// select line plot
/// </summary>
public void setLinePlot()
{
plts = new LinePlotStrategy();
}
/// <summary>
///
/// </summary>
public void readFile()
{
ArrayList xc = new ArrayList();
ArrayList yc = new ArrayList();
//reads data in from data file
csFile fl = new csFile("data.txt");
fl.OpenForRead();
string sline = fl.readLine();
while (sline != null)
{
int i = sline.IndexOf(" ");
if (i > 0)
{
float tmp = Convert.ToSingle(sline.Substring(0, i));
xc.Add(tmp);
tmp = Convert.ToSingle(sline.Substring(i + 1));
yc.Add(tmp);
}
sline = fl.readLine();
}
//copy into arrays from collections
float[] xp = new float[xc.Count];
float[] yp = new float[yc.Count];
for (int i = 0; i < xc.Count; i++)
{
xp[i] = (float)xc[i];
yp[i] = (float)yc[i];
}
x = xp;
y = yp;
fl.close();
}
}
/// <summary>
/// Summary description for PlotStrategy.
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public abstract class PlotStrategy
{
public abstract void plot(float[] x, float[] y);
}
/// <summary>
/// Summary description for LinePlotStrategy.
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public class LinePlotStrategy : PlotStrategy
{
/// <summary>
///
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public override void plot(float[] x, float[] y)
{
LinePlotForm lplt = new LinePlotForm();
lplt.Show();
lplt.plot(x, y);
}
}
/// <summary>
/// Summary description for BarPlotStrategy.
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public class BarPlotStrategy : PlotStrategy
{
public override void plot(float[] xp, float[] yp)
{
BarPlotForm bplot = new BarPlotForm();
bplot.Show();
bplot.plot(xp, yp);
}
}
/// <summary>
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public partial class BarButton : System.Windows.Forms.Button, Command
{
/// <summary>
///
/// </summary>
private Context contxt;
/// <summary>
///
/// </summary>
/// <param name="ctx"></param>
public void setContext(Context ctx)
{
contxt = ctx;
}
public void Execute()
{
contxt.setBarPlot();
contxt.plot();
}
/// <summary>
///
/// </summary>
public BarButton()
{
InitializeComponent();
}
/// <summary>
///
/// </summary>
/// <param name="container"></param>
public BarButton(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
/// <summary>
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public partial class LineButton : System.Windows.Forms.Button, Command
{
/// <summary>
///
/// </summary>
private Context contxt;
/// <summary>
///
/// </summary>
/// <param name="ctx"></param>
public void setContext(Context ctx)
{
contxt = ctx;
}
/// <summary>
///
/// </summary>
public void Execute()
{
contxt.setLinePlot();
contxt.plot();
}
/// <summary>
///
/// </summary>
public LineButton()
{
InitializeComponent();
this.Text = "Line plot";
}
/// <summary>
///
/// </summary>
/// <param name="container"></param>
public LineButton(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
/// <summary>
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public partial class BarPlotForm : Form
{
protected float ymin, ymax, xfactor, yfactor;
protected float xpmin, xpmax, ypmin, ypmax, xp, yp;
private float xmin, xmax;
private int w, h;
protected float[] x, y;
private ArrayList colors;
protected Pen bPen;
protected bool hasData;
protected const float max = 1.0e38f;
/// <summary>
///
/// </summary>
/// <param name="xp"></param>
/// <param name="yp"></param>
public void plot(float[] xp, float[] yp)
{
x = xp;
y = yp;
setPlotBounds(); //compute scaling factors
hasData = true;
pic.Refresh();
}
/// <summary>
///
/// </summary>
public void findBounds()
{
xmin = max;
xmax = -max;
ymin = max;
ymax = -max;
for (int i = 0; i < x.Length; i++)
{
if (x[i] > xmax) xmax = x[i];
if (x[i] < xmin) xmin = x[i];
if (y[i] > ymax) ymax = y[i];
if (y[i] < ymin) ymin = y[i];
}
}
/// <summary>
///
/// </summary>
public virtual void setPlotBounds()
{
findBounds();
//compute scaling factors
h = pic.Height;
w = pic.Width;
xfactor = 0.8F * w / (xmax - xmin);
xpmin = 0.05F * w;
xpmax = w - xpmin;
yfactor = 0.9F * h / (ymax - ymin);
ypmin = 0.05F * h;
ypmax = h - ypmin;
//create array of colors for bars
colors = new ArrayList();
colors.Add(new SolidBrush(Color.Red));
colors.Add(new SolidBrush(Color.Green));
colors.Add(new SolidBrush(Color.Blue));
colors.Add(new SolidBrush(Color.Magenta));
colors.Add(new SolidBrush(Color.Yellow));
}
/// <summary>
///
/// </summary>
/// <param name="xp"></param>
/// <returns></returns>
public int calcx(float xp)
{
int ix = (int)((xp - xmin) * xfactor + xpmin);
return ix;
}
/// <summary>
///
/// </summary>
/// <param name="yp"></param>
/// <returns></returns>
public int calcy(float yp)
{
yp = ((yp - ymin) * yfactor);
int iy = h - (int)(ypmax - yp);
return iy;
}
/// <summary>
///
/// </summary>
public BarPlotForm()
{
InitializeComponent();
this.Text = "Bar Plot";
}
/// <summary>
///
/// </summary>
/// <param name="container"></param>
public BarPlotForm(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BarPlotForm_Load(object sender, EventArgs e)
{
}
/// <summary>
/// LinePlotForm需要重写此方法
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void pic_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (hasData)
{
for (int i = 0; i < x.Length; i++)
{
int ix = calcx(x[i]);
int iy = calcy(y[i]);
Brush br = (Brush)colors[i];
g.FillRectangle(br, ix, h - iy, 20, iy);
}
}
}
}
/// <summary>
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public partial class LinePlotForm : BarPlotForm
{
/// <summary>
///
/// </summary>
public LinePlotForm()
{
init();
//InitializeComponent();
}
/// <summary>
///
/// </summary>
protected void init()
{
bPen = new Pen(Color.Black);
this.Text = "Line Plot";
}
/// <summary>
/// 重写BarPlotForm的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void pic_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (hasData)
{
for (int i = 1; i < x.Length; i++)
{
int ix = calcx(x[i - 1]);
int iy = calcy(y[i - 1]);
int ix1 = calcx(x[i]);
int iy1 = calcy(y[i]);
g.DrawLine(bPen, ix, iy, ix1, iy1);
}
}
}
/// <summary>
///
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// LinePlotForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
this.ClientSize = new System.Drawing.Size(678, 702);
this.Name = "LinePlotForm";
this.Load += new System.EventHandler(this.LinePlotForm_Load);
//this.Paint += new System.Windows.Forms.PaintEventHandler(this.LinePlotForm_Paint);
this.ResumeLayout(false);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LinePlotForm_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 在窗体画
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LinePlotForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (hasData)
{
for (int i = 1; i < x.Length; i++)
{
int ix = calcx(x[i - 1]);
int iy = calcy(y[i - 1]);
int ix1 = calcx(x[i]);
int iy1 = calcy(y[i]);
g.DrawLine(bPen, ix, iy, ix1, iy1);
}
}
}
}
调用:
/// <summary>
/// Strategy Pattern 策略模式
///20220918
/// geovindu,Geovin Du,涂聚文
/// </summary>
public partial class StrategyPatternForm : Form
{
private void init()
{
EventHandler evh = new EventHandler(ButtonClick);
btLine.Click += evh;
btBar.Click += evh;
Context contxt = new Context();
btBar.setContext(contxt);
btLine.setContext(contxt);
}
/// <summary>
///
/// </summary>
public StrategyPatternForm()
{
InitializeComponent();
init();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StrategyPatternForm_Load(object sender, EventArgs e)
{
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonClick(object sender, System.EventArgs e)
{
Command comd = (Command)sender;
comd.Execute();
}
}
data:
1 20 2 35 3 13 4 52 5 44
输出:

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
浙公网安备 33010602011771号