在java中创建对象的最佳实践

发布于 2024-12-09 22:02:34 字数 571 浏览 0 评论 0原文

我正在阅读 Joshua Bloch 所著的Effective Java一书。在第一章中,他说使用工厂而不是构造函数,并列出了这种方法的优点和缺点。据我所知,缺点与对象构造没有密切关系。

此外,Bloch 表示 Java Bean 的构造风格也有缺点。 来源:http://www.javapractices.com/topic/TopicAction.do?Id =84

好的,所以使用构造函数并不好,Java bean也不好,工厂很好,所以你可以做一些缓存查找并避免创建额外的对象(取决于情况,有时你不需要缓存)。

如果我尝试避免构造函数和 java beans,我应该如何创建对象?

我是否遗漏了一点?最佳实践是什么?

编辑:

class Foo{
   private Foo(){}

   public Foo Create(){
      return new Foo();
   }

}

I'm reading the Effective Java book by Joshua Bloch. In the first chapter, he says to use factories instead of constructors and lists the advantages and disadvantages of this approach. As far as I see disadvantages are not closely related to to object construction.

Moreover, Bloch says that Java Bean style of construction has disadvantages as well.
Source: http://www.javapractices.com/topic/TopicAction.do?Id=84

OK, so using constructors is not great, Java beans are not great, factories are nice, so you can do some cache lookups and avoid creating extra objects (depends on the situation, sometimes you dont want caching).

How am I supposed to create an object if I try to avoid constructors and java beans?

Am I missing a point? What is the best practice?

EDIT:

class Foo{
   private Foo(){}

   public Foo Create(){
      return new Foo();
   }

}

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

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

发布评论

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

评论(8

深空失忆 2024-12-16 22:02:34

使用构造函数,直到您开始感受到布洛赫提到的缺点。然后考虑工厂、依赖注入或其他方法是否更好。

Use constructors until you start to feel the disadvantages Bloch mentions. Then consider whether factories, dependency injection, or some other approach is better.

花心好男孩 2024-12-16 22:02:34

对参数数量较少的简单对象使用构造函数。如果参数数量增加,则开始考虑布洛赫建议的构建器或工厂。

大多数简单的情况,构造函数都能很好地完成工作。

我的经验是,如果定义对象的属性数量增加很多,我会回去检查设计,看看是否必须以更好的方式对属性进行分组。就像餐桌可以分解成n条腿+1个顶部木制部分。

如果您对所有对象构造使用工厂模式,它看起来不太好。

  • 也永远不要在你的类中使用类似java bean的setter,除非有充分的理由*你会感谢我这么说,因为这会让代码的维护成为一场噩梦——你永远不知道谁以及如何调用setter来改变对象的状态。应该通过构造函数使用尽可能多的细节来构造对象,使它们尽可能不可变,如果不能使它们仅通过一种或两种方法来更新对象状态的几种方法。

Use constructors for simple objects with small number of arguments. If the number of arguments grow , then start thinking about either builder or factory as suggested by bloch.

Most of the simple cases, constructors does the job neatly.

My experiences is that, if the number of attributes to define a object grows a lot, I would go back and review the design and find out if I have to group the attributes in a better way. Like DININGTABLE can be broken into the n legs + 1 top wooden part.

If you use factory pattern for all your object constructions, it does not look nice.

  • also NEVER USE java bean like setters in your classes unless there is a good reason * You will thank me for saying this because that will make the maintenance of the code a nightmare --- you never know who and how the setters are called to change the state of the object. Objects should be constructed with as much details as possible thru a constructor , make them as much as possible as immutable, if not make them only few ways to update the state of the object via one or two methods only.
忘你却要生生世世 2024-12-16 22:02:34

这取决于场景。正如您所提到的,如果涉及缓存,那么静态工厂是更好的方法。如果有很多状态变量,则使用构建器模式。

It depends on the scenario. As you mentioned, if there is caching involved, then static factories are the preferable way. If there are lots of state variables, then use a Builder pattern.

温柔一刀 2024-12-16 22:02:34

您可能有兴趣熟悉依赖注入模式,使用Google Guice 是实现它的最流行的框架之一。

You might be interested in getting familiar with the Dependency Injection pattern, with Google Guice being one of the most popular frameworks to implement it.

小镇女孩 2024-12-16 22:02:34

好吧,我认为这家伙指的是控制反转模式:

http://en.wikipedia.org /wiki/Inversion_of_control

不是在这里做论文,我只是说,在对象实例化的这个狭窄上下文中的控制反转涉及到拥有单独的服务协议的事实(和好处)使用对象实例化,而不必手动实例化这些对象。实现这一目标的一种方法是工厂模式,根据您所说,该人正在描述该模式。另一种方法是使用一个为您执行 IOC 的框架,例如 Spring:

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html

(这实际上离工厂模式并不远)

第三种选择是制作自己的 IOC处理对象实例化的机制以某种方式,这样你就不必每次都明确地这样做。

这里的想法不是停止使用构造函数来创建实例,您总是使用它来获取实例,这里的想法是何时以及如何调用该构造函数:

  • 您是否在需要实例的类中直接调用它
  • ?一个单独的机制(如 Factory)在需要时处理获取该实例(依赖项),这样您就永远不会自己明确地执行此操作

。这两种方法都有优点。通常情况下,最好单独处理实例化,而不是手动执行,因为这样可以生成更干净、耦合性更少且更可测试的代码。

Well I think what the guy is reffering to there is Inversion of Control pattern:

http://en.wikipedia.org/wiki/Inversion_of_control

Not to make a dissertation here, I'll just say that inversion of control in this narrow context of object instanciation reffers to the fact (and benefits) of having a separate service deal with object instanciation, and not having to instanciate those objects manually. One way to achieve this is the Factory Pattern which, from what you say, the guy is describing. Another one would be to use a framework that does IOC for you, like Spring:

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html

(which is really not that far from the Factory Pattern)

A third option is to make your own IOC Mechanism that deals with object instanciation in some way so you don't have to do it explicitly every time.

The idea here is not to stop using the constructor to create instances, you always use that to get your instances, the idea here is WHEN and HOW you call that constructor:

  • do you call it directlly in the class that needs the instance
  • do you have a separate mechanism (like Factory) that deals with getting that instance (dependency) when needed, such that you never explicitly do it yourself

There are advantages to both ways. More often than not is better to deal with instanciation separatelly and not do it manually as it leads to cleaner, less coupled and more testable code.

梦开始←不甜 2024-12-16 22:02:34

如果您遇到一个程序正在通过数学计算来计算出一周中的哪一天,您会怎么想?您可能会认为“计算出一周中的哪一天的数学应该是在它自己的方法中,因此它可以表达一次且仅一次,只要代码需要知道哪一天,就可以调用该方法这是本周的“”。

实际上,构建一个对象与计算出一周中的哪一天没有什么不同。在一个地方执行此操作,将其设为一个方法,然后从需要新对象的任何地方调用该方法。

现在,在某些情况下,该方法本身可以是构造函数(构造函数实际上只是一种有趣的方法,对吧?)。在其他情况下,该方法将调用构造函数,该构造函数不会在其他任何地方使用。这取决于创建对象需要做多少工作,以及您想要隐藏正在创建的对象的类的程度(想象一个 createDaysOfTheWeek 工厂方法 - 它可能返回一个 Collection,并隐藏它是 ArrayListLinkedHashSetEnumSet 的事实 任何)。将构造包装在工厂方法中可以提供更多封装,但透明度较低。编写好的代码需要这两种品质,但就像啤酒和馅饼一样,您需要平衡它们。

If you came across a program that was doing maths to work out what day of the week it was all over the place, what would you think? You'd probably think "that maths to work out what day of the week it is should be in a method of its own, so it can be expressed once and only once, with the method being called wherever the code needs to know what day of the week it is".

Constructing an object is no different to working out what day of the week it is, really. Do it in one place, make that a method, and call that method from wherever you need a new object.

Now, in some cases, that method can itself be the constructor (a constructor is really just a funny kind of method, right?). In others, the method will call the constructor, which will not be used anywhere else. It depends on how much work there is to do to create the object, and how much you want to hide the class of the object being created (imagine a createDaysOfTheWeek factory method - it could return a Collection<DayOfTheWeek>, and hide the fact that it's an ArrayList or LinkedHashSet or EnumSet or whatever). Wrapping the construction in a factory method gives you more encapsulation, but less transparency. Both of those qualities are needed to make good code, but like beer and pies, you need to have a balance of them.

浪漫之都 2024-12-16 22:02:34

始终根据上下文来判断建议。构造函数是创建对象的标准方法,但它们也并非完全没有缺点。

例如,他谈到了服务提供者框架 - 这只有在构造对象的工厂方法上才可能实现。但重点是你并不是一直在设计服务提供者框架。

他再次引用了 Collection 框架中使用实例控制类的示例。如果将对象创建限制为简单的构造函数样式,则这是不可能的。但同样,日常代码不需要采用实例控制的类。

他还制作了其他支持工厂方法的案例 - 所有这些都是在某种使用环境下进行的。在其他情况下,构造函数可能就足够了。

Always judge a recommendation in the context. Constructors are the standard way to create an object , but they are not entirely free from disadvantages.

For example , he talks about a Service provider framework - this is made possible only on factory methods of constructing objects. But the point is you dont design Service Provider Framework all the time.

Again , he quotes examples from Collection framework which use instance-controlled classes. This is not possible if you limit object creation to simple constructor style. But again , everyday code need not adopt the instance-controlled classes.

There are other cases he makes in support of the factory method - all under some context of use. In other contexts , constructors may well suffice.

鲜肉鲜肉永远不皱 2024-12-16 22:02:34

您可以使用 Cinstructor 创建对象,就像使用 new 一样,如下所示:

Foo f=new Foo();

有一个称为单例的概念。在这种情况下,您可以如上所示使用此类型,但将 create 函数设置为静态,否则用户将如何调用 create 函数,如下所示:

class Foo{
   private Foo(){}

   public static Foo Create(){
      return new Foo();
   }

}

You can create object using Cinstructor like using new as follows example:

Foo f=new Foo();

There is a concept called singleton.In that case you can use this type as you shown above but make the create function static else how the user will call the function create as follows:

class Foo{
   private Foo(){}

   public static Foo Create(){
      return new Foo();
   }

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