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

  

 

輸出:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章