Шаблон проектирования Singleton — один из наиболее важных и часто используемых в программировании. Это гарантирует, что класс будет иметь только один экземпляр во время выполнения приложения, и предоставляет глобальную точку доступа к этому экземпляру. В этой статье мы обсудим важность Singleton, способы его реализации в Golang и преимущества, которые он приносит, особенно в параллельных средах.
Синглтон — это шаблон проектирования, который ограничивает экземпляр класса одним экземпляром. Это особенно полезно в ситуациях, когда требуется единая точка управления или один общий ресурс, например:
Я собираюсь перечислить некоторые моменты реализации из Pattern, которые имеют больше смысла, а также показать, что не все так радужно, и некоторые проблемы, с которыми мы можем столкнуться.
Для реализации синглтона я буду использовать Golang. В этом языке мы должны уделять особое внимание параллелизму, чтобы гарантировать создание только одного экземпляра, даже когда несколько горутин пытаются получить доступ к экземпляру одновременно.
Чтобы приблизить наш пример к реальному миру, давайте создадим Logger для нашего приложения. Регистратор — это распространенный инструмент в приложениях, который должен быть уникальным, чтобы обеспечить согласованность журналов.
Сначала мы определяем структуру, которую хотим иметь в единственном экземпляре.
package logger import ( "fmt" "sync" ) type Logger struct {} var loggerInstance *Logger
Функция NewInstance отвечает за возврат единственного экземпляра структуры Singleton. Мы используем мьютекс для обеспечения безопасности в параллельных средах, реализуя блокировку с двойной проверкой для повышения эффективности.
package logger import ( "fmt" "sync" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new Logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger }
Инструмент журнала всегда имеет несколько типов журналов, например «Информация», чтобы просто показать информацию, «Ошибка», чтобы показать ошибки и так далее. Это также способ отфильтровать тип информации, которую мы хотим отображать в нашем приложении.
Итак, давайте создадим метод, который будет отображать наш журнал с типом Info. Для этого мы создадим функцию, которая будет получать наше сообщение журнала и форматировать его в формат INFO.
package logger import ( "fmt" "sync" "time" ) const ( INFO string = "INFO" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger } func (l *Logger) Info(message string) { fmt.Printf("%s - %s: %s\n", time.Now().UTC().Format(time.RFC3339Nano), INFO, message) }
И чтобы использовать наш новый регистратор, мы создадим его экземпляр в нашем основном пакете и создадим журнал, чтобы увидеть, как работает эта реализация.
package main import ( "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") }
Это результат запуска программы:
Creating new logger 2024-07-03T19:34:57.609599Z - INFO: This is an example of log
Если мы хотим проверить, действительно ли NewInstance гарантирует, что у нас будет работать только один экземпляр, мы можем провести следующий тест.
package main import ( "fmt" "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") log2 := logger.NewInstance() log2.Info("This is another example of log") if log == log2 { fmt.Println("same instance") } else { fmt.Println("different instance") } }
Наши журналы изменились, и теперь мы видим, что заблокировали создание нового экземпляра:
Creating new logger 2024-07-03T19:45:19.603783Z - INFO: This is an example of log Logger already created 2024-07-03T19:45:19.603793Z - INFO: This is another example of log same instance
Шаблон Singleton — это мощный инструмент, позволяющий гарантировать, что во время выполнения приложения существует только один экземпляр определенного класса. В примере с регистратором мы увидели, как можно применить этот шаблон для обеспечения согласованности журналов во всем приложении.
Надеюсь, это поможет вам лучше понять Синглтон в Golang.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3