试图只使用一个方法名称

时间:2009-10-14 20:35:31

标签: java php oop

当我在PHP中编写Form Validator时,在创建新方法时,我需要增加旧方法中的参数数量。

当我学习Java时,当我读到扩展是为了不接触以前测试过的工作代码时,我认为我不应该增加旧方法中的参数数量,而是用新方法覆盖旧方法

想象一下,如果您要验证表单的某个部分,另一部分以及另一部分中的字段是否为空。

如果参数不同,你将重载isEmpty,但是,如果参数相等,是否正确使用isEmpty,isEmpty2,isEmpty3,每个类有三个类和一个isEmpty,如果两者都错,那么应该是什么我做过吗?

5 个答案:

答案 0 :(得分:1)

所以问题是:

如果对于接收相同数字参数的方法isEmpty我需要不同的行为,我该怎么办?

  1. 使用不同的名字? (isEmpty,isEmpty2,isEmpty3)
  2. 使用一个isEmpty方法有三个类吗?
  3. 其他
  4. 如果这是问题那么我认为你应该使用:

    1. 当它们属于同一个逻辑单元(它们具有相同类型的验证)但不使用数字作为版本时,最好在它们执行后命名它们:isEmptyUser,{ {1}},isEmptyAddress

    2. 验证器对象可以在一个地方计算并在程序生命周期中传递。让我们说:isEmptyWhatever然后将其用作:Validator v = Validator.getInstance( ... );并让多态性为它的工作。

    3. 或者你可以将参数打包在一个类中并将其传递给validator.isEmpty()方法,尽管你最终会遇到几乎相同的名称问题。从那里重构更容易,让新类为你做验证。

      isEmpty

答案 1 :(得分:1)

开放/封闭原则[通常归因于Bertrand Meyer]说“软件实体(类,模块,功能等)应该是可以扩展的,但是关闭以进行修改”。这可能是您在Java时代遇到的原则。在现实生活中,这适用于已完成的代码,其中修改,重新测试和重新认证的成本超过了通过直接更改获得的简单性的好处。

如果要更改方法,因为它需要一个额外的参数,您可以选择使用以下步骤:

  1. 复制旧方法。
  2. 从副本中删除实现。
  3. 更改原始方法的签名以添加新参数。
  4. 更新原始方法的实现以使用新参数。
  5. 根据参数的默认值,使用新方法实现副本。
  6. 如果您的实现语言不支持方法重载,那么原理是相同的,但您需要为新方法签名找到新名称。

    这种方法的优点是您已将新参数添加到方法中,并且您现有的客户端代码将继续编译并运行。

    如果新参数有明显的默认值,那么效果很好,如果不存在则不太好。

答案 2 :(得分:0)

  1. 从java 5开始,您可以使用void foo(Object ... params)
  2. 中的变量参数列表
  3. 您需要为您的方法提供创意名称,因为您不能重载具有相同类型和数量的参数(或基于返回类型)的方法。事实上,我个人更喜欢这种超载。所以你可以拥有isEmpty和isEmptyWhenFoo以及isEmptyWhenIHaveTheseArguments(好吧meybe不是最后一个:)

答案 3 :(得分:0)

不确定这是否真的回答了你的问题,但在“现实生活”中思考OO的最佳方式是考虑Nygaard Classification

  

ObjectOrientedProgramming。程序执行被视为一个物理模型,模拟世界的真实或虚构部分的行为。

那么你将如何构建一个物理设备来完成你在代码中尝试做的事情?您可能有某种“Form”对象,并且表单对象将有少量选项卡或位连接到它以表示不同的Form变量,然后您将构建一个Validator对象,该对象将把Form对象放在一个槽中然后如果表单有效则闪烁一盏灯,如果表单无效则闪烁另一盏灯。或者你的Validator可以在一个槽中取一个Form对象并返回一个Form对象(可能是同一个),但是以各种方式修改(只有Validator才能理解)以使其“有效”。或者,验证者可能是表格的部分,因此表格中有这个验证者的东西,它会突然出现......

我的观点是,试着想象一下这样的机器会是什么样子以及它是如何工作的。然后考虑该机器的所有部件,并使每个部件成为一个对象。这就是“面向对象”事物在“现实生活”中的作用,对吗?

话虽如此,“扩展”一个类是什么意思?好吧,类是对象的“模板” - 每个对象实例都是通过从类构建它来实现的。子类只是一个从父类“继承”的类。至少在Java中,有两种继承:接口继承和实现继承。在Java中,您可以一次从最多一个类继承实现(实际方法代码),但是您可以继承许多接口 - 这些接口基本上只是某人可以从您的类外部看到的属性集合。

另外,考虑OO编程的一种常见方式是考虑“消息”而不是“方法调用”(事实上,这是Alan Kay为Smalltalk发明的原始术语,这是第一种实际上是称为“面向对象”)。因此,当您向对象发送isEmpty消息时,您希望它如何响应?您是否希望能够使用isEmpty消息发送不同的参数并使其响应不同?或者您想将isEmpty消息发送到不同的对象并让它们以不同的方式响应?两者都是合适的答案,具体取决于代码的设计。

答案 4 :(得分:0)

相反,让一个类提供多个版本的isEmpty具有不同的名称,尝试将模型分解为更精细的部分,可以更灵活的方式组合在一起。

  • 创建一个名为Empty with的界面 一个方法isEmpty(String value);
  • 创建此实现 像EmptyIgnoreWhiteSpace这样的界面 和EmptyIgnoreZero
  • 创建FormField 具有验证方法的类 委托给实现的 空。
  • 您的表单对象将具有 FormField的实例将会 知道如何验证自己。

现在你有很大的灵活性,你可以结合使用Empty实现类来创建像EmptyIgnoreWhiteSpaceAndZero这样的新类。您可以在与表单字段验证无关的其他地方使用它们。 您没有多种类似命名的方法来污染您的对象模型。