តើអ្វីទៅដែលហៅថា Service Container?

PHP application ដ៏ទំនើបគឺពោពេញទៅដោយ objects ។ Object មួយអាចជួយសម្រួលដល់ការចែកចាយនូវសាររបស់អ៊ីម៉េលខណៈពេលដែល object ផ្សេងទៀតអាចនឹងអនុញ្ញាតអោយអ្នកបញ្ចូលព័ត៌មានទៅក្នុង database ។ ក្នុង application របស់អ្នក ប្រហែលជាអ្នកបង្កើតនូវ object ដែលគ្រប់គ្រងនូវបញ្ចីផលិតផលរបស់អ្នក រឺក៏ object ផ្សេងទៀតដែលដំណើរការនូវទិន្នន័យពីភាគី API ។ ចំនុចត្រង់នេះគឺ application សម័យថ្មីអាចធ្វើការងារជាច្រើននិងបានរៀបចំទៅជា objects ជាច្រើនដែលធ្វើការគ្រប់គ្រងលើការងារនីមួយៗ។

ក្នុងមេរៀននេះគឺនិយាយពី PHP object ពិសេសនៅក្នុង Symfony ដែលជួយអ្នកក្នុងការ instantiate រៀបចំ និងទទួលនូវ objects ជាច្រើននៃ application របស់អ្នក។ object នេះហៅថា service container នឹងអនុញ្ញាតអោយអ្នកនូវវិធីស្តង់ដារនិងរួមមួយនៃ objects គឺបង្កើតក្នុង application របស់អ្នក។ Container ធ្វើអោយអ្នកងាយស្រួល និងលឿនជាទីបំផុត និងសង្កត់់ធ្ងន់ទៅលើការស្ថាបនាដែលជំរុញនូវការប្រើប្រាស់ម្ដងទៀតនិងការបំបែកកូដ។ តាំងពី core Symfony classes ទាំងអស់ប្រើប្រាស់នូវ container នោះមកអ្នកត្រូវរៀនអំពីរបៀបនៃការ extend និង configure និង ប្រើ object ផ្សេងទៀតក្នុង Symfony ។ មួយចំណែកទៀតគឺ service container គឺជាអ្នកចូលរួមចំណែកដ៏ធំបំផុតក្នុងការពន្លឿននិងការពង្រីកនៃ Symfony។

ជាចុងក្រោយ ការ configure និងការប្រើប្រាស់នូវ service container គឺងាយស្រួលណាស់។ នៅចុងបញ្ចប់នៃជំពូកនេះ អ្នកនឹងអាចមានលិទ្ធភាពបង្កើត objects ដោយខ្លួនអ្នកផ្ទាល់តាមរយៈ container និងកែប្រែ object ពីភាគី bundle។

១ តើអ្វីទៅដែលហៅថា Service?

Service គឺជា PHP object ទាំងឡាយណាដែលដើរតួជា “global” task។ គោលបំណងរបស់វាគឺឈ្មោះត្រូវបានប្រើក្នុងកុំព្យូទ័រតាំងពីការបកស្រាយនូវ object ដែលបានបង្កើតសម្រាប់គោលបំណងជាក់លាក់ណាមួយ។ Service នីមួយៗគឺបានប្រើនៅទូទាំង application របស់អ្នកនៅពេលណាដែលអ្នកត្រូវការនូវមុខងារជាក់លាក់ដែលវាផ្ដល់អោយ។ អ្នកមិនចាំបាច់ធ្វើអ្វីផ្សេងទៀតនោះទេ អ្នកគ្រាន់តែសរសេរនូវ PHP class ជាមួយនឹងកូដខ្លះដែលអាចសម្រេចការងារជាក់លាក់មួយបាន។

ចំពោះ Services គឺមានអត្ថប្រយោជន៏ត្រង់ថាពេលដែលអ្នកចាប់ផ្ដើមគិតទៅលើការបំបែកជាផ្នែកនៃមុខងារក្នុង application ទៅក្នុង សេរីនៃ services។ តាំងពី service នីមួយៗធ្វើការងារមួយ អ្នកអាចងាយស្រួលចូលទៅកាន់ service នីមួយៗនិងប្រើមុខងាររបស់វានៅកន្លែងណាដែលអ្នកត្រូវការ។ Service នីមួយៗគឺងាយស្រួលក្នុងការតេស្តនិងconfigure ចាប់តាំងពីវាបានបំបែកខ្លួនចេញពីមុខងារផ្សេងទៀតក្នុង application របស់អ្នក។ គំនិតបែបនេះគេហៅថា service-oriented architecture និងមិនមែនមានលក្ខណៈតែមួយដូចទៅនឹង Symfony រឺក៏ event PHP នោះ។

២ អ្វីទៅដែលហៅថា Service Container?

Service Container គឺជា PHP object ដែលអាចគ្រប់គ្រងនូវ instantiation នៃ services ។ ឧទាហរណ៏៖ ឧបមាថាអ្នកមាន PHP class មួយដែលអាចចែកចាយនូវសាររបស់អ៊ីម៉េល។ ក្រៅពី service container អ្នកត្រូវបង្កើតនូវ object នៅពេលដែលអ្នកត្រូវការដោយដៃផ្ទាល់៖

sc1

ពេលនេះគឺងាយស្រួលណាស់។ Mailer class អាចអោយអ្នកធ្វើការ configure នូវ method ដែលប្រើក្នុងការចែកចាយនូវសារអ៊ីម៉េល (sendmail, smtc, និងមានផ្សេងទៀត) ប៉ុន្តែប្រសិនបើអ្នកត្រូវការប្រើនូវ mailer service នៅកន្លែងផ្សេងទៀត អ្នកត្រូវធ្វើយ៉ាងណា? អ្នកពិតជាមិនចង់ធ្វើការ configure នូវ mailer ម្ដងទៀតនោះទេនៅពេលដែលអ្នកចង់ប្រើប្រាស់នូវ Mailer object ។ តើអ្វីដែលអ្នកនឹងត្រូវកែប្រែ transport ពី sendmail ទៅជា smtp គ្រប់ទីកន្លែងក្នុង application របស់អ្នក? អ្នកនឹងធ្វើការកែប្រែគ្រប់កន្លែងដែលអ្នកបានបង្កើត Mailer service និងប្ដូរវា។

៣ ការបង្កើត និង configure Services នៅក្នុង Container

ចម្លើយដែលល្អបំផុតគឺអោយ service container បង្កើត Mailer object អោយអ្នក។ ដើម្បីអោយមានដំណើរការគឺអ្នកត្រូវ teach  នូវ container អំពីការបង្កើតនូវ Mailer service ។ ដើម្បីធ្វើបែបនេះបានគឺត្រូវធ្វើការ configure ដែលអាចបញ្ជាក់នៅក្នុង YAML, XML រឺក៏ PHP៖

sc2

ឧទាហរណ៏នៃ AppBundle\Mailer class គឺអាចប្រើប្រាស់បានតាមរយៈ service container។ Container គឺអាចប្រើបានក្នុង Symfony controller ដើមដែលជាកន្លែងដែលអ្នកអាចចូលទៅកាន់ services នៃ container តាមរយៈ get() shortcut method ។

sc3

ពេលអ្នកសួររក app.mailer service ពី container នោះ container នឹងបង្កើតនូវ object និងបញ្ជូនវាមក។ នេះជាជំនាញមួយនៃការប្រើប្រាស់ service container ។ Namely ជា service មួយដែលមិនបង្កើតឡើងនៅពេលដែលវាមិនត្រូវការ ហើយប្រសិនបើអ្នកកំណត់ service និងមិនដែលប្រើវានៅលើការស្នើទេ នោះ service គឺនឹងមិនបង្កើតឡើយ។ ដូចនេះវាអាចចំណេញ memory និងបង្កើននូវល្បឿននៃ application របស់អ្នក ទាំងនេះគឺមានន័យថា វាពិតជាតូចរឺក៏ គ្មានដំណើរការណាមួយដែលបង្ខំសម្រាប់ការកំណត់ នៃ services ជាច្រើន។ Services ណាដែលមិនធ្លាប់បានប្រើគឺជា service ដែលមិនធ្លាប់បានបង្កើត។

Service Parameters

ការបង្កើតនូវ services ថ្មី តាមរយៈ container គឺជាផ្លូវត្រង់ពេក។ ដូចនេះ Parameters ធ្វើអោយមានការកំណត់ services ច្រើនអោយមានរបៀបនិងមានភាពបត់បែន៖

sc4

លទ្ធចុងក្រោយគឺពិតជាដូចគ្នានឹងកាលពីមុន ភាពខុសគ្នាគឺមានតែ របៀបដែលអ្នកកំណត់នូវ service ។ ដោយមានការភ្ជាប់អក្សរ app.mailer.transport ជាមួយនឹងសញ្ញា (%) container ដឹងច្បាស់ថានឹងត្រូវធ្វើការលើ parameter ជាមួយនឹងឈ្មោះ។ ពេលដែល container បង្កើត គឺវាក្រលេកទៅមើលតម្លៃនៃ parameter នីមួយៗ និងប្រើវាក្នុង service definition ។

គោលបំណងនៃ parameters គឺផ្ដល់ព៌ត៏មានទៅកាន់ services ។ ជាការពិតគឺមិនមានអ្វីខុសឡើយជាមួយនឹងការកំណត់នូវ service ក្រៅពីការប្រើប្រាស់ parameters ផ្សេងទៀត។ Parameters គឺមានគុណសម្បត្តិច្រើនណាស់ដូចជា៖

ក/ ការបំបែកនិងរៀបចំ service “options” ទាំងអស់ស្ថិតនៅក្រោម single parameters key

ខ/ តម្លៃរបស់ parameter អាចនឹងប្រើក្នុង service definitions បានច្រើន

គ/ ពេលបង្កើត service ក្នុង bundle គឺការប្រើប្រាស់ parameters អនុញ្ញាតអោយ service មានការកែប្រែបានយ៉ាងងាយស្រួលក្នុង application របស់អ្នក។

ជម្រើសនៃការប្រើប្រាស់រឹមិនប្រើ parameters គឺអាស្រ័យទៅលើអ្នក។ គុណភាពខ្ពស់ ភាគីនៃ bundles នឹងប្រើតែ parameters ដូចដែលពួកគេធ្វើអោយ service រក្សាទុកក្នុង container បន្ថែមទៀត។ សម្រាប់ services ក្នុង application របស់អ្នក ទោះជាយ៉ាងណា អ្នកអាចនឹងមិនចាំបាច់ត្រូវការភាពបត់បែននៃ parameters ។

Referencing (Injecting) Services

ជាយូរណាស់មកហើយ app.mailer ដើមគឺមានលក្ខណៈសាមញ្ញ វាធ្វើការត្រឹមតែមួយអាគុយម៉ង់ក្នុង constructor របស់វាណាមួយដេលងាយស្រួលក្នុងការ configure។ ដូចដែលអ្នកបានឃើញហើយ ឥទ្ធិពលពិតនៃ container គឺបានដឹងពេលដែលអ្នកត្រូវការបង្កើត service មួយដែលផ្អែកទៅលើ services មួយរឺច្រើនផ្សេងទៀតក្នុង container។

ឧបមាថាអ្នកមាន service ថ្មីមួយ NewsletterManager ដែលជួយក្នុងការគ្រប់គ្រងនូវការរៀបចំនិងចែកចាយនូវ សារអ៊ីម៉េលទៅកាន់ អាស័យដ្ឋានដែលយើងបានចងក្រង។ ជាការពិត app.mailer service គឺពិតជាល្អណាស់ក្នុងការចែកចាយសារ ដូចនេះអ្នកអាចនឹងប្រើវាខាងក្នុង NewsletterManager ដើម្បីក្ដោបនូវការផ្ញើរសារ។ class មួយនេះគឺដូចទៅនឹងឧទាហរណ៏ខាងក្រោម៖

sc5

ក្រៅពីការប្រើប្រាស់ service container អ្នកអាចបង្កើត NewsletterManager ថ្មីមួយពីក្នុង controller៖

sc6

វិធីសាស្ត្រនេះគឺល្អ ប៉ុន្តែក្រោយមក ប្រសិនបើអ្នកសម្រេចចិត្តថា NewsletterManager class ត្រូវការ constructor argument ទី២ រឺទី៣ តើវាយ៉ាងម៉េចដែរ? តើមានអ្វីកើតឡើងបើអ្នកសម្រេចចិត្តក្នុងការrefactor កូដរបស់អ្នកនិងកែឈ្មោះនៃ class? ក្នុងបញ្ហាទាំង២នេះ អ្នកនឹងត្រូវការស្វែងរកកន្លែងជាច្រើនដែល NewsletterManager បានធ្វើការ instantiate និងកែប្រែវា។ ពិតណាស់ service container អោយអ្នកនូវ option ជាច្រើន៖

sc7