单子模式[英] Singleton Pattern

本文是小编为大家收集整理的关于单子模式的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

这个问题,就像我以前的问题一样,参考有效的Java .这次我有很多子问题.

  1. 特权客户可以在AccessibleObject.setAccessible()方法的帮助下对私人构造函数进行反思.如果您需要防御这种情况,请修改构造函数.
    如何确切地调用私人构造函数?什么是AccessibleObject.setAccessible()?

  2. 您的专家使用什么方法?

    // Approach A
    public class Test{
        public static final Test TestInstance = new Test();
        private Test(){ ... }
        .
        .
        .
    }
    
    
    // Approach B
    public class Test{
        private static final Test TestInstance = new Test();
        private Test(){ ... }
        public static Test getInstance() { return TestInstance; }
        .
        .
        .
    }
    

    第二种方法不是更灵活,以防我们每次或每次都必须检查新实例吗?

  3. 如果我尝试克隆类/对象怎么办?

  4. 单元素枚举类型是实现单身人士的最佳方法.
    为什么?如何?

推荐答案

一个有特权的克莱特(Cleint)可以借助AccessibleObject.stainaccessible的方法来调用私人构造函数,如果您需要捍卫它,请修改构造函数.我的问题是:如何调用私人构造函数?什么是AccessibleObject.setAccessible?

显然可以通过类本身来调用私人构造函数(例如,从静态出厂方法中).反射性,布洛赫在谈论的是:

import java.lang.reflect.Constructor;

public class PrivateInvoker {
    public static void main(String[] args) throws Exception{
        //compile error 
//      Private p = new Private();

        //works fine
        Constructor<?> con = Private.class.getDeclaredConstructors()[0];
        con.setAccessible(true);
        Private p = (Private) con.newInstance();
    } 
}

class Private {
    private Private() {
        System.out.println("Hello!");
    } 
}

2.您的专家如何遵循什么方法:

...

通常,第一个受到青睐.第二个(假设您要在返回新实例之前测试TestInstance是为null的),以懒惰加载,以需要同步或螺纹 - 不安全.

我在声明时写下了您的第二个示例未将实例分配给TestInstance时,我写了上述内容.如前所述,上述考虑是无关紧要的.

如果我们每次都必须每次或同一实例进行检查,那么第二种方法不是更灵活吗?

这与灵活性无关,而是关于创建一个(和唯一)实例的成本.如果您执行选项a)在课程加载时间会发生.这通常很好,因为无论如何只有一旦需要加载.

我在声明时写下了您的第二个示例未将实例分配给TestInstance时,我写了上述内容.如前所述,在这两种情况下,Singleton都将在类负载下创建.

如果我尝试克隆类/对象怎么办?

出于明显的原因,单身人士不应允许克隆.应该抛出clonotsupportedException,除非您出于某种原因实现Cloneable.

单元素枚举类型是实现单身人士的最佳方法.为什么?以及如何?

示例在书中,以及理由也是如此.您不明白哪一部分?

其他推荐答案

一个有特权的克莱特可以反思地调用私人构造师 援助 AccessibleObject.setAccessible方法, 如果您需要辩护,请修改 构造函数.我的问题是:如何 私人构造函数确切可以是 调用?是什么 accessibleObject.setAccessible ??

您可以使用Java反射来调用私人构造函数.

您的专家采用哪种方法来遵循Singletons:

我是使用Enum实际做到这一点的粉丝.这也在书中.如果这不是一个选项,那么执行选项A要简单得多,因为您不必检查或担心已经创建的实例.

如果我试图克隆 类/对象?

不确定你是什么意思?您是说克隆()还是我不知道的其他东西?

单元素枚举类型是实现单身人士的最佳方法. 为什么?以及如何?

啊,我自己的回答.哈哈.这是最好的方法,因为在这种情况下,Java编程语言保证了单身人士,而不是开发人员必须检查单身人士.几乎是单身人士是框架/语言的一部分.

编辑: 我没有看到这是一个好人.更新我的答案 - 最好使用这样的函数,因为您可以控制通过getter发生的事情,但是如果每个人都直接使用参考,则不能做同样的事情.想想未来.如果您最终做了躯体,然后您想让它懒惰,以免立即加载,那么您将需要在任何地方更改它.

其他推荐答案

单身人士是一个很好的学习模式,尤其是作为入门设计模式.但是,请注意,它们通常最终成为最过度使用的模式.到了某些人认为他们为" anti-pattern" .最好的建议是"明智地使用它们."/p>

为此,对此进行了很好的介绍,以及许多其他有用的模式(我个人发现策略,观察者和命令比单身人士更有用),请查看头部第一个设计模式.

本文地址:https://www.itbaoku.cn/post/627698.html

问题描述

This question, like my previous question, references Effective Java. This time I have quite a few sub-questions.

  1. A privileged client can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible() method. If you need to defend against this, modify the constructor.
    How, exactly, can a private constructor be invoked? And what is AccessibleObject.setAccessible()?

  2. What approach do you experts follow with singletons?

    // Approach A
    public class Test{
        public static final Test TestInstance = new Test();
        private Test(){ ... }
        .
        .
        .
    }
    
    
    // Approach B
    public class Test{
        private static final Test TestInstance = new Test();
        private Test(){ ... }
        public static Test getInstance() { return TestInstance; }
        .
        .
        .
    }
    

    Isn't the second approach more flexible, in case we have to make a check for new instances every time or the same instance every time?

  3. What if I try to clone the class/object?

  4. a single-element enum type is the best way to implement a singleton.
    Why? How?

推荐答案

A priviledged cleint can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method, If you need to defend this, modify the constructor. My question is: How exactly can a private constructor is invoked? and what is AccessibleObject.setAccessible??

Obviously a private constructor can be invoked by the class itself (e.g. from a static factory method). Reflectively, what Bloch is talking about is this:

import java.lang.reflect.Constructor;

public class PrivateInvoker {
    public static void main(String[] args) throws Exception{
        //compile error 
//      Private p = new Private();

        //works fine
        Constructor<?> con = Private.class.getDeclaredConstructors()[0];
        con.setAccessible(true);
        Private p = (Private) con.newInstance();
    } 
}

class Private {
    private Private() {
        System.out.println("Hello!");
    } 
}

2.What approach do you experts follow with singletons:

...

Typically, the first is favoured. The second (assuming you were to test if TestInstance is null before returning a new instance) gains lazy-loading at the cost of needing to be synchronized or being thread-unsafe.

I wrote the above when your second example didn't assign the instance to TestInstance at declaration. As stated now, the above consideration is irrelevant.

Isn't the second approach more flexible in case we have to make a check for new instance every time or same instance every time?

It's not about flexibility, it's about when the cost of creating the one (and only) instance is incurred. If you do option a) it's incurred at class loading time. That's typically fine since the class is only loaded once it's needed anyway.

I wrote the above when your second example didn't assign the instance to TestInstance at declaration. As stated now, in both cases the Singleton will be created at class load.

What if I try to clone the class/object?

A singleton should not allow cloning for obvious reasons. A CloneNotSupportedException should be thrown, and will be automatically unless you for some reason implement Cloneable.

a single-element enum type is the best way to implement a singleton. Why? and How?

Examples for this are in the book, as are justifications. What part didn't you understand?

其他推荐答案

A priviledged cleint can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method, If you need to defend this, modify the constructor. My question is: How exactly can a private constructor is invoked? and what is AccessibleObject.setAccessible??

You can use java reflection to call private constructors.

What approach do you experts follow with singletons:

I am a fan of using enum to actually do this. This is in the book also. If that's not an option, it is much simpler to do option a because you don't have to check or worry about instance being already created.

What if I try to clone the class/object?

Not sure what you mean? do you mean clone() or something else that I don't know of?

a single-element enum type is the best way to implement a singleton. Why? and How?

Ahh my own answer. haha. This is the best way because in this case, the java programming language guarantees a singleton instead of the developer having to check for a singleton. It's almost as if the singleton was part of the framework/language.

Edit: I didn't see that it was a getter before. Updating my answer to this - it's better to use a function such getInstance because you can control what happens through a getter but you can't do the same if everybody is using a reference directly instead. Think of the future. If you ended up doing SomeClass.INTANCE and then later you wanted to make it lazy so it doesn't load right away then you would need change this everywhere that its being used.

其他推荐答案

Singletons are a good pattern to learn, especially as an introductory design pattern. Beware, however, that they often end up being one of the most over-used patterns. It's gotten to the point that some consider them an "anti-pattern". The best advice is to "use them wisely."

For a great introduction to this, and many other useful patterns (personally, I find Strategy, Observer, and Command to be far more useful than Singleton), check out Head First Design Patterns.