惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
Y
Y Combinator Blog
Recorded Future
Recorded Future
博客园 - Franky
I
InfoQ
T
The Blog of Author Tim Ferriss
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园_首页
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
雷峰网
雷峰网
P
Palo Alto Networks Blog
G
GRAHAM CLULEY
Cloudbric
Cloudbric
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Check Point Blog
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
U
Unit 42
N
Netflix TechBlog - Medium
The Cloudflare Blog
Spread Privacy
Spread Privacy
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
T
Troy Hunt's Blog
Engineering at Meta
Engineering at Meta
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tenable Blog
B
Blog
S
Securelist
H
Hacker News: Front Page
Google Online Security Blog
Google Online Security Blog
G
Google Developers Blog

博客园 - 踏踏实实干

asp.net MVC4 框架揭秘 读书笔记系列3 asp.net MVC4 框架揭秘 读书笔记系列1 什么?你还不会写JQuery 插件 jQuery命名空间,插件开发 微信开发资源 jstree 从简单说起Jquery 插件应用说明 sync framework参考收集系列 收集一些.net 组件开发资源 (转) c# 调用SQL Server存储过程返回值(转) C#事务 访问数据库(转) 多库查询 sp_addlinkedserver使用方法(添加链接服务器)(转)片段整理 asp.net 动态数据网站简单应用,快速建立站点实现对库方便的增删改 利用asp.net路由实现url解析 智能客户端(Smart Client )中文文档及案例(转贴) 利用反射对对象属性赋值取值操作 男人30而立,30岁的男人喊起来!你们立了吗? jquery 实现从左边listbox选择至右边listbox asp.net 造成seesion 丢失的问题之一 转摘 JQUERY操作JSON例子
asp.net MVC4 框架揭秘 读书笔记系列2
踏踏实实干 · 2015-01-05 · via 博客园 - 踏踏实实干

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


    }