Singleton design pattern i zapobieganie klonowaniu

Wiele artykułów, które czytałem w Internecie na temat Singleton design pattern wspomina, że klasa powinna zastąpić metodę' clone () 'i w niej rzucić wyjątek 'CloneNotSupported'. Czy to naprawdę konieczne?

Metoda clone () domyślnie jest chroniona, więc żadna klasa (z wyjątkiem tych w tym samym pakiecie) nie byłaby w stanie wywołać jej na tej instancji Singletona. Dodatkowo, Jeśli ten Singleton nie zaimplementuje Cloneable, to nawet jeśli ta metoda zostanie wywołana, to da wyjątek runtime. Plus, the konstruktor będąc prywatnym, nie będziemy w stanie go podklasować, a tym samym pozwolić na jego klonowanie. Czy nadal powinienem stosować tę radę do moich zajęć Singleton?

EDIT: tak dla jasności: nie szukam najlepszego możliwego sposobu na implementację Singletona. Pytam tylko o zasadność powyższej porady, w. r. t 'normal' Singleton pattern (a nie Enum based Singleton).

Author: shrini1000, 2012-02-16

11 answers

Jeśli naprawdę zamierzasz wdrożyć singleton, użyj jednoelementowego enum i przestań o tym myśleć.


EDIT: tak dla jasności: nie szukam najlepszego możliwego sposobu na implementację Singletona. Pytam tylko o zasadność powyższej porady, w. r. t 'normal' Singleton pattern (a nie Enum based Singleton).

Skoro masz skuteczną Javę, {[19] } to powinieneś już być świadomy pułapek i problemy z Cloneable. To powiedziawszy, jeśli zamierzasz zaimplementować singleton jednym z "złych" sposobów, Nie, Nie ma absolutnie żadnego powodu, aby zaimplementować Cloneable i zastąpić Object#clone() po prostu rzucić CloneNotSupportedException. Object#clone() robi to już , Gdy interfejs Cloneable jest nieobecny.

 23
Author: Matt Ball,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:08

@Shrini1000, masz poprawne pytanie ale sugestia o clone jest bardzo specyficzne dla następującego warunku

public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException(); 
}

Powyższe jest konieczne tylko wtedy, gdy Klasa nadrzędna klasy singleton implementuje publiczną metodę clone () .

 6
Author: Gourabp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-09 13:01:52

Poniższy kod zapobiega klonowaniu klasy singleton.Nadpisuje metodę klonowania i rzuca nową metodę CloneNotSupportedException ()

public final class SingeltonCloneTest implements Cloneable {

    /**
     * @param args
     * @return
     */
    private static SingeltonCloneTest instance = null;

    private SingeltonCloneTest() {
     System.out.println("Rahul Tripathi");
    }

    public static SingeltonCloneTest getInstance() {

        if (instance == null) {
            instance = new SingeltonCloneTest();
            return instance;
        }
        return instance;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {

        // TODO Auto-generated method stub
        /*
         * Here forcibly throws the exception for preventing to be cloned
         */
        throw new CloneNotSupportedException();
        // return super.clone();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SingeltonCloneTest test1 = SingeltonCloneTest.getInstance();

        try {
            SingeltonCloneTest test2 = (SingeltonCloneTest) test1.clone();
        } catch (CloneNotSupportedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
 3
Author: Rahul Tripathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-09 12:51:03

Zobacz https://stackoverflow.com/a/71399/385478 dla najbezpieczniejszego sposobu egzekwowania wzoru Singletona. Zasadniczo, aby Singleton był enum, a nie class, z pojedynczą wartością INSTANCE.

 2
Author: Graham Borland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:12

Podczas pisania klasy używając wzorca Singleton, tylko jedna instancja ta klasa może istnieć na raz. W rezultacie klasa nie może być / align = "left" /

Wzorzec Singletona mówi, że wewnątrz programu istnieje tylko jedna instancja klasy, więc dobrze jest wywołać CloneNotSupportedException w metodzie Clone ().

 2
Author: aleroot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 14:35:20

Jest to konieczne, jeśli Klasa Singleton rozszerza klasę, która ma widoczną metodę clone() zdefiniowaną w swojej hierarchii.

 2
Author: user2103311,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-23 22:03:23

Można uniknąć klonowania podając już utworzony obiekt metodą klonowania.

public Object clone() {

return singletoneObject;

}
 2
Author: user3020398,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-22 05:41:05

Najlepszy przykład jaki znalazłem to:

class SingletonSuper implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
   }
}

class Singleton2 extends SingletonSuper {
    // 1. Make all constructors private
    private Singleton2() {
     }

// 2. Declare a private static variable to hold single instance of class
    private static Singleton2 INSTANCE = new Singleton2();

    public static Singleton2 getInstance() {
        return INSTANCE;
   }
  }

 public class SingletonCloningTest {
    public static void main(String[] args) throws Exception {
        System.out.println("Singleton Test!");
         System.out.println("Singleton Instance:" +                         +  Singleton2.getInstance());
        System.out.println("Singleton clone:"
            + Singleton2.getInstance().clone());
    }
}



 The result will:

 Singleton Test!
 Singleton Instance:com.sample.test.Singleton2@50d89c
 Singleton clone:com.sample.test.Singleton2@1bd0dd4
 1
Author: hitesh141,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-20 10:56:04

Override metoda clone () poprzez implementację interfejsu Cloneable I throw CloneNotSupportedException ();

@Override
protected Object clone() throws CloneNotSupportedException {
    // directly throw Clone Not Supported Exception
    throw new CloneNotSupportedException();
}     

Aby dowiedzieć się więcej o ograniczaniu 4-sposobów tworzenia obiektów w Javie, przeczytaj tutaj http://www.benchresources.net/singleton-design-pattern-restricting-all-4-ways-of-object-creation-in-java/

 1
Author: BenchResources.Net,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-20 09:09:34

Musisz nadpisać metodę clone() tylko wtedy, gdy twoja klasa singleton implementuje interfejs Cloneable lub klasę, która implementuje interfejs Cloneable.

 0
Author: prageeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-25 11:38:01

Zgodnie z moim zrozumieniem nie musisz implementować metody clone (). Uzasadnienie: 1. Jeśli nie zaimplementujesz metody klonowania i interfejsu Cloneable, spowoduje to wyrzucenie CloneNotSupportedException. 2. metoda klonowania jest chroniona i nie można podklasować klasy singleton.

 0
Author: Anirban B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-06 10:38:07