学习ASP.NET MVC框架揭秘笔记-实例演示:SC模式的应用

实例演示:SC模式的应用

为了对SC模式下的MVP,尤其是该模式下的View和Presenter之间的交互方式有一个深刻的认识,我们现在来做一个实例演示。我们采用员工查询的场景,用ASP.NET Web Forms来建立这个简单的应用。

我们先来定义员工的数据类型,Employee来表示一个员工,有5个属性:ID、姓名、性别、出生日期和部门。

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;
        }

作为包含应用状态和状态操作行为的Model,通过如下一个简单的EmployeeRepository类型来体现。表示所有员工列表的数据通过一个静态字段来维护,而GetEmployees方法返回指定部门的员工列表。如果没有指定筛选部门或者指定的部门字符为空,该方法直接返回所有员工列表。

public class EmployeeRepository
    {
        private static IList<Employee> employees;
        static EmployeeRepository()
        {
            employees = new List<Employee>();
            employees.Add(new Employee("001", "张三", "男",new DateTime(1981, 8, 24), "销售部"));
            employees.Add(new Employee("002", "李四", "女",new DateTime(1982, 7, 10), "人事部"));
            employees.Add(new Employee("003", "王五", "男",new DateTime(1981, 9, 21), "人事部"));
        }

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

接下来我们看看作为View接口的IEmployeeView的定义。该接口定义了BindEmployees和BindDepartments两个方法,分别用于绑定基于部门列表的DropDownList和基于员工列表的GridView。除此之外,IEmployeeView接口还定义了一个事件DepartmentSelected,该事件会在用户选择了筛选部门之后单机查询按钮时触发。DepartmentSelected事件参数类型为自定义的DepartmentSelectedEventAges,属性Department表示用户选择的部门。

public interface IEmployeeView
    {
        void BindEmployees(IEnumerable<Employee> employees);
        void BindDepartments(IEnumerable<string> departments);
        event EventHandler<DepartmentSelectedEventArgs> DepartmentSelected;
    }
public class DepartmentSelectedEventArgs : EventArgs
    {
        public string Department { get; private set; }
        public DepartmentSelectedEventArgs(string department)
        {
            this.Department = department;
        }
    }

作为MVP三角关系核心的Presenter通过EmployeePresenter表示。里面包含两个属性,一个代表View的只读属性IEmployeeView接口 的View,而另一个代表Model的只读属性EmployeeRepository对象的Repository,两个属性均在构造函数中初始化。

public class EmployeePresenter
    {
        public IEmployeeView View { get; private set; }
        public EmployeeRepository Repository { get; private set; }

        public EmployeePresenter(IEmployeeView view)
        {
            this.View = view;
            this.Repository = new EmployeeRepository();
            this.View.DepartmentSelected += OnDepartmentSelected;
        }

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

        protected void OnDepartmentSelected(object sender,  DepartmentSelectedEventArgs args)
        {
            string department = args.Department;
            var employees = this.Repository.GetEmployees(department);
            this.View.BindEmployees(employees);
        }
    }

我们在构造函数中注册了View的DepartmentSelected事件,作为事件处理器的OnDepartmentSelected方法通过调用Repository(即Model)得到了用户选择部门下的员工列表,并且绑定到了View上。

下面我们来看看View的Web页面。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
        <title>员工管理</title>
        <link rel="stylesheet" href="Content/bootstrap.css" />
        <link rel="stylesheet" href="Content/site.css" />
    </head>
    <body>
        <form id="form1" runat="server">
            <div id="page">
                <div class="text-center">
                    <asp:DropDownList ID="DropDownListDepartments" runat="server" CssClass="form-inline" />
                    <asp:Button ID="ButtonSearch" runat="server" Text="查询" OnClick="ButtonSearch_Click" CssClass="btn-primary" />
                </div>
                <asp:GridView ID="GridViewEmployees" runat="server" AutoGenerateColumns="false" Width="100%" CssClass="table table-bordered">
                    <Columns>
                        <asp:BoundField DataField="Name" HeaderText="姓名" />
                        <asp:BoundField DataField="Gender" HeaderText="性别" />
                        <asp:BoundField DataField="BirthDate" HeaderText="出生日期" DataFormatString="{0:dd/MM/yyyy}" />
                        <asp:BoundField DataField="Department" HeaderText="部门"/>
                    </Columns>
                </asp:GridView>
            </div>
        </form>
    </body>
</html>

下面是Web页面的后台代码定义,他实现了定义在IEmployeeView接口的方法和事件。

public partial class Default : System.Web.UI.Page, IEmployeeView
    {
        public EmployeePresenter Presenter { get; private set; }
        public event EventHandler<DepartmentSelectedEventArgs> DepartmentSelected;

        public Default()
        {
            this.Presenter = new EmployeePresenter(this);
        }

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

        protected void ButtonSearch_Click(object sender, EventArgs e)
        {
            string department = this.DropDownListDepartments.SelectedValue;
            DepartmentSelectedEventArgs eventArgs = new DepartmentSelectedEventArgs(department);
            if (null != DepartmentSelected)
            {
                DepartmentSelected(this, eventArgs);
            }
        }

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

        public void BindDepartments(IEnumerable<string> departments)
        {
            this.DropDownListDepartments.DataSource = departments;
            this.DropDownListDepartments.DataBind();
        }
    }
时间: 2024-10-09 08:26:22

学习ASP.NET MVC框架揭秘笔记-实例演示:SC模式的应用的相关文章

学习ASP.NET MVC框架揭秘笔记-PV与SC

1.                                   PV与SC 解决View难以测试最好的办法就是让他无须测试.如果View不需要测试,其先决条件就是让它尽可能不涉及UI处理逻辑,这就是PV模式的目的所在. 如果我们纯粹的采用PV模式来设计View意味着我们需要将View中的UI元素通过属性的形式暴露出来.具体来说,当我们为View定义接口的时候,需要定义基于UI元素的属性使Presenter可以对View进行细粒度操作,但这并不意味着我们直接将View上的控件暴露出来.

学习ASP.NET MVC框架揭秘笔记目录

学习ASP.NET MVC框架揭秘笔记目录 第一章     ASP.NET+MVC 1.1传统的MVC模式 持续更新中,,,,

学习ASP.NET MVC框架揭秘笔记-IIS/ASP.NET管道(一)

IIS/ASP.NET管道 ASP.NET MVC就是建立在ASP.NET平台基础上基于MVC模式的Web应用框架,深入理解ASP.NET MVC的前提是对ASP.NET管道式设计有深刻的认识.由于ASP.NET Web应用大都寄宿于IIS上,接下来会介绍3个主要的IIS版本对各自Web请求的处理方式. 1.3.1 IIS 5.x与ASP.NET IIS 5.x运行在进程InetInfo.exe中,该进程寄宿着一个名为World WideWeb Publishing Service(简称W3SV

学习ASP.NET MVC框架揭秘笔记-MVP

1.2.1                      MVP MVP是一种UI架构模式,适用于基于事件驱动的应用框架.MVP中的M和V分别对应MVC的Model和View,而P(Presenter)代替了Controller. 在MVP模式中,能够与Model直接进行交互的仅限于Presenter,View只能通过Presenter间接地调用Model.Model的独立性在这里得到真正的体现,他不仅仅与可视化元素的呈现无关,与UI处理逻辑(Presenter)也无关. MVP不仅仅避免了View

学习ASP.NET MVC框架揭秘笔记-传统MVC模式

1.1传统MVC模式 对于大部分面向最终用户的应用来说,他们都需要具有一个与用户进行交互的可视化UI界面,我们将这个UI称为视图(View).在早期,我们倾向于将所有与UI相关的操作糅合在一起,这些操作包括UI界面的呈现.用户交互操作的捕捉与响应.业务流程的执行及对数据的存取等,我们将这种设计模式称为自治视图(Autonomuous View  ,  AV). 1.1.1  自治视图 1.1.2  什么是MVC模式

学习ASP.NET MVC框架揭秘笔记-自治视图

1.1.1自治视图 一个典型的人机交互应用具有3个主要的关注点,既数据在可视化界面上的呈现.UI处理逻辑(用于处理用户交互式操作的逻辑)和业务逻辑.自治视图模式将三者混合在一起,势必会带来如下一些问题. 1.重用性.业务逻辑是与UI无关的,应该最大限度地被重用,但是若将业务逻辑定义在自治视图中相当于使他完全与视图本身绑定在一起.除此之外,如果我们能够将UI的行为抽象出来,基于抽象化UI的处理逻辑也是可以被共享的,但是定义在自治视图中的UI处理逻辑也完全丧失了重用的可能. 2.稳定性.业务逻辑具有

学习ASP.NET MVC框架揭秘笔记-什么是MVC模式

1.1.2什么是MVC模式 MVC的创建者是Trygve M.H.Reenskau,他是挪威的计算机专家,同时也是奥斯陆大学的名誉教授.MVC是他在1979年提出的一种主要针对GUI应用的软件架构模式. MVC体现了"关注点分离"这一基本的设计方针,他将一个人机交互应用设计的功能分为Model.Controller和View三部分,他们各自具有如下的职责. 1.Model是对应用状态和业务逻辑的封装,我们可以将它理解为同时包含数据和行为的领域模型.Model接受Controller的请

学习ASP.NET MVC框架揭秘笔记-IIS/ASP.NET管道(二)

IIS7.0与ASP.NET IIS7.0在请求的监听和分发机制上又进行了革新性的改进,主要体现在引入Window进程激活服务(Windows Process Activation Service,WAS)分流了原来(IIS6.0)W3SVC承载的部分功能.IIS6.0中W3SVC主要承载着如下三大功能. 1.HTTP请求接收:接收HTTP.SYS监听到的HTTP请求. 2.配置管理:从元数据库(metabase)中加载配置信息对相关组件进行配置. 3.进程管理:创建.回收.监控工作进程. II

学习ASP.NET MVC框架揭秘笔记-IIS/ASP.NET管道(三)

ASP.NET管道 以IIS6.0为例,它在工作进程w3wp.exe中会利用aspnet_isapi.dll加载.NET运行时(如果.NET运行时尚未加载).IIS6.0引入了应用程序进程池的概念,一个工作进程对应着一个应用程序池.一个应用程序进程池可以承载一个或者多个Web应用,每个Web应用映射到一个IIS虚拟目录.与IIS5.x一样,每一个Web应用运行在各自的应用程序域中. 如果HTTP.SYS接收到的HTTP请求是对该Web应用的第一次访问,在成功加载运行时后,IIS会通过AppDom