你如何通信服务层消息/错误给高层使用MVP? [英] How Do You Communicate Service Layer Messages/Errors to Higher Layers Using MVP?

查看:110
本文介绍了你如何通信服务层消息/错误给高层使用MVP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在写从UI下一个ASP.Net应用程序。我实现一个MVP的架构,因为我生病的WinForms和想要的东西,不得不关注一个更好的分离。

I'm currently writing an ASP.Net app from the UI down. I'm implementing an MVP architecture because I'm sick of Winforms and wanted something that had a better separation of concerns.

因此​​,与MVP的presenter处理由视图引发的事件。下面是一些code,我在地方应对创建用户:

So with MVP, the Presenter handles events raised by the View. Here's some code that I have in place to deal with the creation of users:

public class CreateMemberPresenter
{
    private ICreateMemberView view;
    private IMemberTasks tasks;

    public CreateMemberPresenter(ICreateMemberView view) 
        : this(view, new StubMemberTasks())
    {
    }

    public CreateMemberPresenter(ICreateMemberView view, IMemberTasks tasks)
    {
        this.view = view;
        this.tasks = tasks;

        HookupEventHandlersTo(view);
    }

    private void HookupEventHandlersTo(ICreateMemberView view)
    {
        view.CreateMember += delegate { CreateMember(); };
    }

    private void CreateMember()
    {
        if (!view.IsValid)
            return;

        try
        {
            int newUserId;
            tasks.CreateMember(view.NewMember, out newUserId);
            view.NewUserCode = newUserId;
            view.Notify(new NotificationDTO() { Type = NotificationType.Success });
        }
        catch(Exception e)
        {
            this.LogA().Message(string.Format("Error Creating User: {0}", e.Message));
            view.Notify(new NotificationDTO() { Type = NotificationType.Failure, Message = "There was an error creating a new member" });
        }
    }
}

我已经使用内置的.Net验证控件我的主要形式验证完成,但现在我需要验证数据充分满足标准的服务层。

I have my main form validation done using the built in .Net Validation Controls, but now I need to verify that the data sufficiently satisfies the criteria for the Service Layer.

假设下面的服务层信息可以显示出来:

Let's say the following Service Layer messages can show up:


  • 电子邮件帐户已经存在(失败)

  • 进入不存在。参见用户(失败)

  • 密码长度超过数据存储允许长度(失败)

  • 会员创建成功(成功)

让我们也说,更多的规则将在服务层,该UI无法预见。

Let's also say that more rules will be in the service layer that the UI cannot anticipate.

目前我在服务层抛出一个异常,如果事情没有按计划去了。是的一个充分的战略?这是否code气味你们?如果我写了这样一个服务层,你会在无需编写以这种方式使用presenters被惹恼了?返回codeS显得过于老派和布尔是不够翔实。

Currently I'm having the service layer throw an exception if things didn't go as planned. Is that a sufficent strategy? Does this code smell to you guys? If I wrote a service layer like this would you be annoyed at having to write Presenters that use it in this way? Return codes seem too old school and a bool is just not informative enough.

修改不是由OP:在后续评论认为合并是由OP

Cheekysoft,我喜欢ServiceLayerException的概念。我已经有,我没有预料到异常的全局异常模块。你觉得让这些自定义异常繁琐?我在想,追赶基Exception类是有点臭,但并不完全知道如何进步从那里。


Cheekysoft, I like the concept of a ServiceLayerException. I already have a global exception module for the exceptions that I don't anticipate. Do you find making all these custom exceptions tedious? I was thinking that catching base Exception class was a bit smelly but wasn't exactly sure how progress from there.

tgmdbm,我喜欢巧妙地利用了拉姆达前pression那里!

tgmdbm, I like the clever use of the lambda expression there!

感谢Cheekysoft的跟进。所以我猜测这将是该策略,如果你不介意的用户显示一个单独的页面(我主要是Web开发人员),如果异常没有被处理。

Thanks Cheekysoft for the follow-up. So I'm guessing that would be the strategy if you don't mind the user being displayed a separate page (I'm primarily a web developer) if the Exception is not handled.

不过,如果我想在用户提交了导致错误的数据相同观点返回错误信息,我将不得不赶在presenter例外?

However, if I want to return the error message in the same view where the user submitted the data that caused the error, I would then have to catch the Exception in the Presenter?

下面是什么CreateUserView样子时presenter已经处理了ServiceLayerException:

Here's what the CreateUserView looks like when the Presenter has handled the ServiceLayerException:

对于这种类型的错误,它是很好的报告给了同样的观点。

For this kind of error, it's nice to report it to the same view.

不管怎么说,我认为我们将超出我原来的问题的范围了。我会玩弄你贴什么,如果我需要进一步的细节我会发布一个新的问题。

Anyways, I think we're going beyond the scope of my original question now. I'll play around with what you've posted and if I need further details I'll post a new question.

推荐答案

这听起来正好给我。例外的是preferable,因为他们可以从任何地方的服务层内被抛起到服务层的顶部,不管嵌套在服务方法实现内部有多深它是。如你所知调用presenter总是会得到这个问题的通知,这样可以使服务code干净。

That sounds just right to me. Exceptions are preferable as they can be thrown up to the top of the service layer from anywhere inside the service layer, no matter how deeply nested inside the service method implementation it is. This keeps the service code clean as you know the calling presenter will always get notification of the problem.

不要捕捉异常

不过,别在presenter牛逼catch异常,我知道它诱人的,因为它保持code短,但你需要捕捉特定的例外避免受凉系统级的异常。

However, don't catch Exception in the presenter, I know its tempting because it keeps the code shorter, but you need to catch specific exceptions to avoid catching the system-level exceptions.

规划一个简单的异常层次结构

如果你打算以这种方式使用异常,你应该设计一个异常层次结构为自己的异常类。
在minumum创建一个ServiceLayerException类和投掷其中一个在你的服务方法时出现问题。然后,如果你需要抛出应当/可以通过不同的presenter处理的异常,可以抛出ServiceLayerException的一个具体子类:说,AccountAlreadyExistsException

If you are going to use exceptions in this way, you should design an exception hierarchy for your own exception classes. At a minumum create a ServiceLayerException class and throw one of these in your service methods when a problem occurs. Then if you need to throw an exception that should/could be handled differently by the presenter, you can throw a specific subclass of ServiceLayerException: say, AccountAlreadyExistsException.

您presenter再有这样做的选项

Your presenter then has the option of doing

try {
  // call service etc.
  // handle success to view
} 
catch (AccountAlreadyExistsException) {
  // set the message and some other unique data in the view
}
catch (ServiceLayerException) {
  // set the message in the view
}
// system exceptions, and unrecoverable exceptions are allowed to bubble 
// up the call stack so a general error can be shown to the user, rather 
// than showing the form again.

在自己的异常类使用继承意味着你不需要赶在presenter multipile例外 - 你可以,如果有必要 - 你最终不会意外捕获异常你不能处理。如果你的presenter已经在调用堆栈的顶部,添加一个catch(异常)块以不同的观点来处理系统错误。

Using inheritance in your own exception classes means you are not required to catch multipile exceptions in your presenter -- you can if there's a need to -- and you don't end up accidentally catching exceptions you can't handle. If your presenter is already at the top of the call stack, add a catch( Exception ) block to handle the system errors with a different view.

我总是尝试和思考我的服务层作为一个单独的可分配库,并抛出具体异常的是有道理的。它是那么到presenter /控制器/远程服务实现,以决定是否需要担心的具体细节,或者只是把问题作为一个一般性的错误。

I always try and think of my service layer as a seperate distributable library, and throw as specific an exception as makes sense. It is then up to the presenter/controller/remote-service implementation to decide if it needs to worry about the specific details or just to treat problems as a generic error.

这篇关于你如何通信服务层消息/错误给高层使用MVP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆