Чекор по чекор
Почетни чекори со Java
Објектно оријентирани концепти во Јава - Прв дел
Објектно оријентирани концепти во Јава - Втор дел
Објектно оријентирани концепти во Јава - Трет дел
Јава сервлети - Прв дел
Единствен Јава објект (singleton)
Најчести 10 грешки што ги прават Java програмерите
повеќе...
Што е тоа ...
... IDE
... Tomcat
... објект?
... класа?
... наследување?
... интерфејс?
... наследување? (прашања и одговори)
повеќе...
За загревање
Нов проект во Eclipse?
Примитивни податочни типови
Променливи
Оператори
Доделувачки, аритметички и Unary оператори
Оператори за еднаквост, релации и услови
Изрази, искази и блокови
повеќе...
Како да ...
... конвертирам java.sql.Timestamp во java.util.Date
... зададам формат на датум
... ковертирам „long“ во HEX и обратно
... прочитам датотека и променам стринг
... креирам ZIP датотека
... поврзам Apache и Tomcat користејќи mod_jk
... пратам недефиниран број на атрибути до некоја метода
повеќе...
Java преку примери
new Socket(String addr,int port)
new URL(String address)
new URL(String protocol, String host, int port, String file)
CommPort: getInputStream()
CommPortIdentifier: getPortIdentifiers()
Statement: executeQuery(String sql)
Statement: getMaxRows()
повеќе...
Грешка
Нов напис
Рубрика:
Наслов:
  
  

страна број:123
Единствен Јава објект (singleton)
прегледано:  4137
 вкупно гласови:  4
 средна оценка:  5.0
 коментари:  9
За тие коишто не слушнале за дизајн патерн (design pattern) претходно, или на кои им е познат изразот, но не и значењето, дизајн патерн е шема за развој на софтвер. Целта на шемата е да дефинира начин или техника која може да се употреби како градбена единка за конструкција на софтвер - решавање на универзални проблеми кои ги имаат програмерите. Тоа се всушност решенија кои се предаваат од еден на друг. Гледај на дизајн патерн како на корисен совет за дизајнирање на софтвер.

Еден од дизајн-патерните е синглтон (singleton). Синглтон е објект кој не може да се инстанцира. На почеток, ова може да изгледа неинтуитивно - сепак, нас ни треба инстанца на објект пред да го користиме. Да, синглтонот може да се креира, но не може да се инстанцира од програмерот - тоа значи дека синглтон класата има контрола над тоа како се креира. Рестрикцијата на синглтонот е дека може да постои само една инстанца од синглтонот креирана од јава виртуелната машина (JVM) - со превенција на директно инстанцирање можеме да се осигураме дека програмерите нема да креираат втора копија.

Зошто би користело ова? Често, при дизајн на систем, сакаме да имаме контрола како се користи некој објект, и да спречиме некој (вклучувајќи не и нас) да прави копии или да креира нови инстанци. На пример, централен конфигурациски објект што чува информации треба да има една и само една инстанца - глобална копија пристапна од било кој дел на апликацијата, вклучувајќи ги сите активни нишки (threads). Креирањето на нов конфигурациски објект е потполно бескорисно, бидејќи некои делови од апликацијата може да гледаат во стар конфигурациски објект, и промените нема да се пренесат подеднакво низ цела апликација. Ова е чест критериум за дизајн (не е користен секој ден, но се јавува потреба од време на време). Синглтон патернот може да се искористи во било кој јазик, но бидејќи ние сме Java програмери, да видиме како може да се имплементира во Java.
 
Спречување на директно инстанцирање

Сите знаеме како се инстанцираат објекти, нели? Ако не, да се потсетиме.

Објектите се инстанцираат со користењеот на клучниот збор "new". Тој збор овозможува креирање на нова инстанца на објект и специфицирање на параметри во класниот конструктор. Не мора да се специфицираат параметри, и во тој случај се повикува "празниот" конструктор. Конструкторите можат да бидат public или private, кои користат за контрола на тоа кои класи можат да го повикаат конструкторот. За да спречиме директно инстанцирање, креираме приватен "празен" конструктор, такашто другите класи нема да можат да креираат нова инстанца.

Ќе почнеме со класната дефиниција за класата SingletonObject. После, ќе вметнеме "празен" конструктор кој е маркиран како private. Не е потребен код во конструкторот, но може да се стави иницијализациски, доколку постои потреба.


public class SingletonObject  {
    private SingletonObject() {
        // ne e potreben kod
    }
}


Земање на синглтон инстанца

Треба да обезбедиме метод, кој враќа инстанца од SingletonObject класата, но не дозволува повеќе од една копија да биде пристапна. Можеме мануелно да инстанцираме објект, но мораме да чуваме референца кон синглтонот, такашто други последователни повици кон методот ќе ја враќаат истата копија (наместо да креираат нов објект). За да го направите ова, дефинирајте јавен статички метод наречен getSingletonObject(), и чувајте копија од синглтонот во приватна променлива.


public class SingletonObject {

    private static SingletonObject ref;

    private SingletonObject()    {
        // ne e potreben kod
    }

    public static SingletonObject getSingletonObject() {
        if (ref == null)
            // vo red e, mozeme da go povikame konstruktorot
            ref = new SingletonObject();

        return ref;
    }
}


Досега, се е добро. Кога првпат ќе биде повикан, методот getSingletonObject() креира синглтон инстанца, ја сместува во променлива и го враќа самиот синглтон. Следните повици ќе го вратат истиот синглтон, и се е во ред. Можете да ја проширите функционалноста на синглтон објектот со додавање на нови методи, кои ќе ги извршуваат задачите сто се потребни од синглтонот. Синглтонот е готов, нели? Па, скоро...
 

Спречување на проблеми со нишки кај синглтоните

Мораме да се осигураме дека нишките кои го повикуваат методот getSingletonObject() не предизвикуваат проблеми, па препорачливо е методот да се маркира како synchronized. Ова спречува две нишки да го повикаат методот getSingletonObject() во исто време. Ако едната нишка влезе во методот одма после другата, може да се случи конструкторот на SingletonObject да се повика двапати да се вратат различни вредности. Затоа, сменете го методот во:

public static synchronized SingletonObject getSingletonObject()


Дали сега сме завршиле?

Со ова, да. Синглтон објектот гарантира дека ќе постои само една инстанца од оваа класа. Така? Па, не баш... Кога постои волја, постои и начин - сеуште е возможно да се креира повеќе од една инстанца од синглтон објектот. Повеќето од написите за синглтон го забораваат ова, бидејќи забораваат на клонирањето. Видете го следниов пример, кој клонира синглтон објект.


public class Clone {
    public static void main(String args[]) throws Exception {
        // Zemi singlton
        SingletonObject obj = SingletonObject.getSingletonObject();
        // Tuka se klonira objektot
        SingletonObject clone = (SingletonObject) obj.clone();
    }
}


Всушност, не постои clone() метод дефиниран во SingletonObject, но постои во java.lang.Object класата од која наследува. Вообичаено, методот clone() е маркиран како protected, но ако SingletonObject наследува класа која поддржува клонирање, возможно е да се нарушат принцпите за дизајн на синглтон. За да бидеме 100% сигурни дека синглтонот навистина е синглтон, мораме да додадеме наш clone() метод, и да фрлиме CloneNotSupportedException ако некој се осмели да клонира.

Ова е конечниот код за SingletonObject, кој можете да го користите како шема за вашите синглтони.

public class SingletonObject
{

    private static SingletonObject ref;

    private SingletonObject() {
        // ne e potreben kod
    }
  
    public static SingletonObject getSingletonObject() {
        if (ref == null)
            // vo red e, mozeme da go povikame konstruktorot
            ref = new SingletonObject();

        return ref;
    }

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



Заклучок

Синглтон е класа која може да биде инстанцирана еднаш и само еднаш. Ова е понекогаш доста корисно во некои објектни дизајни. Креирањето на имплементација на синглтон е едноставно - спречете пристап до сите конструктори, креирајте статички метод за земање на синглтон инстанцата и спречете клонирање.
 
Коментирај
автор: Анонимус
Анонимните коментари ќе бидат објавувани веднаш после нивната проверка.
За да вашиот коментар биде веднаш валиден претходно пријавете се или креирајте свој профил


напишал: MZ (11.01.2008 00:24:11)
Одлично.

Сум направил бааги singleton класи у живот, ама ниеднаш не ми текнало на Clone().

Додуша сеа вака од тепка појма неам ни што ќе се изврши ако викнеш object.Clone() без да го оverridе-уваш. Типувам на ништо. :)

Excelent work у секој случај!
напишал: igor (11.01.2008 00:32:32)
Тоа е идејата, доколку clone() остане не override-увана ... нема баш (поради дизајнот де) да остане singleton.
напишал: finger.k4 (11.01.2008 01:02:27)
супер article, ама мислам дека е време да почнеш(почнеме!!) да го структуираме сајтов.
премногу хаотично стана
ако го отвори почетник сајтов ќе види RMI, desing patterns и while и do while loop-ови ...

малце сум зафатен со испити ама планирам и јас да почнам нешто да пишам (само да не ме мрзи да инсталирам мак поддршка на linov :P ), design patterns баш сега ги изучувам и дури имам и неколку туторијали што ги предавав на fucks за netbeans што мислам дека ќе бидат корисни ... АМА ... мора структура и координација ... I HATE CHAOS ;)

other than that ... mucho респект до игор (колку што сватив ти си one man army :P)
напишал: igor (11.01.2008 23:03:24)
Ај вака, од сега па натака на сите ви благодарам за сите пофалби и критики.

Што се однесува до хаотичноста ... да во право си и тоа под итно ќе треба да се решава тоа прашање, така да се надевам дека во брзо време (барем како преодно) ќе има некое решение.

... инаку не сум one man army, има луѓе кои доста помагаат, секој на свој начин, така да благодарност и до нив.
напишал: slavejovanovski (11.01.2008 10:38:33)
Баш добар почетен текст за Design Patterns. Ми се допадна и изборот, не верувам дека е случаен, бидејќи Singleton е најверојатно еден од најлесно разбирливите Design Pattern. Притоа треба да бидете внимателни, бидејќи ретко кој знае да напише "добар" Singleton. Што подразбирам под "добар" е дефинирано подолу.

За почеток мала замерка во врска со дефиницијата на Singleton. "Синглтон е објект кој не може да се инстанцира". Најчестата дефиниција за Singleton е всушност: "Singleton е објект кој што се инстанцира еднаш и само еднаш". Мислам дека нешто слично е спомнато во истиор параграф каде што се дефинира поимот Singleton, но сакав да појаснам за секој случај. :)

Интересен факт е дека Singleton зад себе има и долга пrоблематична историја во постарите верзии на Java Виртуелната Машина. Во постарите верзии на Виртуелната Машина се до JRE 1.2 имаше проблем кој што понекогаш ќе ја собереше меморијата користена од Singleton објектот поради грешка во начинот на кој што виртуелната машина ги брои референците. После собирањето на меморијата, Sinleton-от повторно ќе беше иницијализиран. Овој проблем во виртуелната машина го нарушуваше дизајнот на Singleton. За среќа денешниве виртуелни машите ги
немаат овие проблеми. Фала му на господ.

Вистинските проблеми со Singleton се појавуваат кога повеќе нишки го достапуваат Singleton објектот во исто време, пред Singleton-от да биде иницијализиран. Решението со зборот synchronized дефинитивно работи, но дефинитивно ја деградира брзината на извршување на вашата комплицирана апликација. Причина за деградацијата е фактот дека со ставање на зборот synchronized пред метод, само една нишка може да го пристапува тој метод во било кое време. Во апликација во која многу нишки често го повикуваат методот getSingletonObject() ова може да биде вистински проблем бидејки другите нишки мора да чекаат додека една нишка го извршува методот getSingletonObject().

Доста добар напис во секој случај. Ја поздравувам иницијативата за вклучување на Design Patterns на java.com.mk бидејќи Design Patterns се дел од програмерското линго.

Се надевам дека овој напис ќе биде надополнет со втор дел кој што ќе би објасни можните решенија со исфрлање на зборот synchronized и проблемите со истите. Јас би волонтирал со помош кон пишувањето на истиот.
напишал: igor (11.01.2008 11:22:27)
Се слагам со се што напиша во коментарот, освен кај делот за критиката, не, не поради самата критика (која е очигледно супер баш поради тоа што разјаснува нејаснотија) туку поради преносната смисла на „не се инстанцира“, секако дека може да се инстанцира, но се губи основата смисла на дизајнот :).

Што се однесува до „вториот дел“ еве и официјална покана да се вклучиш во „градењето“ на Java.com.mk со пишување написи. Слободно можеш да започнеш со пишување на написот кој ќе биде објавен на Java.com.mk под твое име, се разбира написот треба да е убаво напишан.
напишал: niksa (11.01.2008 16:18:05)
Тоа за дефиницијата се сложувам. Инстанцирањето всушност се врши но се врши еднаш и тоа имплицитно преку static метода.
Но тука сакам да прашам една работа, како ќе споделите еден ресурс во multi-thread околина без synhronized?
Кога имате еден ресурс, мора да се ограничи пристапот, тоа што ќе чекаат thread-овите тоа е неизбежно, башка што не знаете точно како процесорското време се дели меѓу thread-овите. Тука е познатото прашање што ако thread-от биде прекинат откако ќе помине некој ВЛЕЗЕН IF услов?
Обично колку што знам, за клиент-сервер архитектура, се истанцираат одреден број на thread-ови, за да не дојде до преоптоварување на серверот. Сите останати вишак клиенти, добиваат порака Обидете се повторно :).
Уште ова ако неќат да користат Syncronized на метода нека користат synchronized на блок !

synchronized{
...
}

Ако ми текне уште нешто, ќе пишам :)
поздрав
напишал: slavejovanovski (11.01.2008 23:55:45)
Комплетно се согласувам дека synchronized е де-факто стандард кога станува збор за заеднички ресурси кои се користат од повеќе нишки. Доколку дефинирате некој метод како synchronized тогаш со сигурност не би имале проблеми со пристап кон заедничкиот ресурс. Проблемот со користење на synchronized на цел метод, како што напоменав во претходниот коментар, е што сите нишки треба да чекаат додека некоја друга нишка го извршува тој метод, иако можеби само еден дел од тој метод треба да е вистински synchronized.

Целта на мојот напис, кој се надевам ќе биде напишан за недела-две, е да прикажам проблеми со други методи на синхронизирање на ресурси спомнати во коментарот на niksa (синхронизирање околу IF, синхронизирање околу објект, синхронизирани блокови, и слично). Друга цел ќе биде да покажам дека постои начин да напишете Thread-safe Singleton класи без да користите synchronized на цел метод.

Славе
напишал: niksa (11.01.2008 16:03:46)
Текстов е добар и ќе користи доста. И тоа за Clone стварно не сум го знаел, пошто не сум го користел ни Clone у принцип. Ама сеа знам.. :)
Поздрав
пребарување
најди
 
Форум
 
JugMK
GetJava Download Button
http://www.eclipse.org
 
 
 
 
Copyrights © 2006 - 2017 by Java.com.mk
Права и правила за користење на java.com.mk
Контакт адреса:
contact AT java.com.mk
Powered by Supernova v.0.70 beta
JavaTM и Java-базираните ознаки се трговски марки или регистрирани трговски марки на Sun Microsystems, Inc. во САД и други држави. Java.com.mk никако не соработува со Sun Microsystems, Inc.
Сите други трговски марки се сопственост на нивните сопственици.