Singleton პატერნი – Java

ყველა სახელმძღვანელო რომელიც წამიკითხავს იწყება სწორედ ამ პატერნის აღწერით, რაც უდავოდ გამოწვეულია იმით რომ იგი წარმოადგენს ყველაზე მარტივს არსებულ პატერნებს შორის.

ამ პატერნის გამოყენებით შესაძლებელია კონკრეტული ტიპის(კლასის) ერთი და მხოლოდ ერთი ობიექტის (ეგზემპლარის) შექმნა რომელიც გამოყენებული იქნება გლობალურად გარკვეულ კონტექსტში. ზოგიერთ პროგრამირების ენაში (მაგ. C, PHP) არსებობს ე.წ. გლობალური ცვლადის ცნება, რომლის ინიციალიზაციაც ხდება ფუნქციებისა და კლასების კონტექსტ მიღმა და მისი გამოყენება შესაძლებელია ნებისმიერ ფუნქციასა თუ კლასში. მიუხედავად იმისა რომ Java არ არის აღჭურვილი მსგავსი შესაძლებლობით Singleton პატერნის მეშვეობით შესაძლებელია მივიღოთ იგივე(თუმცა უფრო დახვეწილი და მოქნილი) შედეგი რაც მიიღება გლობალური ცვლადებით სხვა ენებში.

თავისი უმარტივესი ფორმით ეს პატერნი შეიძლება ჩავწეროთ შემდეგნაირად:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Singleton {
   
    private static Singleton singleton = null; //private static variable to store reference to the singleton instance

    private Singleton() {} //private constructor

    public static Singleton getInstance() {

        if (singleton == null) {
            singleton = new Singleton();
        }

        return singleton; //return the reference

    }

}

მთავარი დეტალი ამ პატერნის გამოყენებისას არის ის რომ კლიენტს(პროგრამის სხვა კოდი რომელიც იყენებს ამ კლასს) არ უნდა შეეძლოს ამ კლასის ობიექტის ცხადად შექმნა (new-ს გამოყენებით) რაც მიიღწევა ამ კლასის კონსტრუქტორის როგორც private წევრად აღწერით. ერთი შეხედვით შეიძლება უცნაურად(და სულელურად) გეჩვენოთ private კონსტრუქტორი კლასში, მაგრამ გარდა იმისა რომ ეს სავსებით დასაშვებია Java-ში ასევე არის ერთადერთი გზა რათა კლიენტს შევუზუდოთ ამ კლასის ობიექტების შექმნა.

private კონსტრუქტორს გარდა იმ ამოცანისა რაც აღნიშნული იყო ზევით ასევე გააჩნია სხვა დანიშნულება, იმ შემთხვევაში თუ კლასში არ განვსაზღვრავთ ერთ კონსტრუქტორს (ამ შემთხვევაში private) მაინ, მაშინ კომპილატორი თავად დააგენერირებს ნაგულისხმევ კონსტრუქტორს ფაილის კომპილაციისას რაც თავისთავად გულისხმობს იმას რომ ამ კლასის მემკვიდრეებსა და იმავე პაკეტში არსებულ სხვა კლასებს მისცემს მისი ობიექტების ცხადად შექმნის საშუალებას.

ნაცვლად Singleton კლასის ობიექტის ცხადად შექმნის შესაძლებლობისა კლიენტს უნდა შევთავაზოთ მეთოდი(მეთოდები) რომლებიც იზრუნებენ ამ კლასის ობიექტის შექმნასა და მის დაბრუნებაზე. ზემოთ აღწერილ მაგალითში ასეთი მეთოდია getInstance() რომელიც არის public და ასევე static რაც გულისხმობს იმას რომ ამ მეთოდზე წვდომა შესაძლებელია მისი კლასის ობიექტის არსებობის გარეშე.

თავისთავად მეთოდი მარტივია და აკეთებს ორ ძირითად რამეს:

  1. ამოწმებს არსებობს თუ არა Singleton კლასის ობიექტი, თუ არ არსებობს ქმნის მას.
  2. აბრუნებს უკვე არსებულ ობიექტს.

ასევე აღსანიშნავია ლოკალური singleton ცვლადი რომელიც არის private და static რაც თავისთავად გულისხმობს რომ მასთან წვდომა გააჩნიათ მხოლოდ იგივე კლასის სხვა წევრებს და მისი ინიციალიზაციისათვის არ არის აუცილებელი კლასის ობიექტის შექმნა.

ტეგები: ,

2 Responses to “Singleton პატერნი – Java”

  1. levani says:

    ეს პატერნი არ არის ThreadSafe, აქვე მოვუთითებ მიზეზსაც :
    multithreaded ენვირონმენტში არ არის გარანტირებული რომ ყოველთვის ერთი ობიექტი იქნება შექმნილი, ამის მოსაგვარებლად ალბათ იფიქრებთ syncronized დავამატოთ მეთოდს და ეგა რის პრობლემის მოგვარებაცო, მაგრამ მაშჳ უკვე სხვა პრობლემების წინაშე ვდგებით, ბევრი რო არ გავაგრძელო ასე შემთხვევაში საჭიროა Threadlocal ის გამოყენება .სწორი სრულყოფილი Singletone pattern-ი ასე გამოიყურება :

     class SingletonObj {
    
             private final ThreadLocal perThreadInstance = new ThreadLocal();
             private MySingleTone singl = null;
             public MySingleTone  getMySingleTone () {
                 if (perThreadInstance.get() == null){createMySingleTone ();}
                 return singl ;
             }
             private final void createMySingleTone () {
                 synchronized(this) {
                     if (singl == null)
                         singl = new MySingleTone  ();
                 }
    	     // Any non-null value would do as the argument here
                 perThreadInstance.set(perThreadInstance);
             }
    	}
    
  2. იოსები says:

    დიდი მადლობა ლევან სასარგებლო კომენტარისთვის :)

დატოვე კომენტარი:

ქართული კლავიატურა, ჩართვა/გამორთვა კლავიშით "~"