Java 生成单态

Java 生成单态,java,singleton,Java,Singleton,这听起来可能是个奇怪的想法,我还没有好好想清楚 例如,假设您有一个应用程序需要一定数量的单例来执行一些I/O。您可以编写一个单例,基本上可以根据需要多次复制代码 然而,作为程序员,我们应该想出创造性的解决方案,避免任何形式的冗余或重复。什么是一个解决方案,使多个东西,每个都可以作为一个单一的行为 附言:这适用于不能使用Spring等框架的项目。将参数传递给创建单例的函数(例如,它的名称或专门化)如何,该函数知道为每个唯一参数创建单例?您可以引入如下抽象: public abstract clas

这听起来可能是个奇怪的想法,我还没有好好想清楚

例如,假设您有一个应用程序需要一定数量的单例来执行一些I/O。您可以编写一个单例,基本上可以根据需要多次复制代码

然而,作为程序员,我们应该想出创造性的解决方案,避免任何形式的冗余或重复。什么是一个解决方案,使多个东西,每个都可以作为一个单一的行为


附言:这适用于不能使用Spring等框架的项目。

将参数传递给创建单例的函数(例如,它的名称或专门化)如何,该函数知道为每个唯一参数创建单例?

您可以引入如下抽象:

public abstract class Singleton<T> {
  private T object;

  public synchronized T get() {
    if (object == null) {
      object = create();
    }
    return object;
  }

  protected abstract T create();
}
private Database database;

public synchronized Database getDatabase() {
  if (database == null) {
    // connect to the database, assign the database field
  }
  return database;
}

private LogCluster logs;

public synchronized LogCluster getLogs() {
  ...

这是因为最终每个单例只需要多出一行代码,而初始化单例模式出错的几率非常低。

确实存在一种模式。无论如何,我60%确信解决原始问题的真正解决方案是RDBMS。

我知道你问过Java,但这里有一个PHP解决方案作为示例:

abstract class Singleton
{
    protected function __construct()
    {
    }

    final public static function getInstance()
    {
        static $instances = array();

        $calledClass = get_called_class();

        if (!isset($instances[$calledClass]))
        {
            $instances[$calledClass] = new $calledClass();
        }

        return $instances[$calledClass];
    }

    final private function __clone()
    {
    }
}
然后你就写:

class Database extends Singleton {}
然而,作为程序员,我们应该想出创造性的解决方案,避免任何形式的冗余或重复

这是不对的。作为程序员,我们应该提出满足以下标准的解决方案:

  • 满足功能要求;e、 g.按要求执行,无缺陷
  • 在规定的时间范围内交付
  • 是可维护的;e、 g.下一个开发人员可以阅读和修改代码
  • 执行任务的速度足够快,并且
  • 可以在将来的任务中重用
(虽然不同的上下文可能会规定不同的顺序,但这些标准大致按优先级的降低顺序排列。)

创造性不是要求,“避免任何形式的冗余或重复”也不是要求。事实上,这两种情况都有明显的危害。。。如果程序员忽略了真正的标准

回到你的问题上来。如果要使代码更具可维护性,您应该只寻找其他方法来实现单例。复杂的“创造性”解决方案很可能会回到你(或将来必须维护你的代码的人)身边,即使他们成功地减少了重复代码的行数


正如其他人所指出的(例如@BalusC),当前的想法是,在许多应用程序类中都应该避免使用单例模式。

@BalusC是正确的,但我要更强烈地说,单例在所有情况下都是邪恶的。 网络应用程序、桌面应用程序等等,只是不要这样做

事实上,一个单身汉所拥有的只是一堆全球数据。全球数据不好。这使得适当的单元测试变得不可能。这使得追踪奇怪的虫子变得越来越困难

《四人帮》这本书在这里完全错了。或者至少在15年前就过时了


如果您只需要一个实例,请创建一个只生产一个实例的工厂。这很容易。

多岁的人在某种程度上与独生子女这个术语相矛盾。考虑使用工厂模式。定义中的单体在过程中有一个实例。所以当你说多个单例时,你是指同一对象的多个实例吗?B.用于不同单例类的通用代码,用于将每个单例类限制为单个实例自从您谈论Spring以来,您使用的是JSP/Servlet Web应用程序吗?您是否考虑过
ServletContextListener
?webapp中的单例程序有异味。为什么不使用Spring/juice这样的框架来创建单例引用?@Techle:Option B.@BalusC:这个项目正在进行中@丹尼斯:这是要求的一部分。这是。。。吓人的。在构造单例时连接DB?@Gnarly我基本上认为这就是为什么不这样做的原因。就我个人而言,我更喜欢Guice(尽管它本身可能很复杂。)-1-这种方法不适用于Java。静态方法不是继承的,因此没有与
get_called_class
等效的方法。这是正确的,但因为我也对PHP感兴趣,所以我会给你投票,因为你费心发布了一个代码示例。我以前见过很多我名字的拼写错误,但现在还没有:)一方面,如果这回答了问题,我会投你一票。另一方面,这似乎是对原始帖子中不必要评论的辩论性回应(尽管OPs有缺陷的思维很可能是这个问题的根本原因)。@Tim Bender-如果有人挥舞着一支装有子弹的枪,最好让他放下枪,而不是给他脚上绷带,或者2)射击课。在我看来,OP对避免冗余的明显痴迷就像一把上了膛的枪。(好吧,也许是一把蜜蜂枪…@Stephen C,我看到过类似情况的最终结果,在这种情况下,程序员沉迷于泛型。你的类比不成立,因为你相信你能让他放下枪。至少在射击课上,OP不会造成太多的附带伤害。@Tim Bender-但你至少应该试着让他放下枪。或者,在本例中,正如我所尝试的那样,纠正OP对消除重复代码的不健康痴迷。我以前从未听说过这种模式,它听起来确实与Spring内部必须做的类似。这里有一个链接供将来参考:那将是理想的。这与使用工厂模式的建议是一致的。
class Database extends Singleton {}