Model view controller 这段代码的MVC版本是什么?
我正试图将我的头脑集中在如何对代码进行企业化上:使用一个简单的例程,并将其拆分为3或4个类中的5或6个方法 我很快想出了三个简单的代码示例,说明了我目前是如何编写它的。有人能把这些转换成MVC/MVP模糊版本吗Model view controller 这段代码的MVC版本是什么?,model-view-controller,language-agnostic,design-patterns,Model View Controller,Language Agnostic,Design Patterns,我正试图将我的头脑集中在如何对代码进行企业化上:使用一个简单的例程,并将其拆分为3或4个类中的5或6个方法 我很快想出了三个简单的代码示例,说明了我目前是如何编写它的。有人能把这些转换成MVC/MVP模糊版本吗 示例1:姓氏是必填项。如果未输入任何内容,则将文本框涂成红色。如果输入了内容,则将其涂成绿色: private void txtLastname_TextChanged(object sender, EventArgs e) { //Lastname mandatory.
示例1:姓氏是必填项。如果未输入任何内容,则将文本框涂成红色。如果输入了内容,则将其涂成绿色:
private void txtLastname_TextChanged(object sender, EventArgs e)
{
//Lastname mandatory.
//Color pinkish if nothing entered. Greenish if entered.
if (txtLastname.Text.Trim() == "")
{
//Lastname is required, color pinkish
txtLastname.BackColor = ControlBad;
}
else
{
//Lastname entered, remove the coloring
txtLastname.BackColor = ControlGood;
}
}
示例2:名字是可选的,但是尝试获取它。我们将在“尝试获取”字段中添加蓝色色调:
例3年龄完全是可选的。如果输入了年龄,则该年龄最好有效:
private void txtAge_TextChanged(object sender, EventArgs e)
{
//Age is optional, but if entered it better be valid
int nAge = 0;
if (Int32.TryParse(txtAge.Text, out nAge))
{
//Valid integer entered
if (nAge < 0)
{
//Negative age? i don't think so
txtAge.BackColor = ControlBad;
}
else
{
//Valid age entered, remove coloring
txtAge.BackColor = SystemColors.Window;
}
}
else
{
//Whatever is in there: it's *not* a valid integer,
if (txtAge.Text == "")
{
//Blank is okay
txtAge.BackColor = SystemColors.Window;
}
else
{
//Not a valid age, bad user
txtAge.BackColor = ControlBad;
}
}
}
我已经把代码弄糊涂了,但它仍然是完整的。我想MVC混淆的下一步是将代码隐藏在3或4个不同的文件中
这是我不明白的下一步。哪些函数被移入哪些其他类的逻辑分隔是什么?有人能把我上面3个简单的例子翻译成成熟的MVC混淆吗
编辑:不是ASP/ASP.NET/Online。假装它在桌面、手持设备、表面、信息亭上。并假设它与语言无关。您在代码中所做的大部分工作都属于控制器类,因为它描述了逻辑。您的视图应该只描述UI,并提供对UI组件的轻松访问。模型类应该描述您的数据模型 想法很简单:控制器做一切,但它必须了解视图和模型。例如,当视图初始化时,控制器设置所有逻辑(类似于您已经在做的事情)。当模型分配给控制器时-它将值设置到适当的UI控件中,并执行相同的操作来检索数据并返回is As模型
因此,基本上,您将数据模型类交给控制器,它进行编辑并再次以模型类的形式返回数据 如果可能的话,在经典ASP.NET中很难遵循MVC,所以我将基于MVP进行回复 在第一个示例中,您正在尝试进行验证。验证姓氏是演示者的责任。将字段显示为红色是视图的责任。因此,您的视图类如下所示:
private void Page_Load()
{
this._presenter = new Presenter();
}
private void txtLastname_TextChanged(object sender, EventArgs e)
{
txtLastName.BackColor = presenter.IsLastnameValid(txtLastName.Text) ?
ControlGood : ControlBad;
}
public Presenter()
{
public bool IsLastNameValid(string lastname)
{
return string.IsNullOrEmpty(lastname);
}
}
class Controller
{
// This is the model we are operating on
private Model model_;
public enum Status
{
Normal,
Required,
Good,
Bad
}
public delegate void FirstNameStatusChangedDelegate(Status newStatus);
public event FirstNameStatusChangedDelegate FirstNameStatusChangedEvent;
public string FirstName
{
get { return model_.FirstName; }
set
{
if (value == "")
RaiseFirstNameStatusChanged(Status.Required);
else if ( value.Trim() == "" )
RaiseFirstNameStatusChanged(Status.Bad);
else
{
model_.FirstName = value;
RaiseFirstNameStatusChanged(Status.Normal);
}
}
}
private void RaiseFirstNameStatusChanged(Status newStatus)
{
if ( FirstNameStatusChangedEvent != null )
FirstNameStatusChangedEvent(newStatus);
}
}
public partial class Dinner {
public bool IsValid {
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations() {
yield break;
}
public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title is required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description is required", "Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy is required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address is required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country is required", "Address");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# is required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}
partial void OnValidate(ChangeAction action) {
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
您的presenter类应该是这样的:
private void Page_Load()
{
this._presenter = new Presenter();
}
private void txtLastname_TextChanged(object sender, EventArgs e)
{
txtLastName.BackColor = presenter.IsLastnameValid(txtLastName.Text) ?
ControlGood : ControlBad;
}
public Presenter()
{
public bool IsLastNameValid(string lastname)
{
return string.IsNullOrEmpty(lastname);
}
}
class Controller
{
// This is the model we are operating on
private Model model_;
public enum Status
{
Normal,
Required,
Good,
Bad
}
public delegate void FirstNameStatusChangedDelegate(Status newStatus);
public event FirstNameStatusChangedDelegate FirstNameStatusChangedEvent;
public string FirstName
{
get { return model_.FirstName; }
set
{
if (value == "")
RaiseFirstNameStatusChanged(Status.Required);
else if ( value.Trim() == "" )
RaiseFirstNameStatusChanged(Status.Bad);
else
{
model_.FirstName = value;
RaiseFirstNameStatusChanged(Status.Normal);
}
}
}
private void RaiseFirstNameStatusChanged(Status newStatus)
{
if ( FirstNameStatusChangedEvent != null )
FirstNameStatusChangedEvent(newStatus);
}
}
public partial class Dinner {
public bool IsValid {
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations() {
yield break;
}
public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title is required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description is required", "Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy is required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address is required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country is required", "Address");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# is required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}
partial void OnValidate(ChangeAction action) {
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
姓是你的模特儿
请注意,我准备这些课程只是为了展示如何形成MVP结构。在现实世界中,有很多更好的验证方法。通常情况下,您会在业务中使用这种方法,而不是验证。我在为Windows窗体实现MVC时的主要想法是,我希望对我的模型和控制器进行单元测试。为了实现这一点,我的控制器不应该知道关于使用它的视图的任何信息,因此任何应该在UI级别处理的通知都被实现为事件。在您的示例中,我的控制器如下所示:
private void Page_Load()
{
this._presenter = new Presenter();
}
private void txtLastname_TextChanged(object sender, EventArgs e)
{
txtLastName.BackColor = presenter.IsLastnameValid(txtLastName.Text) ?
ControlGood : ControlBad;
}
public Presenter()
{
public bool IsLastNameValid(string lastname)
{
return string.IsNullOrEmpty(lastname);
}
}
class Controller
{
// This is the model we are operating on
private Model model_;
public enum Status
{
Normal,
Required,
Good,
Bad
}
public delegate void FirstNameStatusChangedDelegate(Status newStatus);
public event FirstNameStatusChangedDelegate FirstNameStatusChangedEvent;
public string FirstName
{
get { return model_.FirstName; }
set
{
if (value == "")
RaiseFirstNameStatusChanged(Status.Required);
else if ( value.Trim() == "" )
RaiseFirstNameStatusChanged(Status.Bad);
else
{
model_.FirstName = value;
RaiseFirstNameStatusChanged(Status.Normal);
}
}
}
private void RaiseFirstNameStatusChanged(Status newStatus)
{
if ( FirstNameStatusChangedEvent != null )
FirstNameStatusChangedEvent(newStatus);
}
}
public partial class Dinner {
public bool IsValid {
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations() {
yield break;
}
public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title is required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description is required", "Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy is required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address is required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country is required", "Address");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# is required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}
partial void OnValidate(ChangeAction action) {
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
该视图将为FirstNameStatusChanged
事件提供处理程序:
class View : Form
{
private Controller controller_;
private static readonly Dictionary<Controller.Status, Color> statusColors_ = new Dictionary<Controller.Status, Color>
{
{Controller.Status.Normal, SystemColors.Window},
{Controller.Status.Required, ControlRequired},
{Controller.Status.Good, ControlGood},
{Controller.Status.Bad, ControlRed}
};
public View(Controller controller)
{
InitializeComponent();
controller_ = controller;
contoller_.FirstNameStatusChangedEvent += OnFirstNameStatusChanged;
}
private void txtFirstname_TextChanged(object sender, EventArgs e)
{ controller_.FirstName = txtFirstName.Text; }
private void OnFirstNameStatusChanged(Controller.Status newStatus)
{ txtFirstName.BackColor = statusColors_[newStatus]; }
}
类视图:表单
{
专用控制器;
私有静态只读字典statusColors\uux=新字典
{
{Controller.Status.Normal,SystemColors.Window},
{Controller.Status.Required,ControlRequired},
{Controller.Status.Good,ControlGood},
{Controller.Status.Bad,ControlRed}
};
公共视图(控制器)
{
初始化组件();
控制器=控制器;
contoller_u2;.FirstNameStatusChangedEvent+=OnFirstNameStatusChanged;
}
私有void txtFirstname_TextChanged(对象发送方,事件参数e)
{controller_u.FirstName=txtFirstName.Text;}
私有void OnFirstNameStatusChanged(Controller.Status newStatus)
{txtFirstName.BackColor=statusColors_u[newStatus];}
}
MVC/MVP模式的目的不是混淆,而是。混淆是指(隐藏)通信中的预期含义,使通信变得混乱、故意模棱两可,并且更难解释。模式的使用是为了使代码更清晰,更易于理解。我建议你从阅读和上的维基百科条目开始
这两种模式都是对代码进行结构化的方法,以便将应用程序分解为具有明确定义的交互边界的元素,以实现特定目的。在应用程序的各个类中,没有专门针对业务关注点、输入/输出处理和表示的代码,而是在各个体系结构组件中分离和隔离这些关注点。这些体系结构元素通过交互边界(接口)彼此隔离,使它们彼此更加独立,更易于修改,而不会影响整个应用程序 伊恩
如果希望立即验证控件,则需要使用javascript或jQuery。对于经典的ASP.NET也是如此。由于您使用的是代码隐藏方法,因此我假设您的验证将等待回发
以下示例来自NerdDinner项目。NerdDinner是一个开源项目,它是ASP.NET MVC体系结构的一个示例。作者们慷慨地提供了一个教程,可在
在ASP.NET MVC中提交表单时,表单作为FormCollection对象进入相应的控制器:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {
Dinner dinner = dinnerRepository.GetDinner(id);
try
{
UpdateModel(dinner);
dinnerRepository.Save();
}
catch
{
ModelState.AddModelErrors(dinner.GetRuleViolations())
}
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
UpdateModel接受表单值并尝试将它们填充到晚餐对象中。晚餐对象如下所示:
private void Page_Load()
{
this._presenter = new Presenter();
}
private void txtLastname_TextChanged(object sender, EventArgs e)
{
txtLastName.BackColor = presenter.IsLastnameValid(txtLastName.Text) ?
ControlGood : ControlBad;
}
public Presenter()
{
public bool IsLastNameValid(string lastname)
{
return string.IsNullOrEmpty(lastname);
}
}
class Controller
{
// This is the model we are operating on
private Model model_;
public enum Status
{
Normal,
Required,
Good,
Bad
}
public delegate void FirstNameStatusChangedDelegate(Status newStatus);
public event FirstNameStatusChangedDelegate FirstNameStatusChangedEvent;
public string FirstName
{
get { return model_.FirstName; }
set
{
if (value == "")
RaiseFirstNameStatusChanged(Status.Required);
else if ( value.Trim() == "" )
RaiseFirstNameStatusChanged(Status.Bad);
else
{
model_.FirstName = value;
RaiseFirstNameStatusChanged(Status.Normal);
}
}
}
private void RaiseFirstNameStatusChanged(Status newStatus)
{
if ( FirstNameStatusChangedEvent != null )
FirstNameStatusChangedEvent(newStatus);
}
}
public partial class Dinner {
public bool IsValid {
get { return (GetRuleViolations().Count() == 0); }
}
public IEnumerable<RuleViolation> GetRuleViolations() {
yield break;
}
public IEnumerable<RuleViolation> GetRuleViolations() {
if (String.IsNullOrEmpty(Title))
yield return new RuleViolation("Title is required", "Title");
if (String.IsNullOrEmpty(Description))
yield return new RuleViolation("Description is required", "Description");
if (String.IsNullOrEmpty(HostedBy))
yield return new RuleViolation("HostedBy is required", "HostedBy");
if (String.IsNullOrEmpty(Address))
yield return new RuleViolation("Address is required", "Address");
if (String.IsNullOrEmpty(Country))
yield return new RuleViolation("Country is required", "Address");
if (String.IsNullOrEmpty(ContactPhone))
yield return new RuleViolation("Phone# is required", "ContactPhone");
if (!PhoneValidator.IsValidNumber(ContactPhone, Country))
yield return new RuleViolation("Phone# does not match country", "ContactPhone");
yield break;
}
partial void OnValidate(ChangeAction action) {
if (!IsValid)
throw new ApplicationException("Rule violations prevent saving");
}
}
公共部分课堂晚餐{
公共布尔是有效的{
获取{return(GetRuleViolations().Count()==0);}
}
公共IEnumerable GetRuleViolations(){
屈服断裂;
}
公共IEnumerable GetRuleViolations(){
if(String.IsNullOrEmpty(Title))
收益-收益-新规则违反