Добрый день,
Уважаемые javarushевцы!
По мере изучения java, все чаще и чаще начал сталкиваться с таким понятием, как паттерны(или шаблоны) проектирования, но на просторах интернета очень мало информации на эту тему для... начинающих программистов. Проще говоря - чайников (кем я и являюсь).
Я решил уделить немного времени и постараться рассказать про некоторые из них как можно более просто. Они же встречаются нам по мере продвижения на курсе javarush:
- Singleton / Одиночка
- Wpapper / Decorator / Обертка
- Adapter / Адаптер
- Strategy / Стратегия
- Ведение логов Объект, который отвечает за запись логов. Нам необходим только один экземпляр, так как нужно писать лог, используя один и тот же файл.
- Хранение настроек Объект с настройками нужен только один, так как для всей программы настройки одни и те же.
- Cоздаем единственный экземпляр некоторого типа
- Предоставляем к нему доступ извне
- Запрещаем создание нескольких экземпляров того же типа
- С ленивой инициализацией*, не синхронизированный
- Синхронизированный
public class NonSynchronizedSingleton {
private static NonSynchronizedSingleton instance;
private NonSynchronizedSingleton(){}
public static NonSynchronizedSingleton getInstance(){
if(instance == null) instance = new NonSynchronizedSingleton();
return instance;
}
}
Делаем приватным наш инстанс(объект) класса, чтобы запретить напрямую к нему обращаться
private static NonSynchronizedSingleton instance;
Также делаем приватным конструктор, чтобы наш синглтон и через конструктор было не создать
private NonSynchronizedSingleton(){}
Теперь создаем метод(работать он будет, как геттер)
public static NonSynchronizedSingleton getInstance()
Присваиваем ему модификатор доступа public - глобальный, то есть, теперь мы из любого места можем воспользоваться нашим singleton. В этом методе мы запрашиваем объект данного класса - если объекта еще нет, создаем его, если он уже есть, получаем его же.
Обращаемся к нашему объекту мы таким образом
NonSynchronizedSingleton.getInstance()
Плюсы/Минусы:
Данный вариант реализации хорош всем, кроме того, что он не работает в многопоточной среде, а поэтому подходит исключительно для однопоточных приложений. Почему? Потому что несколько нитей могут одновременно создать объекты данного класса.
2. Синхронизированный
public class SynchronizedSingleton {
private static SynchronizedSingleton instance = new SynchronizedSingleton();
private SynchronizedSingleton(){}
public static SynchronizedSingleton getInstance(){
return instance;
}
}
Описание:
Создаем переменную
private static SynchronizedSingleton instance = new SynchronizedSingleton();
Но делаем ее приватной, чтобы никто к ней обратиться напрямую не мог.
Конструктор тоже приватный
private SynchronizedSingleton(){}
Ну и для работы с объектом создаем метод(геттер), который возвращает нам наш объект
public static SynchronizedSingleton getInstance(){
Плюсы:
Проблему многопоточности мы решили, так как static переменная инициализируется сразу же во время инициализации класса, и сколько бы нитей одновременно ни обратились, получат всегда один и тот же объект.
Минусы:
Теперь у нас нет отложенной инициализации (Объект instance будет создан classloader-ом во время инициализации класса)
Итог:
public class Test {
public static void main(String[] args) {
NonSynchronizedSingleton nonSynchronizedSingleton = NonSynchronizedSingleton.getInstance();
NonSynchronizedSingleton secondNonSynchronizedSingleton = NonSynchronizedSingleton.getInstance();
SynchronizedSingleton synchronizedSingleton = SynchronizedSingleton.getInstance();
SynchronizedSingleton secondSynchronizedSingleton = SynchronizedSingleton.getInstance();
System.out.println(nonSynchronizedSingleton.hashCode());
System.out.println(secondNonSynchronizedSingleton.hashCode());
System.out.println(nonSynchronizedSingleton.equals(secondNonSynchronizedSingleton));
System.out.println(synchronizedSingleton.hashCode());
System.out.println(secondSynchronizedSingleton.hashCode());
System.out.println(synchronizedSingleton.equals(secondSynchronizedSingleton));
Car car1 = new Car();
Car car2 = new Car();
System.out.println(car1.hashCode());
System.out.println(car2.hashCode());
System.out.println(car1.equals(car2));
}
public static class Car {}
}
Пытаемся создать больше одного объекта в каждой реализации, но на выходе получаем один и тот же объект: хешкоды равны, equals возвращает true.
Для примера создал класс
public static class Car {}
И сравнил хешкоды, equals двух объектов данного класса(уже не singleton) - хешкоды разные, equals возвращает false
1956725890
1956725890
true
356573597
356573597
true
1735600054
21685669
false
Плюсы:
//TODO
Минусы:
//TODO
Wpapper / Decorator / Обертка
Описание:
//TODO
Что такое
Зачем нужен
Примеры
Порядок действий:
//TODO
Код:
//TODO
Плюсы:
//TODO
Минусы:
//TODO
Adapter / Адаптер
Описание:
//TODO
Что такое
Зачем нужен
Примеры
Порядок действий:
//TODO
Код:
//TODO
Плюсы:
//TODO
Минусы:
//TODO
Strategy / Стратегия
Описание:
//TODO
Что такое
Зачем нужен
Примеры
Порядок действий:
//TODO
Код:
//TODO
Плюсы:
//TODO
Минусы:
//TODO
При изучении тем использовал
- http://www.programcreek.com/java-design-patterns-in-stories/
- http://habrahabr.ru/post/103681/
- http://habrahabr.ru/post/116577/
- http://habrahabr.ru/post/129494/
- http://cpp-reference.ru/patterns/catalog/
- https://ru.wikipedia.org/wiki/%D0%9E%D1%82%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F
- http://habrahabr.ru/post/27108/
- http://www.amse.ru/courses/cpp1/2010.03.05.html
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ