Сегодня начнем тематику паттернов проектирования. Паттерны проектирования - это описание некоторых проблем, возникающих во время объектно-ориентированного проектирования, а также способов их решения (как практических, так и теоретических). Говоря иначе - это примеры правильных подходов к решению классических задач проектирования.
Хотелось бы начать с самого распространенного паттерна - Singleton (Одиночка).
Хотелось бы начать с самого распространенного паттерна - Singleton (Одиночка).
Задача: Ограничить количество экземпляров некоторого класса.
Реализация:
- Ленивый / Lazy initialization
- Активный / Eager initialization
Если программа будет всегда нужна, например, или если стоимость создания экземпляра не слишком велика по времени и ресурсам, программист может переключиться на активную инициализацию, которая всегда создает экземпляр:
Далее разберем нашу композицию по ноткам:
Конструктор класса необходимо объявить с модификатором видимости private. Это предотвратит создание экземпляров класса как с помощью класса Singleton, так и с помощью его наследников. В связи с этим к объявлению класса смело можно дописать модификатор final.
Метод getInstance() создаст ровно один экземпляр класса Singleton. Этот метод объявлен как synchronized. Сделано это вот почему. В многопоточных программах при одновременном вызове метода getInstance() из нескольких потоков можно создать несколько экземпляров класса Singleton. А должен остаться только один!
От модификатора synchronized можно избавиться. Для этого _instance нужно проинициализировать:
Но использование ленивой(поздней)инициализации (lazy initialization) предпочтительнее в случае, если создание экземпляра класса занимает много времени.
А теперь перейдем к применению, зачем нужен Singleton:
Мне приходится чаще всего использовать этот паттерн при работе с конфигурацией. Иногда конфигурацию программы удобно хранить в файле. Допустим, это будет простой текстовый файл “props.txt” со строками типа “ключ=значение”. Нам нужно гарантировать, что конфигурация в программе будет в единственном экземпляре. Вторую мы бы и так не создали, но нужно запретить это делать пользователю класса. Итак,
Теперь для работы с конфигурацией можно использовать конструкцию вида:
Если имена свойств в “props.txt” меняться не будут, можно описать их в классе таким образом:
а значения получать так:
На том пока все :)
- Ленивый / Lazy initialization
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- Активный / Eager initialization
Если программа будет всегда нужна, например, или если стоимость создания экземпляра не слишком велика по времени и ресурсам, программист может переключиться на активную инициализацию, которая всегда создает экземпляр:
public class Singleton {
private static Singleton _instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return _instance;
}
}
Далее разберем нашу композицию по ноткам:
Конструктор класса необходимо объявить с модификатором видимости private. Это предотвратит создание экземпляров класса как с помощью класса Singleton, так и с помощью его наследников. В связи с этим к объявлению класса смело можно дописать модификатор final.
Метод getInstance() создаст ровно один экземпляр класса Singleton. Этот метод объявлен как synchronized. Сделано это вот почему. В многопоточных программах при одновременном вызове метода getInstance() из нескольких потоков можно создать несколько экземпляров класса Singleton. А должен остаться только один!
От модификатора synchronized можно избавиться. Для этого _instance нужно проинициализировать:
private static final Singleton _instance = new Singleton(),а в методе getInstance() удалить "if".
Но использование ленивой(поздней)инициализации (lazy initialization) предпочтительнее в случае, если создание экземпляра класса занимает много времени.
А теперь перейдем к применению, зачем нужен Singleton:
Мне приходится чаще всего использовать этот паттерн при работе с конфигурацией. Иногда конфигурацию программы удобно хранить в файле. Допустим, это будет простой текстовый файл “props.txt” со строками типа “ключ=значение”. Нам нужно гарантировать, что конфигурация в программе будет в единственном экземпляре. Вторую мы бы и так не создали, но нужно запретить это делать пользователю класса. Итак,
import java.util.*;
import java.io.*;
public class Configuration {
private static Configuration _instance = null;
private Properties props = null;
private Configuration() {
props = new Properties();
try {
FileInputStream fis = new FileInputStream(
new File(“props.txt”));
props.load(fis);
}
catch (Exception e) {
// обработайте ошибку чтения конфигурации
}
}
public synchronized static Configuration getInstance() {
if (_instance == null)
_instance = new Configuration();
return _instance;
}
// получить значение свойства по имени
public synchronized String getProperty(String key) {
String value = null;
if (props.containsKey(key))
value = (String) props.get(key);
else {
// сообщите о том, что свойство не найдено
}
return value;
}
}
Теперь для работы с конфигурацией можно использовать конструкцию вида:
String propValue = Configuration.getInstance()
.getProperty(propKey);
Если имена свойств в “props.txt” меняться не будут, можно описать их в классе таким образом:
public static final String PROP_KEY = “propKey”,
а значения получать так:
String propValue = Configuration.getInstance(). getProperty(Configuration.PROP_KEY).Так же Singleton частенько применяется для коннекта к базам данных...
На том пока все :)











Комментариев нет:
Отправить комментарий