您的位置:首页 > 移动开发 > Objective-C

MVP(model,view Presenter) Pattern(模式) 学习

2009-08-05 16:25 399 查看
  昨天下了Microsoft Unity想学习一下ioc的东西,没想到自己连mvp pattern还不知道呢,太无知了,MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过
Controller。,现在我把 Unity的实例中用到的mvp的代码整理出来了,还花了我一番功夫的,没有的依赖注入了,类的实例化还得手动处理,但是我整理的这个一个地方违背了mvp的原则(只是想代码简单些)

,顺便也考考你的眼力如何,能否看出哪一点违背了mvp的原则,呵呵!源代码如下(或者去我的资源了下载完整的源代码也可以):

  public interface IStoplightView : INotifyPropertyChanged

    {

        Color CurrentColor { get; set; }

        string GreenDuration { get; set; }

        string YellowDuration { get; set; }

        string RedDuration { get; set; }

        event EventHandler UpdateClicked;

        event EventHandler ForceChangeClicked;

    }

    public static class StoplightViewProperties

    {

        public const string CurrentColor = "CurrentColor";

        public const string GreenDuration = "GreenDuration";

        public const string YellowDuration = "YellowDuration";

        public const string RedDuration = "RedDuration";

    }

    public enum StoplightColors

    {

        Green,

        Yellow,

        Red

    }

————————————————————————————————————

public class LightChangedEventArgs : EventArgs

    {

        private StoplightColors currentColor;

        public StoplightColors CurrentColor

        {

            get { return currentColor; }

            private set { currentColor = value; }

        }

        public LightChangedEventArgs(StoplightColors color)

        {

            CurrentColor = color;

        }

    }

    public delegate void StoplightChangedHandler(object sender, LightChangedEventArgs e);

    public class Stoplight

    {

        public const StoplightColors Green = StoplightColors.Green;

        public const StoplightColors Yellow = StoplightColors.Yellow;

        public const StoplightColors Red = StoplightColors.Red;

        private StoplightColors currentColor = StoplightColors.Green;

        public event StoplightChangedHandler Changed;

        public StoplightColors CurrentColor

        {

            get { return currentColor; }

        }

        public void Next()

        {

            ++currentColor;

            if (currentColor > StoplightColors.Red)

            {

                currentColor = StoplightColors.Green;

            }

            RaiseChanged();

        }

        protected void RaiseChanged()

        {

            StoplightChangedHandler handlers = Changed;

            if (handlers != null)

            {

                LightChangedEventArgs e = new LightChangedEventArgs(currentColor);

                handlers(this, e);

            }

        }

    }

————————————————————————————————————————

 public class StoplightPresenter

    {

        private Timer timer;

        public Timer Timer

        {

            get { return timer; }

            set { timer = value; }

        }

        private Stoplight stoplight;

        public Stoplight Stoplight

        {

            get { return stoplight; }

            set { stoplight = value; }

        }

        private StoplightSchedule schedule;

        public StoplightSchedule Schedule

        {

            get { return schedule; }

            set { schedule = value; }

        }

        /// <summary>

        /// 构造方法

        /// </summary>

        /// <param name="timer"></param>

        public StoplightPresenter(Timer timer)

        {

            this.Timer = timer;

        }

        private IStoplightView view;

        public void SetView(IStoplightView view)

        {

            this.view = view;

            view.PropertyChanged += OnViewPropertyChanged;

            view.UpdateClicked += OnViewUpdateClicked;

            view.ForceChangeClicked += OnViewForceChangeClicked;

            if(Stoplight==null)

            {

                Stoplight = new Stoplight();

            }

            Stoplight.Changed += OnStoplightChanged;

            view.GreenDuration = "3000";

            view.YellowDuration = "4000";

            view.RedDuration = "5000";

            view.CurrentColor = Color.Green;

            if (Schedule == null)

            {

                Schedule = new StoplightSchedule(Timer);

                Schedule.ChangeLight += OnScheduledLightChange;

            }

            Schedule.Update(TimeSpan.FromMilliseconds(3000),

                         TimeSpan.FromMilliseconds(4000),

                         TimeSpan.FromMilliseconds(5000));

            Schedule.Start();

        }

        public void OnScheduledLightChange(object sender, EventArgs e)

        {

            Stoplight.Next();

        }

        private void OnViewPropertyChanged(object sender, PropertyChangedEventArgs e)

        {

            string newDurationValue = null;

            int newDurationInMilliseconds;

            if (e.PropertyName == StoplightViewProperties.CurrentColor)

            {

                return;

            }

            ActOnProperty(e.PropertyName,

                delegate { newDurationValue = view.GreenDuration; },

                delegate { newDurationValue = view.YellowDuration; },

                delegate { newDurationValue = view.RedDuration; });

            if (!int.TryParse(newDurationValue, out newDurationInMilliseconds))

            {

                MessageBox.Show("Duration must be an integer");

            }

            else

            {

            }

        }

        private delegate void Action();

        private void ActOnProperty(

            string propertyName, Action greenAction, Action yellowAction, Action redAction)

        {

            switch (propertyName)

            {

                case StoplightViewProperties.GreenDuration:

                    greenAction();

                    break;

                case StoplightViewProperties.YellowDuration:

                    yellowAction();

                    break;

                case StoplightViewProperties.RedDuration:

                    redAction();

                    break;

                case StoplightViewProperties.CurrentColor:

                    return;

            }

        }

        private void OnViewForceChangeClicked(object sender, EventArgs e)

        {

            Schedule.ForceChange();

        }

        private void OnViewUpdateClicked(object sender, EventArgs e)

        {

            string[] durationsAsString = new string[3];

            List<string> propNames = new List<string>(new string[]

            {

                StoplightViewProperties.GreenDuration,

                StoplightViewProperties.YellowDuration,

                StoplightViewProperties.RedDuration

            });

            foreach (string propName in propNames)

            {

                ActOnProperty(propName,

                delegate { durationsAsString[0] = view.GreenDuration; },

                delegate { durationsAsString[1] = view.YellowDuration; },

                delegate { durationsAsString[2] = view.RedDuration; }

                );

            }

            TimeSpan[] timeSpans = Array.ConvertAll<string, TimeSpan>(durationsAsString,

            delegate(string s)

            {

                return

                TimeSpan.FromMilliseconds(

                int.Parse(s));

            });

            Schedule.Update(timeSpans[0], timeSpans[1], timeSpans[2]);

        }

        private void OnStoplightChanged(object sender, LightChangedEventArgs e)

        {

            switch (e.CurrentColor)

            {

                case StoplightColors.Green:

                    view.CurrentColor = Color.Green;

                    break;

                case StoplightColors.Yellow:

                    view.CurrentColor = Color.Yellow;

                    break;

                case StoplightColors.Red:

                    view.CurrentColor = Color.Red;

                    break;

            }

        }

    }

——————————————————————————————————————————

 public class StoplightSchedule

    {

        private Timer timer;

        private TimeSpan[] lightTimes = new TimeSpan[3];

        private int currentLight = 0;

        public event EventHandler ChangeLight;

        public StoplightSchedule(Timer timer)

        {

            this.timer = timer;

            this.timer.Tick += OnClick;

        }

        public void Start()

        {

            timer.Start();

        }

        public void Update(TimeSpan green, TimeSpan yellow, TimeSpan red)

        {

            lightTimes[0] = green;

            lightTimes[1] = yellow;

            lightTimes[2] = red;

        }

        public void ForceChange()

        {

            OnTimerExpired(this, EventArgs.Empty);

        }

        public void OnTimerExpired(object sender, EventArgs e)

        {

            EventHandler handlers = ChangeLight;

            if (handlers != null)

            {

                handlers(this, EventArgs.Empty);

            }

            currentLight = (currentLight + 1) % 3;

            timer.Interval = (int)lightTimes[0].TotalMilliseconds;

            timer.Start();

        }

        private void OnClick(object sender, EventArgs e)

        {

            timer.Stop();

            OnTimerExpired(sender, e);

        }

    }

——————————————————————————————————————————

 public class StoplightForm : Form, IStoplightView

    {

        #region Designer.cs

        /// <summary>

        /// Required designer variable.

        /// </summary>

        private System.ComponentModel.IContainer components = null;

        /// <summary>

        /// Clean up any resources being used.

        /// </summary>

        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

        protected override void Dispose(bool disposing)

        {

            if (disposing && (components != null))

            {

                components.Dispose();

            }

            base.Dispose(disposing);

        }

        #region Windows Form Designer generated code

        /// <summary>

        /// Required method for Designer support - do not modify

        /// the contents of this method with the code editor.

        /// </summary>

        private void InitializeComponent()

        {

            this.components = new System.ComponentModel.Container();

            this.stopLightPanel = new System.Windows.Forms.Panel();

            this.label1 = new System.Windows.Forms.Label();

            this.label2 = new System.Windows.Forms.Label();

            this.label3 = new System.Windows.Forms.Label();

            this.greenDurationTextBox = new System.Windows.Forms.TextBox();

            this.yellowDurationTextBox = new System.Windows.Forms.TextBox();

            this.redDurationTextBox = new System.Windows.Forms.TextBox();

            this.updateScheduleButton = new System.Windows.Forms.Button();

            this.forceChangeButton = new System.Windows.Forms.Button();

            this.timer1 = new System.Windows.Forms.Timer(this.components);

            this.SuspendLayout();

            //

            // stopLightPanel

            //

            this.stopLightPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;

            this.stopLightPanel.Location = new System.Drawing.Point(45, 36);

            this.stopLightPanel.Name = "stopLightPanel";

            this.stopLightPanel.Size = new System.Drawing.Size(213, 30);

            this.stopLightPanel.TabIndex = 0;

            //

            // label1

            //

            this.label1.AutoSize = true;

            this.label1.Location = new System.Drawing.Point(42, 80);

            this.label1.Name = "label1";

            this.label1.Size = new System.Drawing.Size(95, 12);

            this.label1.TabIndex = 1;

            this.label1.Text = "&Green Duration:";

            //

            // label2

            //

            this.label2.AutoSize = true;

            this.label2.Location = new System.Drawing.Point(42, 108);

            this.label2.Name = "label2";

            this.label2.Size = new System.Drawing.Size(101, 12);

            this.label2.TabIndex = 3;

            this.label2.Text = "&Yellow Duration:";

            //

            // label3

            //

            this.label3.AutoSize = true;

            this.label3.Location = new System.Drawing.Point(42, 133);

            this.label3.Name = "label3";

            this.label3.Size = new System.Drawing.Size(83, 12);

            this.label3.TabIndex = 5;

            this.label3.Text = "&Red Duration:";

            //

            // greenDurationTextBox

            //

            this.greenDurationTextBox.Location = new System.Drawing.Point(131, 80);

            this.greenDurationTextBox.Name = "greenDurationTextBox";

            this.greenDurationTextBox.Size = new System.Drawing.Size(127, 21);

            this.greenDurationTextBox.TabIndex = 2;

            //

            // yellowDurationTextBox

            //

            this.yellowDurationTextBox.Location = new System.Drawing.Point(131, 105);

            this.yellowDurationTextBox.Name = "yellowDurationTextBox";

            this.yellowDurationTextBox.Size = new System.Drawing.Size(127, 21);

            this.yellowDurationTextBox.TabIndex = 4;

            //

            // redDurationTextBox

            //

            this.redDurationTextBox.Location = new System.Drawing.Point(131, 130);

            this.redDurationTextBox.Name = "redDurationTextBox";

            this.redDurationTextBox.Size = new System.Drawing.Size(127, 21);

            this.redDurationTextBox.TabIndex = 6;

            //

            // updateScheduleButton

            //

            this.updateScheduleButton.Location = new System.Drawing.Point(93, 174);

            this.updateScheduleButton.Name = "updateScheduleButton";

            this.updateScheduleButton.Size = new System.Drawing.Size(126, 21);

            this.updateScheduleButton.TabIndex = 7;

            this.updateScheduleButton.Text = "&Update Schedule";

            this.updateScheduleButton.UseVisualStyleBackColor = true;

            this.updateScheduleButton.Click += new System.EventHandler(this.OnUpdateScheduleClicked);

            //

            // forceChangeButton

            //

            this.forceChangeButton.Location = new System.Drawing.Point(93, 201);

            this.forceChangeButton.Name = "forceChangeButton";

            this.forceChangeButton.Size = new System.Drawing.Size(126, 21);

            this.forceChangeButton.TabIndex = 8;

            this.forceChangeButton.Text = "&Change Light";

            this.forceChangeButton.UseVisualStyleBackColor = true;

            this.forceChangeButton.Click += new System.EventHandler(this.OnChangeLightClicked);

            //

            // timer1

            //

            this.timer1.Enabled = true;

            this.timer1.Interval =100;

            //

            // StoplightForm

            //

            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);

            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

            this.ClientSize = new System.Drawing.Size(312, 270);

            this.Controls.Add(this.forceChangeButton);

            this.Controls.Add(this.updateScheduleButton);

            this.Controls.Add(this.redDurationTextBox);

            this.Controls.Add(this.yellowDurationTextBox);

            this.Controls.Add(this.greenDurationTextBox);

            this.Controls.Add(this.label3);

            this.Controls.Add(this.label2);

            this.Controls.Add(this.label1);

            this.Controls.Add(this.stopLightPanel);

            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;

            this.Name = "StoplightForm";

            this.Text = "Stoplight Simulator";

            this.ResumeLayout(false);

            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Panel stopLightPanel;

        private System.Windows.Forms.Label label1;

        private System.Windows.Forms.Label label2;

        private System.Windows.Forms.Label label3;

        private System.Windows.Forms.TextBox greenDurationTextBox;

        private System.Windows.Forms.TextBox yellowDurationTextBox;

        private System.Windows.Forms.TextBox redDurationTextBox;

        private System.Windows.Forms.Button updateScheduleButton;

        private System.Windows.Forms.Button forceChangeButton;

        private Timer timer1;

        #endregion

       

        private StoplightPresenter presenter;

        public StoplightForm()

        {

            InitializeComponent();

            // 创建presenter层对象

            Presenter = new StoplightPresenter(this.timer1);

        }

        public StoplightPresenter Presenter

        {

            get { return presenter; }

            set

            {

                presenter = value;

                presenter.SetView(this);

            }

        }

        #region IStoplightView Members

        public Color CurrentColor

        {

            get { return stopLightPanel.BackColor; }

            set

            {

                stopLightPanel.BackColor = value;

                RaisePropertyChanged(StoplightViewProperties.CurrentColor);

            }

        }

        public string GreenDuration

        {

            get { return greenDurationTextBox.Text; }

            set

            {

                greenDurationTextBox.Text = value;

                RaisePropertyChanged(StoplightViewProperties.GreenDuration);

            }

        }

        public string YellowDuration

        {

            get { return yellowDurationTextBox.Text; }

            set

            {

                yellowDurationTextBox.Text = value;

                RaisePropertyChanged(StoplightViewProperties.YellowDuration);

            }

        }

        public string RedDuration

        {

            get { return redDurationTextBox.Text; }

            set

            {

                redDurationTextBox.Text = value;

                RaisePropertyChanged(StoplightViewProperties.RedDuration);

            }

        }

        public event EventHandler UpdateClicked;

        public event EventHandler ForceChangeClicked;

        public void SetError(string propertyName, string errorMessage)

        {

            Dictionary<string, Control> controlsByName = new Dictionary<string, Control>();

            controlsByName.Add(StoplightViewProperties.GreenDuration, greenDurationTextBox);

            controlsByName.Add(StoplightViewProperties.YellowDuration, yellowDurationTextBox);

            controlsByName.Add(StoplightViewProperties.RedDuration, redDurationTextBox);

        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        // Event firing helpers

        protected virtual void RaisePropertyChanged(string propertyName)

        {

            PropertyChangedEventHandler handlers = PropertyChanged;

            if (handlers != null)

            {

                handlers(this, new PropertyChangedEventArgs(propertyName));

            }

        }

        protected virtual void RaiseUpdateClicked()

        {

            EventHandler handlers = UpdateClicked;

            if (handlers != null)

            {

                handlers(this, EventArgs.Empty);

            }

        }

        protected virtual void RaiseForceChangeClicked()

        {

            EventHandler handlers = ForceChangeClicked;

            if (handlers != null)

            {

                handlers(this, EventArgs.Empty);

            }

        }

        private void OnUpdateScheduleClicked(object sender, EventArgs e)

        {

            RaiseUpdateClicked();

        }

        private void OnChangeLightClicked(object sender, EventArgs e)

        {

            RaiseForceChangeClicked();

        }

    }

————————————————————————————————————

 static class Program

    {

        /// <summary>

        /// 应用程序的主入口点。

        /// </summary>

        [STAThread]

        static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new StoplightForm());

        }

    }

代码粘贴结束了,考察一下您的眼力啦,呵呵......

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息