OO上的JavaWorld:Getters / Setters vs Builder [英] JavaWorld on OO: Getters/Setters vs Builder

查看:142
本文介绍了OO上的JavaWorld:Getters / Setters vs Builder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现这篇文章,其中Allen Holub解释了Getters / Setters的替代方法,它保留了隐藏对象实现的原则(他的示例代码可以也可以在下面找到。)

I found this article on JavaWorld, where Allen Holub explains an alternative to Getters/Setters that maintains the principle that the implementation of an object should be hidden (his example code can also be found below).

它解释了类名称 / EmployeeId / Money 应该有一个构造函数接受一个字符串 - 原因是如果你输入一个 int ,稍后需要将其更改为 long ,您将不得不修改该类的所有用途,并且您不必使用此模式。

It is explained that the classes Name/EmployeeId/Money should have a constructor taking a single string - the reasoning is that if you type it as an int, and later need to change it to a long, you will have to modify all the uses of the class, and with this pattern you don't have to.

我想知道:这不是简单地将问题转移到解析抛出的 String 参数?例如,如果所有使用 EmployeeId 的代码(从 Exporter 收到)解析字符串进入 int ,然后突然开始导出 long 值,需要修改正如许多用途一样......如果你开始将其解析为 long ,它可能必须改为 double (即使这对id没有意义)......如果你不能确定将 String 解析成什么,你就不能实现任何东西

I was wondering: doesn't this simply move the problem to the parsing of the String parameters being tossed about? For example, if all the code using the EmployeeId (received from the Exporter) parses the String into an int, and suddenly you start exporting long values, you need to modify exactly as many uses... and if you start out parsing it as a long it might well have to change to a double (even though that makes no sense for id's)... and if you can't be sure what to parse the String into, you can't implement anything.

除了这个问题,我还有另外一个:我意识到这篇文章已经超过七年了,所以有人能指出我最近关于OO设计的一些概述,特别是关于getter / setter和实现隐藏辩论的想法吗?

Besides this question, I have another: I realise that the article is over seven years old, so could anyone point me to some recent overviews concerning OO-design, and specifically to ideas concerning the getter/setter and implementation hiding debate?

  public class Employee
  {   private Name        name;
      private EmployeeId  id;
      private Money       salary;

      public interface Exporter
      {   void addName    ( String name   );
          void addID      ( String id     );
          void addSalary  ( String salary );
      }

      public interface Importer
      {   String provideName();
          String provideID();
          String provideSalary();
          void   open();
          void   close();
      }

      public Employee( Importer builder )
      {   builder.open();
          this.name   = new Name      ( builder.provideName()     );
          this.id     = new EmployeeId( builder.provideID()       );
          this.salary = new Money     ( builder.provideSalary(),
                                    new Locale("en", "US") );
          builder.close();
      }

      public void export( Exporter builder )
      {   builder.addName  ( name.toString()   );
          builder.addID    ( id.toString()     );
          builder.addSalary( salary.toString() );
      }

      //...
  }


推荐答案

问题1
字符串解析看起来很奇怪。恕我直言,你只能做很多事情来预测未来的增强功能。您可以从一开始就使用 long 参数,或者考虑稍后添加其他构造函数。或者,您可以引入可扩展的参数类。见下文。

Question 1: String parsing seems strange. IMHO you can only do so much to anticipate future enhancements. Either you use a long parameter right from the start to be sure, or consider adding additional constructors later. Alternatively you can introduce an extensible parameter class. See below.

问题2
有几种方案可以使用构建器模式。

Question 2: There are several scenarios in which the builder pattern can be useful.


  • 复杂对象创建

  • Complex Object creation

当你处理非常复杂的对象时,有很多属性
,你最好只在对象创建时设置一次,用
常规构造函数执行此操作可能会变得难以阅读,因为构造函数
有很长的参数列表。将此作为API发布并不是好的样式
,因为每个人都必须仔细阅读文档,并确保
他们不会混淆参数。

When you are dealing with very complex object that have lots of properties that you would preferably only set once at object creation, doing this with regular constructors can become hard to read, because the constructor will have a long list of parameters. Publishing this as an API is not good style because everyone will have to read the documentation carefully and make sure they do not confuse parameters.

相反,当你提供一个构建器时,只需要处理带有所有参数的(私有)
构造函数,但是你的类的消费者可以使用更加可读的单个方法。

Instead when you offer a builder, only you have to cope with the (private) constructor taking all the arguments, but the consumers of your class can use much more readable individual methods.

Setter不是一回事,因为它们允许你在创建对象后更改对象
属性。

Setters are not the same thing, because they would allow you to change object properties after its creation.

可扩展API

当你只为你的类发布一个多参数构造函数时,后来
决定你需要添加一个新的(可选)属性(比如说)在你的软件的更高版本中)
你必须创建一个与第一个相同的第二个构造函数,但是
需要多一个参数。否则 - 如果你只是将它添加到现有的
构造函数中 - 你将破坏与现有代码的兼容性。

When you only publish a multi-parameter constructor for your class and later decide you need to add a new (optional) property (say in a later version of your software) you have to create a second constructor that is identical to the first one, but takes one more parameter. Otherwise - if you were to just add it to the existing constructor - you would break compatibility with existing code.

使用构建器,你只需添加一个新的新属性的方法,所有现有的
代码仍然兼容。

With a builder, you simply add a new method for the new property, with all existing code still being compatible.

Immutability

Immutability

软件开发强烈倾向于并行执行
多线程。在这种情况下,最好使用在创建后不能修改
的对象(不可变对象),因为这些
不会导致来自多个线程的并发更新问题。这是
为什么setter不是一个选项。

Software development is strongly trending towards parallel execution of multiple threads. In such scenarios it is best to use objects that cannot be modified after they have been created (immutable objects), because these cannot cause problems with concurrent updates from multiple threads. This is why setters are not an option.

现在,如果你想避免多参数公共构造函数的问题,
那个留下建设者是一个非常方便的选择。

Now, if you want to avoid the problems of the multi-parameter public constructors, that leaves builders as a very convenient alternative.

可读性(流利API)

基于构建器API可以非常容易阅读,如果构建器的方法是巧妙命名的
,你可以使用几乎像英语句子的代码。

Builder based APIs can be very easy to read, if the methods of the builder are named cleverly, you can come out with code that reads almost like English sentences.

通常,构建器是一种有用的模式,根据您使用的语言,它们要么非常容易使用(例如Groovy),要么更乏味(例如在Java中) )用于API的提供者。然而,对于消费者来说,他们可以同样轻松。

In general, builders are a useful pattern, and depending on the language you are using, they are either really easy to use (e. g. Groovy) or a little more tedious (e. g. in Java) for the provider of an API. For the consumers, however, they can be just as easy.

这篇关于OO上的JavaWorld:Getters / Setters vs Builder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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