繁体   English   中英

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

[英]Best practice to creating Objects in java

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

此外,Bloch说Java Bean的构造方式也有缺点。 资料来源: http//www.javapractices.com/topic/TopicAction.do? Id= 84

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

如果我试图避免构造函数和java bean,我应该怎么创建一个对象?

我错过了一点吗? 什么是最佳做法?

编辑:

class Foo{
   private Foo(){}

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

}

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

将构造函数用于具有少量参数的简单对象。 如果参数的数量增加,那么就开始考虑bloch建议的构建器或工厂。

大多数简单案例,构造函数都能很好地完成工作。

我的经验是,如果定义对象的属性数量增长很多,我会回过头来检查设计并找出是否必须以更好的方式对属性进行分组。 就像DININGTABLE可以分成n个腿+ 1个顶部木制部分。

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

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

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

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

好吧,我觉得那个人正在苦苦挣扎的是Inversion of Control模式:

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

不要在这里做论文,我只是说在对象实例的这个狭窄的上下文中反转控制是指对物体实例进行单独服务处理的事实(和好处),而不是手动实例化那些对象。 实现这一目标的一种方法是工厂模式,根据你的说法,这个人正在描述。 另一个是使用一个为你做IOC的框架,比如Spring:

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

(真的离工厂模式不远)

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

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

  • 你在需要实例的类中直接调用它吗?
  • 你有一个单独的机制(如工厂)处理需要时获取该实例(依赖),这样你就不会自己明确地做

两种方式都有优点。 通常情况下,单独处理实例更好,而不是手动执行,因为它会导致更清晰,耦合度更低,代码更易测试。

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

构建一个对象与确定一周中的哪一天是完全没有区别的。 在一个地方做它,使它成为一个方法,并从你需要一个新对象的地方调用该方法。

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

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

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

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

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

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

Foo f=new Foo();

有一个名为singleton的概念。在这种情况下,您可以使用上面显示的此类型,但是使create函数为static,否则用户将如何调用函数create,如下所示:

class Foo{
   private Foo(){}

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

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM