asp.net MVC4 框架揭秘 读书笔记系列2

 

1.2 MVC 变体


MVC 是一种Pattern 另外一种说法是ParaDigm 范例

模式和范例的区别在于前者可以应用到具体的应用上,而后者则仅仅提供一些指导方针

1.2.1 MVP

Model View Presenter 交互图

技术分享

MVC 模式中元素之间 “混乱”的交互主要体现在允许View 和 Model 绕开Controller进行单独交流,这在MVP 模式中得到了充分解决

PV 模式 (passive View)

解决View很难测试的最好方法是让他无需测试,让UI处理更少逻辑,被动的交给Presenter来处理

暴漏UI不一定必须暴漏UI控件,

没有必要写成

public interface IemployeeSearchView1
{
    DropDownList Department { get; }
    GridView Employees { get; }
}

 而可以通过数据的属性来定义接口,这样就可以将presenter中的UI处理逻辑分离出来

public interface IemployeeSearchView
{
    IEnumerable<string> Departments { set; }
    string SelectedDedpartment { get; }
    IEnumerable<Employee> Employees { set; }
}

具体的实现方法如下:

public partial class _Default : System.Web.UI.Page, IemployeeSearchView
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public IEnumerable<string> Departments
    {
        set
        {
            this.DropDownListDepartments.DataSource = value;
            this.DropDownListDepartments.DataBind();
        }
    }

    public string SelectedDedpartment
    {
        get { return this.DropDownListDepartments.SelectedValue; }
    }

    public IEnumerable<Employee> Employees
    {
        set
        {
            this.GridViewEmployees.DataSource = value;
            this.GridViewEmployees.DataBind();
        }
    }
}

这样做意味着所有的UI逻辑都可以被测试,但是它要求将所有可供操作的UI元素定义在对应的接口中,无疑会增加Presenter 的复杂度,这就引出SC模式

SC模式(supervsing Controller)

View 和Presenter 之间的交互式整个MVP的核心,能否正确地应用MVP模式来架构应用,主要取决于View 和Presenter 之间的关系 在由model、View Presenter 组成的三角关系中,核心不是View 而是Presenter,Presenter 不仅是View调用的中介,而是最终决定如何响应用户交互行为的决策者。

View 本身仅仅实现单纯的独立的UI处理逻辑,他处理的数据应该是Presneter实时推送过来的,所以View 尽可能不去维护数据状态,定义在IView的接口最好只包含方法,而避免属性的定义,Presenter 所需的关于View的状态应该在接收到View发送的用户请求时一次性推送,而不需要通过View 的属性去获得它

以下为所有代码

Model

public class Employee
    {
        public string Id { get; private set; }
        public string Name { get; private set; }
        public string Gender { get; private set; }
        public DateTime BirthDate { get; private set; }
        public string Department { get; private set; }

        public Employee(string id, string name, string gender, DateTime birthDate, string department)
        {
            this.Id = id;
            this.Name = name;
            this.Gender = gender;
            this.BirthDate = birthDate;
            this.Department = department;
        }
    }

EmployeeRespository

   public class EmployeeRepository
    {
        private static IList<Employee> employees;

        static EmployeeRepository()
        {
            employees = new List<Employee>();
            employees.Add(new Employee("001", "张三", "", new DateTime(1981, 8, 1), "销售部"));
            employees.Add(new Employee("001", "李四", "", new DateTime(1982, 8, 4), "人事部"));
            employees.Add(new Employee("001", "王五", "", new DateTime(1981, 9, 1), "人事部"));

        }

        public IEnumerable<Employee> GetEmployees(string department = "")
        {
            if (string.IsNullOrEmpty(department))
            {
                return employees;
            }
            return employees.Where(e => e.Department == department).ToArray();

        }
    }

IEmployeeSearchView

 public interface IEmployeeSearchView
    {
        void BindEmployees(IEnumerable<Employee> employees);
        void BindDepartments(IEnumerable<string> departments);

    }

    public class DepartMentSelectedEventArgs : EventArgs
    {
        public string Department { get; private set; }
        public DepartMentSelectedEventArgs(string department)
        {
            this.Department = department;
        }
    }

EmployeeSearchPresenter

 public class EmployeeSearchPresenter
    {
        public IEmployeeSearchView View { get; private set; }
        public EmployeeRepository Repository { get; private set; }

        public EmployeeSearchPresenter(IEmployeeSearchView view)
        {
            this.View = view;
            this.Repository = new EmployeeRepository();
            view.DepartmentSelected += view_DepartmentSelected;
        }

        public void Initialize()
        {
            var employees = this.Repository.GetEmployees();
            this.View.BindEmployees(employees);
            string[] departments = new string[] { "销售部", "人事部", "IT部" };
            this.View.BindDepartments(departments);
        }

        void view_DepartmentSelected(object sender, DepartMentSelectedEventArgs e)
        {
            string department = e.Department;
            var employees = Repository.GetEmployees(department);
            this.View.BindEmployees(employees);
        }
    }

Web

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Chaper1SC.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div id="page">
            <div style="text-align: center; clear: both">
                请选择部门:<asp:DropDownList ID="dpDownListDepartments" runat="server"></asp:DropDownList><asp:Button Text="查询" runat="server" OnClick="Unnamed_Click" />
            </div>
            <div>
                <asp:GridView ID="GvEmployees" runat="server" AutoGenerateColumns="false" Width="100%">
                    <Columns>
                        <asp:BoundField DataField="Name" HeaderText="姓名" />
                        <asp:BoundField DataField="Gender" HeaderText="性别" />
                        <asp:BoundField DataField="BirthDate" HeaderText="出生日期" DataFormatString="{0:dd/MM/yy}" />
                        <asp:BoundField DataField="Gender" HeaderText="性别" />
                    </Columns>
                </asp:GridView>
            </div>
        </div>
    </form>
</body>
</html>

 

 public partial class WebForm1 : System.Web.UI.Page, IEmployeeSearchView
    {
        public event EventHandler<DepartMentSelectedEventArgs> DepartmentSelected;
        public EmployeeSearchPresenter Presenter { get; private set; }

        public WebForm1()
        {
            this.Presenter = new EmployeeSearchPresenter(this);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                this.Presenter.Initialize();
            }
        }

        public void BindEmployees(IEnumerable<Employee> employees)
        {
            this.GvEmployees.DataSource = employees;
            this.GvEmployees.DataBind();
        }

        public void BindDepartments(IEnumerable<string> departments)
        {
            this.dpDownListDepartments.DataSource = departments;
            this.dpDownListDepartments.DataBind();
        }

        protected void Unnamed_Click(object sender, EventArgs e)
        {
            string deparment = this.dpDownListDepartments.SelectedValue;
            DepartMentSelectedEventArgs args = new DepartMentSelectedEventArgs(deparment);
            if (null != DepartmentSelected)
            {
                DepartmentSelected(sender, args);
            }
        }


    }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。