是否“只说,不问”? 适用于用户输入验证?

发布于 2024-07-13 15:56:00 字数 411 浏览 7 评论 0原文

这些年来我一定忽略了“告诉,不要问”OOP 原则,因为我几天前才第一次了解到它。

但上下文是关于验证代码的讨论,验证代码已从 ASP.NET Web 表单页面移出并移至数据/业务对象中,并且没有“Validate()”方法,只有一个本身执行验证和操作的保存方法(据说)提出了一个例外。 我问为什么要这样设计,我被引导到 OOP 的“告诉,不要问”原则,这是我从未听说过的,所以然后我们一起查看了 Google,我立即就受到了教育。 ;)

不过,有些东西听起来不太对劲,在数据从用户手中移交给业务层并在其中进行处理和/或收集之前,不应该对其进行清理,而不是相反? 我很困惑这如何能带来好的设计。

似乎“告诉,不要问”的规则属于这样的想法,即您不应该向目标对象询问目标对象的状态,并且该原则从未真正适用于传递的数据目标对象。

I somehow must have overlooked the "tell, don't ask" OOP principle all these years because I just learned about it a couple days ago for the first time.

But the context was a discussion about validation code that had been moved out of an ASP.NET web form page and into a data/business object, and there was no "Validate()" method, just a save method that itself did validation and (supposedly) raised an exception. I asked why this was designed in this way and I was directed to OOP's "tell, don't ask" principle, which I'd never heard of, so then we looked together at Google and I was immediately educated. ;)

Still, something doesn't smell right, shouldn't data be scrubbed before it gets handed off away from the user and into the business layer where it is processed and/or collected, rather than the other way around? I'm confused as to how this makes for good design.

It seems like the rule of "tell, don't ask" pertains to the idea that you shouldn't ask the target object about the target object's state, and that the principle was never really meant to apply to the data being passed to the target object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叹倦 2024-07-20 15:56:00

我认为这听起来像是一堆“最佳实践”和“设计方法”出了问题,但现在对我来说有点有意义。 这样看:

想象一下将验证放在业务对象中,但将“如果验证失败该怎么办”放在表示层中。这将允许多个不同的表示层重用相同的验证逻辑,但以不同的方式处理错误。

公共 Foo 
  { 
    验证(Baz 栏) 
    { 
        if(!is_number(bar)) 抛出 numberException(); 
    } 

    分配栏(Baz栏) 
    { 
        验证(栏); 
    } 
  } 


  //... 

  尝试 
  { 
    foo.AssignBar(bar); 
  } 
  catch(数字异常 e) 
  { 
    Alert('不是数字!'); 
  } 
  

注意,您可以对抛出异常进行争论,这只是一个例子。 返回状态、布尔值,无论你想要什么。

I thought it sounded like a load of "Best Practices" and "Design Methodologies" gone wrong, but now it kind of makes sense to me. Look at it this way:

Imagine putting validation in the Business Object, but the "what do I do if validation fails' in the presentation layer. This would allow multiple different presentation layers to reuse the same validation logic, but handle errors differently.

public Foo
{
  Validate(Baz bar)
  {
      if(!is_number(bar)) throw numberexception();
  }

  AssignBar(Baz bar)
  {
      Validate(bar);
  }
}


//...

try
{
  foo.AssignBar(bar);
}
catch(numberexception e)
{
  alert('Not a number!');
}

n.b. you can argue all you want about throwing exceptions, it was meant as an example. Return states, bools, whatever you want.

姐不稀罕 2024-07-20 15:56:00

我同意 AviewAview 的观点,但只有在用户告知时才会抛出异常(如果他询问则不会):

public Foo
{
  bool Validate(Baz bar)
  {
        if(!is_number(bar)) return false;
        return true;
  }

  AssignBar(Baz bar)
  {
        if (!Validate(bar)) throw numberexception();
  }
}

Tell:

try
{
  foo.AssignBar(bar);
}
catch(numberexception e)
{
  alert('Not a number!');
}

Ask:

if (foo.Validate(bar)
{
  foo.AssignBar(bar);
}
else
{
  alert('Not a number!');
}

所以,AssignBar 期望一个 VALID bar,如果不是,则抛出异常,但我们还提供了一个 Validate 方法,该方法不会不抛出异常。

I agree with AviewAview, but would only throw exceptions if the user tells (not if he asks):

public Foo
{
  bool Validate(Baz bar)
  {
        if(!is_number(bar)) return false;
        return true;
  }

  AssignBar(Baz bar)
  {
        if (!Validate(bar)) throw numberexception();
  }
}

Tell:

try
{
  foo.AssignBar(bar);
}
catch(numberexception e)
{
  alert('Not a number!');
}

Ask:

if (foo.Validate(bar)
{
  foo.AssignBar(bar);
}
else
{
  alert('Not a number!');
}

So AssignBar expects a VALID bar and throws an exception if it is not, but we also provide a method to Validate which does not throw an exception.

离去的眼神 2024-07-20 15:56:00

我想知道这是否更多的是“关注点分离”而不是“告诉而不询问”的问题。 验证数据由谁负责? 可以说,它是负责持久化的东西。

当然,有时验证多层数据很有用。 如果您的应用程序属于这种情况,那么我在“用户”层中公开验证逻辑没有问题。 但我仍然希望它在业务层。

I wonder if this is more an issue of "separation of concerns" than "tell don't ask". Whose responsibility is it to validate the data? Arguably, it's the thing responsible for persisting it.

Of course, sometimes it's useful to validate the data in multiple layers. If this is the case for your app, I have no problem with exposing the validation logic in the "user" layer. But I would still want it in the business layer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文