Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа. Существенно то, что можно пользоваться именно экземпляром класса, так как при этом во многих случаях становится доступной более широкая функциональность. Например, к описанным компонентам класса можно обращаться через интерфейс, если такая возможность поддерживается языком.
Плюсы
- контролируемый доступ к единственному экземпляру;
- уменьшение числа имён;
- допускает уточнение операций и представления;
- допускает переменное число экземпляров;
- бо?льшая гибкость, чем у операций класса.
Минусы
- Глобальные объекты могут быть вредны для объектного программирования, в некоторых случаях приводя к созданию немасштабируемого проекта.
- Усложняет написание модульных тестов и следованию TDD
Применение
- должен быть ровно один экземпляр некоторого класса, легко доступный всем клиентам;
- единственный экземпляр должен расширяться путем порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода.
Пример реализации на ABAP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
REPORT ztest_singleton_pattern. * *----------------------------------------------------------------------* * CLASS lcl_application DEFINITION *----------------------------------------------------------------------* CLASS lcl_application DEFINITION CREATE PRIVATE.* PUBLIC SECTION. * Cтатический метод возвращающий ссылку на объект одиночку CLASS-METHODS: get_apps_instance RETURNING VALUE(ro_apps) TYPE REF TO lcl_application.* METHODS: set_v_name IMPORTING iv_name TYPE char30, get_v_name RETURNING VALUE(rv_name) TYPE char30.* PRIVATE SECTION. * Статическая переменная будет хранить экземпляр класса одиночки CLASS-DATA: lo_apps TYPE REF TO lcl_application. DATA: v_name TYPE char30. ENDCLASS. "lcl_application DEFINITION * * *----------------------------------------------------------------------* * CLASS lcl_application IMPLEMENTATION *----------------------------------------------------------------------* CLASS lcl_application IMPLEMENTATION. * * Метод возвращает экземпляр объекта одиночки METHOD get_apps_instance. IF lo_apps IS INITIAL. * Создание объекта CREATE OBJECT lo_apps. ENDIF. ro_apps = lo_apps. ENDMETHOD. "get_apps_instance * METHOD set_v_name. me->v_name = iv_name. ENDMETHOD. "set_v_name * METHOD get_v_name. rv_name = me->v_name. ENDMETHOD. "get_v_name * ENDCLASS. "lcl_application IMPLEMENTATION * * START-OF-SELECTION. * *.Создаем 1-й экземпляр объекта DATA: lo_application TYPE REF TO lcl_application. DATA: lv_result TYPE char30. * WRITE: / 'Приложение 1: '. * CREATE OBJECT запрещен т.к. создание объекта объявлено как CREATE PRIVATE lo_application = lcl_application=>get_apps_instance( ). * Установим имя объекту lo_application->set_v_name( 'This is first Object' ). lv_result = lo_application->get_v_name( ). WRITE: / lv_result. CLEAR lv_result. * *.Создадим вторую ссылку на объект DATA: lo_2nd_apps TYPE REF TO lcl_application. SKIP 2. WRITE: / 'Второе приложение : '. * Вызывая метод получаем ранее созданный объект lo_2nd_apps = lcl_application=>get_apps_instance( ). lv_result = lo_2nd_apps->get_v_name( ). WRITE: / lv_result. CLEAR lv_result. |
Оригинальный пример был взят отсюда.