Sunday, August 7, 2011

Enterprise Software Architecture : II


အပိုင္း−၂
Factory Pattern

Factory Pattern ဆိုတာ Design Pattern တခုပါပဲ။ သူ ့ရဲ့ ရည္ရြယ္ခ်က္ကေတာ့ object creating ဆိုတဲ့ ရႈပ္ေထြးလွတဲ့ အပိုင္းကို တာဝန္ယူဖို ့ သက္သက္ပါ။ ဆိုလို တာကဗ်ာ ေရွ ့မွာကြ်န္ေတာ္တို ့ ေဆြးေနြးခဲ့တဲ့ Constructor Dependency Injection မွာ တုန္းကလို Client လုပ္ရမယ့္ အလုပ္ေတြကို ကိုယ္စားေဆာင္ရြက္ ေပးမယ့္ Stand alone class တခုပါပဲ။
သူက မ်ားေသာအားျဖင့္ static method ေတြကိုပဲ သံုးေလ့ရိွတယ္။ အဲဒီ method က client အတြက္ လိုအပ္တဲ့ object ကို ready-made ပံ့ပိုးေပးတယ္ေပါ့ဗ်ာ။

[စကားမစပ္
အခုေလ့လာေနတာက Enterprise level ဆိုေတာ့ ခု ေရးသားတင္ျပခဲ့တဲ့ / ေရးသားတင္ျပမယ့္ sample code ေတြရဲ့ UML diagram, Class diagram ေတြဘာေတြကို Reverse Engineering နည္းကို သံုးျပီး စိတ္ထဲက ဆဲြနိုင္ ျမင္နိုင္ တဲ့ အဆင့္လို ့ ယူဆထားပါတယ္။

ဒါ့အျပင္ static method နဲ ့၊ instance method စတာေတြ ဘာ ကြာတယ္ဆိုတာ ေတာ့ ဒီ အဆင့္မွာ ေကာင္းစြာ သိျပီးျဖစ္မယ္လို ့ ယံုၾကည္ယူဆထားပါတယ္။

မရွင္းတာရိွလည္း မွတ္ခ်က္ေလးဘာေလးေပးျပီး ေအာ္သြားေပါ့ဗ်ာ။ လိုအပ္သလို ျဖည့္စြက္ တင္ျပေပးပါမယ္။]

ကဲေျပာေနတာက ရႈပ္ေနဦးမယ္
ေဟာဒီမွာ ၾကည့္လိုက္ဗ်ာ...။

using IoCContainer.Model.Maps;
using IoCContainer.Model.PlaceOfInterests;

namespace IoCContainer.Model
{
    public static class TouristInformationServiceFactory
    {
        public static TouristInformationService getTouristServiceSatelliteMapEnglish()
        {
            return new TouristInformationService(
                new SatelliteMap(),
                new EnglishPlaceOfInterestDictionary());
        }
    }
}


အဲဒီေတာ့ဗ်ာ...
ဒီတခါ client က TouristInformationService ကို သံုးခ်င္ရင္ Map တို ့ PlaceOfInterest တို ့ ရဲ့ object ေတြကို သူကိုယ္တိုင္ create လုပ္ေနစရာမလိုပဲ [သိေတာင္ သိစရာမလိုပဲ] Factory class က တိုက္ရိုက္ေခၚသံုးလိုက္ရံုပဲေပါ့ဗ်ာ။
ေဟာဒီလို

using IoCContainer.Model;

namespace IoCContainer.ServiceConsumer
{
    public class ClientThatUsesService
    {
        TouristInformationService touInfoService;
        //..
        //..
        //..
        //..
        public void initializeServiceObject()
        {
            touInfoService = TouristInformationServiceFactory.getTouristServiceSatelliteMapEnglish();
            //..
            //..
            //..
        }

        //..
        //..
        //..
    }
}

ပိုျပီးေတာ့ loosely coupled ျဖစ္မလာေပဘူးလားဗ်ာ။
-Client ဟာ TouristInformaionService ကို ဘယ္လို create လုပ္ရမယ္ဆို တဲ့ အေသးစိတ္ေတြ သိစရာမလိုေတာ့ဘူး
-ျပီးေတာ့လည္း client ေပါင္းေျမာက္မ်ားစြာက အလြယ္တကူ လွမ္းေခၚျပီးသံုးလို ့ ရလာျပီ

Service Implementation နဲ ့ Client  က အခုအခါ ေတာ္ေတာ္ေလး Decoupling ျဖစ္သြားျပီ။ ဒါဆိုရင္ မိတ္ေဆြတို ့က ထင္မွာပဲ..အိုေကျပီေပါ့...။ အင္း ခက္တာက အရာတိုင္းဟာ ထင္သလို ထင္သေလာက္ အဆင္ေျပေလ့ မရိွတာပဲ။

ဘာလို ့လဲဆိုေတာ့ဗ်ာ..
ခုကြ်န္ေတာ္တို ့ sample implementation မွာ ေဆြးေနြးေနတာက
-Map ဆိုရင္ SatelliteMap တမို်းတည္း
-PlaceOfInterest ဆိုရင္လည္း EnglishPlaceOfInterest တမို်းတည္း အတြက္ပဲ ရိွေသးတာကိုး။

တကယ္တန္းကြ်န္ေတာ္တို ့ implement လုပ္ရမွာက
ကြ်န္ေတာ္တို ့ေရွ ့မွာေဆြးေနြးခဲ့သလို ဒီ service ဟာ
- နိုင္ငံေပါင္းစံု၊
- ေျမပံု ပံုသ႑ာန္ေပါင္းစံု ကို support လုပ္နိုင္ေအာင္ ေရးရမွာ။

Map ဆိုရင္လည္း SatelliteMap, RoadMap, GraphicMap, NonGraphicMap စသည္ျဖင့္ ပံုသ႑ာန္ အမို်းမို်း support လုပ္နိုင္ရမယ္...။ ပံုနဲ့ အၾကမ္းျဖင္းေျပာရရင္ ဒီလိုမို်းဗ်ာ...။








ျပီးေတာ့လည္း PlaceOfInterest ဆိုရင္လည္း နိုင္ငံေဒသအသီးသီးအတြက္ Support လုပ္ရမွာျဖစ္ေတာ့...ဒီလိုမို်းျဖစ္လာမယ္ဗ်ာ။ ဒါေတာင္ အကုန္မဟုတ္ေသးဘူးေနာ္...။ သေဘာေပါက္ရံု ျမင္သာရံု ေနာက္ နွစ္နိုင္ငံစာေလာက္ထည့္ လိုက္တာပဲရိွေသးတယ္။






ကဲ..အခုမိတ္ေဆြတို ့ ဘာကို သတိထားမိလာသလဲ။
[ဘာမွ သတိမထားမိပါဘူးဗ်ာ...ခင္ဗ်ားေျပာလို ့သာပါပဲ... :-) ;-) ]

ဒီလိုဗ်ာ..။
တကယ္လို ့ Client က
EnglishPlaceOfInterest ကို SatelliteMap နဲ ့လိုခ်င္တယ္။ အဲဒီအခါ sample code မွာျပထားသလို service object ကို create လုပ္လိုက္တာေပါ့။

ဒါေပမယ့္ client က SatelliteMap ကို ၾကည့္ ရတာ သိပ္မရွင္းဘူးျဖစ္ေနတယ္ဗ်ာ။ ခု တခါ သူလိုခ်င္တာ က
EnglishPlaceOfInterest ကို ပဲ RoadMap နဲ ့ ၾကည့္ခ်င္တယ္။

ဒါဆို ဘယ္လိုလုပ္မလဲ...။ Factory class ထဲမွာ ေဟာဒီလို function တခု တိုးလာမွာေပါ့...

public static TouristInformationService getTouristServiceRoadMapEnglish()
        {
            return new TouristInformationService(
                new RoadMap(),
                new EnglishPlaceOfInterestDictionary());
        }

တကယ္လို ့ NonGraphicalMap နဲ ့ လိုခ်င္ရင္

public static TouristInformationService getTouristServiceNonGraphicalMapEnglish()
        {
            return new TouristInformationService(
                new NonGraphicalMap(),
                new EnglishPlaceOfInterestDictionary());
        }



-ဒါ့အျပင္ ဒီ service ကို သံုးမယ့္ client ကလည္း သူလိုခ်င္တဲ့ object အေျခအေနေပၚမူတည္ျပီး သက္ဆိုင္ရာ function ကို ေျပာင္းျပီး ေခၚရမွာေပါ့...။

-ဒါေတာင္ ဒီဥပမာဟာ ဒါဟာ တနိုင္ငံတည္း အတြက္ပဲရိွေသးတယ္ဗ်။ နိုင္ငံေပါင္းစံု အတြက္ဆို So many different variants ေတြ ျဖစ္လာမွာေပါ့။

ဒါေၾကာင့္ ဒီ Factory pattern မွာ
၁။ Factory class ဟာ တကယ္ေတာ့ flow တူ ပံုစံတူတဲ့ object ေပါင္းမ်ားစြာအတြက္ (ခပ္ဆင္ဆင္)တူတဲ့ function ေပါင္းမ်ားစြာ ေရးေနရတယ္။ တကယ္ေတာ့ ဒါဟာ Dirty Job ေပါ့။
၂။ Client ကိုယ္တိုင္ လည္း Factory class နဲ ့ ခုအခါ tightly coupled ျဖစ္ေနျပန္ျပီ။ ဘာလို ့လဲဆိုေတာ့ဗ်ာ
client က သူလို တဲ့ object အေျခေနကို Well Aware ျဖစ္ရေတာ့မွာကိုး။ ဆိုလိုတာက GermanPlaceOfInterest ကို RoadMap နဲ ့လိုခ်င္တာလား၊ NewYorkPlaceOfInterest ကို GraphicMap နဲ ့ လိုခ်င္တာလား.....စသည္ျဖင့္ လိုအပ္ခ်က္ေပၚမူတည္ျပီး ...မတူကဲြျပားတဲ့ function ေတြကို Factory class က ေခၚရမွာကိုး...။


ဒါေၾကာင့္ ဒီအခက္အခဲ ကို ဘယ္လိုေက်ာ္လွြားမလဲဆိုတာကို Enterprise Software Architecture : III ရဲ့ Service Locator Pattern မွာ ဆက္လက္တင္ျပပါ့မယ္။

ရွြင္လန္းခ်မ္းေျမ့ပါေစ။

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.