Як правильно здійснити глобальне використання в додатку express stack overflow російською

Коротко про структуру того що є. При запуску програми

Рядок require ( 'socket') (server) - підключає файл:

Тепер, ближче до справи, в додатку є контролери які успадковані від базового:

І, допустимо, є необхідність всередині methodForPage () послати повідомлення приблизно таким чином:

Але, змінна socket доступна тільки всередині io.on ( 'connection'). Як її зробити доступною всередині контролера? Або як визначити її всередині базового контролера щоб вона була таким чином доступною в усіх контролерів?

І, є ще один момент, наприклад є необхідність всередині контролера встановити подія socket'a, наприклад так:

І при цьому ми хочемо використовувати властивості цього контролера щоб здійснювати, наприклад, запис даних отриманих з сокета в базу даних.

Чи можна все перераховане вище реалізувати в такому вигляді і якщо так, то що для цього потрібно зробити? Чи правильний це підхід?

заданий 22 дек '15 о 9:55

Тут маса варіантів. Я віддаю перевагу архітектуру у вигляді дерева, де є щось на зразок god object, з якого доступні всі модулі, який виконує роль диспетчера між ними і єдиної точки доступу для всіх частин пріложенія.Обично він у мене або лежить в global, або передається в усі конструктори / модулі. Але не факт що це найкраще рішення, для кожного конкретного випадку потрібно окремо дивитися. Будемо сподіватися, що вам напишуть повноцінну відповідь на цю тему. - Darth 22 дек '15 о 10:55

Ви зіткнулися з характерною для ООП підходу проблемою: звідки брати залежності?

Є кілька варіантів вирішення проблеми. Найочевиднішим є використання глобальних змінних. але цей варіант підходить тільки для дуже маленьких проектів або проектів, які не потрібно підтримувати. Про те, чому шкідливі глобальні змінні написано вже дуже велика кількість різних статей. Всі проблеми виходять з одного дуже простого факту: код стає занадто сильно пов'язаним (tight coupling). Як наслідок це виливається в неможливість повторного використання коду, проблеми з модульним тестуванням, складність в налагодженні додатків та інше. У середніх і великих проектах все це призводить через деякий час до такої каші, що стає простіше переписати все з нуля.

Слідуючи цьому підходу, ви повинні зробити наступне:

Повертаєте екземпляр socket.io з функції, що експортується в файлі socket.js:

Оголошуєте екземпляр socket.io явною залежністю базового контролера (або якогось агрегатора маршрутів):

Чи використовуєте екземпляр socket.io в дочірніх контролерах (або реальних маршрутах):

В основному файлі проекту передаєте залежності в явному вигляді (можна використовувати DI контейнер, але це мені здається дещо надмірною):

Дякую вам, за дуже корисний і відповідаю розгорнуто! Я поки ще не спробував ваш рада на практиці, але поглянувши на код, у мене виникає питання, це стосується п. 4. Тут ви пишете, що в пусковому файлі проекту, ми підключаємо дочірній контролер і передаємо в нього примірник socket.io для ініціалізації , але справа в тому, що в моєму проекті контролери завжди инициализируются в Рауса: router.get ( "/ fooBar", function (req, res) ); - sanu0074 23 дек '15 о 16:04

І я не зовсім розумію як це буде працювати, і чому необхідно ініціалізувати дочірні контролери в основному файлі проекту (їх же може бути дуже багато), і як в них потім потрапить req і res? Можливо я неправильно все роблю, і структура проекту неправильно побудована, дуже хотів би щоб ви направили мене на правильний шлях! - sanu0074 23 дек '15 о 16:04