Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中,服务类应该是单例的吗?_Java_Design Patterns - Fatal编程技术网

在java中,服务类应该是单例的吗?

在java中,服务类应该是单例的吗?,java,design-patterns,Java,Design Patterns,在设计服务类时,它应该是java中的singleton吗?通常DAO是单例的,那么调用服务类也应该是单例的吗?是的,服务不应该保持状态,因此应该是单例的。单例是不好的,如果你开发它们的话。如果您使用的是依赖项注入,那么让DI容器处理服务对象的单例性质。如果不使用依赖项注入,请使用静态方法而不是单例 坏消息的典型示例: public class HootUtility // singleton because developer was a goofball. { ... public

在设计服务类时,它应该是java中的singleton吗?通常DAO是单例的,那么调用服务类也应该是单例的吗?

是的,服务不应该保持状态,因此应该是单例的。

单例是不好的,如果你开发它们的话。如果您使用的是依赖项注入,那么让DI容器处理服务对象的单例性质。如果不使用依赖项注入,请使用静态方法而不是单例

坏消息的典型示例:

public class HootUtility // singleton because developer was a goofball.
{
   ...
   public void blammy(...) { ... }
   public HootUtility getInstance() { ... }
}

... somewhere in the code.

HootUtility.getInstance().blammy(...);  // This is silly.
更好地执行上述各项:

public class HootUtility // Not a singleton because I am not a ______. (fill in the blank as you see fit)
{
  // You can limit instantiation but never prevent instantiation.
  // google "java reflection" for details.
  private HootUtility()
  {
    throw new UnsuppotedOperationException();
  }

  public static void blammy(...) { ... }
}

... somewhere in the code.

HootUtility.blammy(...);
如果您有一个具有具体实现的服务接口,请使用依赖注入框架来注入实现(DI框架包括:spring和guice)

编辑:如果我使用的是spring,我会选择singleton范围(默认值)。

事实上,我相信你在设计时不应该在意它。就像@DwB提到的,DI框架应该做这项工作。此外,我相信任何范围(“原型”)都不应该是默认的,如果有人自己创建它,我看不出有什么不好的地方。
同样,这个问题可以通过模块化和分离服务接口和实现来简化,就像最佳实践一样

@Jyotirup正确使用单例不会影响性能(如果有任何改进的话)@Jyotirup:那是错误的,你把线程和对象弄混了。。。同步是一个不同的主题。@ThinkStiple,我的感觉是单例应该实际上是无状态的,并且是线程安全的。@home正如Peter指出的,我的意思是在多线程应用程序中,我们将面临issue@Peter,我同意singleton应该是无状态的,但是当您为服务设计singleton时,我们真的可以实现为无状态吗?关于在构造函数中抛出异常的有趣方法。就我个人而言,我只是把它留白了。你真的在你的生产代码中这样做吗?如果我使用SpringDI,范围应该是“Singleton”还是“Prototype”?大体上我同意你的看法。尽管如此,如果对象(singleton)必须保持内部状态,选项#1是一个合理的解决方案。@Jyotirup在Spring社区中,由于它是默认作用域,所以通常将其设置为singleton。在Guice中-无范围或“原型”。请参阅我的答案,了解更多说明。@StasKurilin因此,在多线程应用程序中,使其成为单线程将影响性能?每个请求的新服务类对象是一种糟糕的方法吗?@Jyotirup我不这么认为。如果它们是无状态的,您可以更改,并且您正确地使用了DI,您可以随时轻松地更改它。我认为这将是一种不好的原型方法。想一想,如果你在你的web应用程序上发出数千个请求,甚至只有数百个。这是一个类的数百个实例被初始化。从概念上讲,如果类及其依赖项(例如,具有db连接的dao原型)的创建成本足够高,则原型化服务可能会导致更快的攻击,特别是在发生DDoS的情况下。使用DI框架(如Spring的@Autowired)的单吨服务将减少一些不必要的资源分配