Saturday, August 13, 2011

Quantum Computing မိတ္ဆက္

He begins working calculus problems in his head as soon as he awakens. He did calculus while driving in his car, while sitting in the living room, and while lying in bed at night.
—Mary Louise Bell divorce complaint

သူဟာ အိပ္ရာက နိုးတာနဲ့ ကဲကုလပ္စ္ျပႆနာေတြကို စ စဉ္းစားျပီ။ ကားေမာင္းေနရင္းနဲ့လည္း ကဲကုလပ္စ္။ ဧည့္ခန္းထဲထိုင္ေနတဲ့ အခိ်န္လည္း ကဲကုလပ္စ္။ ေနာက္ဆံုး ညအိပ္ရာဝင္တဲ့ အခိ်န္ေတာင္ ဒီ ကဲကုလပ္စ္ အေၾကာင္းပဲ စဉ္းစားေနတာ..။

[ရူပေဗဒပညာရွင္ ရစ္ခ်တ္ဖိုင္းမန္း ၏ ဒုတိယဇနီး ေမရီလူစီဘဲလ္ က လင္မယား ကြာရွင္းခြင့္အတြက္ တရားရံုးတြင္ေလ်ာက္ထားေသာ စကား။]


***********************************************
Quantum Computing မိတ္ဆက္

နိုဘယ္ဆုရ ကမၻာေက်ာ္ အေမရိကန္ ရူပေဗဒပညာရွင္ ရစ္ခ်တ္ဖိုင္းမန္း Richard Phillips Feynman (May 11, 1918 – February 15, 1988) က၊ quantum mechanics ရဲ့အကို်းသက္ေရာက္မႈေတြကို ထိထိေရာက္ေရာက္ အသံုးျပုနိုင္မယ့္ computer တစ္မို်း ၊ တနည္းေျပာရရင္ေတာ့ quantum computer အေၾကာင္းကို ၁၉၈၂ ခုနွစ္ေလာက္မွာ စတင္ျပီး စိတ္ကူးၾကံစည္ခဲ့ပါတယ္။

ကေန ့အခါမွာ ကြန္ပူ်တာ ပေရာဆက္ဆာေတြ ထုတ္လုပ္ရာမွာ VLSI (Very-large-scale integration) နည္းပညာကို အသံုးျပုထားတဲ့ အတြက္ေၾကာင့္ ကြန္ပူ်တာေတြရဲ့ လုပ္ေဆာင္နိုင္မႈ အျမန္နႈန္းစြမ္းရည္ (performance) ဟာ တေန ့တျခားတိုးတက္လာေနတယ္ဆိုတာ မိတ္ေဆြတို ့ သတိထားမိမွာပါ။ မိတ္ေဆြ တို ့ သိတဲ့အတိုင္းပဲ [ေဟ့..ေဟ့..ဒို ့ ဘာမွမသိဘူးေနာ္..:-)] VLSI ဆိုတာ ကြန္ပူ်တာ processor ရဲ့ circuit မွာ transistors ေပါင္း၊ ေထာင္ ေသာင္း သိန္း သန္း ခီ်ျပီး ထည့္သြင္းတည္ေဆာက္ တဲ့ နည္းပညာကိုးဗ်။

ဒါေၾကာင့္..

-Computer Processor ကို မ်ားမ်ား Powerful ျဖစ္ေအာင္ transistors မ်ားမ်ားထည့္ရမယ္။

-(Processor အရြယ္အစားကို ကိန္းေသထားမယ္ဆိုရင္ေတာင္)

Processor တခုမွာ transistors မ်ားမ်ားထည့္နိုင္ဖို ့ transistors ရဲ့ အရြယ္အစားကို ေသးငယ္သည္ထက္ ေသးငယ္ေအာင္ လုပ္ရမွာေပါ့။

-ေနာက္တဆင့္အေနနဲ ့ Processor အရြယ္အစားကိုပါ  ပိုမို ေသးငယ္လာေစခ်င္ရင္...

transistors  အရြယ္အစားဟာ ေသးသည္ထက္ေသး ေသးသည္ထက္ေသး ေသးလာရမွာေပါ့။

ေအးဗ်ာ…အဲဒီမွာ စေတြ ့တာပဲ [ဓါတ္တိုင္နဲ ့ မခိုင္ နဲ ့ ;-)]။

-transistors ရဲ့ အရြယ္အစားကို ဘယ္ေလာက္အကန္ ့အသတ္ထိ ေသးငယ္နိုင္မလဲ။ တနည္းေျပာရရင္ အေသးဆံုး ထားနိုင္မယ့္အရြယ္အစား။ အဲဒီထက္ ထပ္ ေသးငယ္လို ့မရေတာ့တဲ့ အေနအထား ဆိုတဲ့ Calculus ရဲ့ limit, minimum, maximum ဆိုတဲ့ သေဘာတရားေတြ..။

-အရာဝတၳုေတြဟာ ေသးလြန္းမက ေသးငယ္လာတဲ့အခါ သူ ့ရဲ့ လားရာ အျပုအမူ အကို်းသက္ေရာက္မႈေတြဟာ ခန္ ့မွန္းတြက္ခ်က္ဖို ့ခက္လာျပီး မေသခ်ာ မေရရာျဖစ္လာတယ္ ဆို တဲ့ quantum mechanics ရဲ့ သီအိုရီေတြ နဲ ့

-လက္ရိွ ရိွျပီးသား Computer Science theory ေတြ ေပါင္းစပ္ ရေတာ့မယ့္ အေျခအေနကို ဆိုက္ေရာက္လာျပီကိုး ဗ်။

ကြ်န္ေတာ္တို့ဟာ ရူပေဗဒတို ့ သခၤ်ာတို ့ ကို အတိုင္းအတာတရပ္အထိ ေျခေျချမစ္ျမစ္ ေလ့လာသိရိွထားမယ္ဆိုရင္ အခု ေဆြးေနြးမယ့္ Quantum Computing အေၾကာင္းဟာ ေတာ္ေတာ္ေလး ရသေျမာက္မယ့္ အားတက္စရာ စိတ္လႈပ္ရွားစရာ စိတ္ဝင္စားစရာ ေခါင္းစဉ္တခုပါ။ အခု ကမၻာမွာ ပညာရွင္ေတြ ေတာ္ေတာ္ေလး က်ယ္က်ယ္ျပန္ ့ျပန္ ့ က်ယ္က်ယ္ေလာင္ေလာင္ ေျပာဆိုေရးသား ေဆြးေနြးေနၾကပါျပီ။

ဒါေၾကာင့္ ဒီေဆာင္းပါးကို ေရွ ့မဆက္ခင္ မိတ္ေဆြတို ့အေနနဲ ့ အေျခခံ calculus သေဘာတရားေလးဘာေလး အေျခခံ quantum mechanics ဗဟုသုတေလးဘာေလး အရင္ဆံုး ဖတ္ရႈေလ့လာ အားျဖည့္ထားလိုက္ပါဦးလို ့ ေလးေလးစားစား တိုက္တြန္းလိုက္ပါရေစခင္ဗ်ာ။ ကြ်န္ေတာ္ ဆက္ေရးမယ့္ Quantum Computing ရဲ့ တကယ့္အေျခခံမိတ္ဆက္ အဆင့္ေလာက္အတြက္ေတာ့ အဲဒါေတြ မျဖစ္မေန လိုအပ္တယ္လို ့ မဆိုလိုပါဘူး။ ဒါေပမယ့္...။

(ဆက္လက္တင္ျပပါမည္။)

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

[ျခိမ့္ထက္]


References:
http://www.doc.ic.ac.uk/~nd/surprise_97/journal/vol4/spb3/
http://en.wikipedia.org/wiki/Richard_Feynman

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 မွာ ဆက္လက္တင္ျပပါ့မယ္။

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

Saturday, August 6, 2011

Enterprise Software Architecture : I


(မွတ္ခ်က္။ ဒီအပိုင္းကို ေကာင္းေကာင္းနားလည္ သေဘာေပါက္နိုင္ဖို့ အတြက္ Dependency Injection Design Pattern ကို အရင္ဆံုး သိရိွနားလည္သေဘာေပါက္ျပီးျဖစ္သင့္ပါတယ္။)

အပိုင္း-၁
Constructor Dependency Injection
[Service provider class ၏ Constructor သို့၎အတြက္ လိုအပ္ေသာ Object မ်ားေပးသြင္းျခင္း]


ဆိုပါစို့ ကြ်န္ေတာ္တို့ဟာ အခု ကမၻာလွည့္ ခရီးသြားလာေရးလုပ္ငန္း တစ္ခုအတြက္ Application Service တခုေရးမယ္ဆိုပါစို ့ဗ်ာ။ အလြယ္ဆံုး အရိုးရွင္းဆံုး simple and plain structure ကိုပဲ စျပီး စဉ္းစားၾကည့္ၾကစို ့။ service name ကို TouristInformationService လို ့ အမည္ေပးလိုက္တာေပါ့။

၁။ ဒီ service မွာ ေနရာေဒသ Location ကို ျပမယ့္ ေျမပံု ပါမယ္။
၂။ ျပီးရင္ စိတ္ဝင္စားစရာ ေနရာေတြ အေၾကာင္းပါမယ္။ ဒါပဲ။


ကဲ အဲဒီေတာ့ ပထမဆံုး လိုအပ္တဲ့ ေျမပံု class ကို model အေနနဲ ့ create လုပ္လိုက္ဗ်ာ။ [ဘာေၾကာင့္ Interface ကို သံုးတာလဲ...ဒီ class ဟာ view လား model လား controller/service လား ဆိုတာေတြကို ေတာ့ သိျပီးျဖစ္မယ္လို ့ ေမွ်ာ္လင့္ပါတယ္။]


namespace IoCContainer.Model.Maps
{
    public interface IMap
    {
        void Set(Location currentLocation);
        void Add(PlaceOfInterests.PlaceOfInterest placeOfInterest);
        bool CurrentLocationIsNear(PlaceOfInterests.PlaceOfInterest placeOfInterest);
    }
}

namespace IoCContainer.Model.Maps
{
    public class SatelliteMap : IMap
    {
        public void Set(Location currentLocation)
        {
       
        }

        public void Add(PlaceOfInterests.PlaceOfInterest placeOfInterest)
        {
       
        }

        public bool CurrentLocationIsNear(PlaceOfInterests.PlaceOfInterest placeOfInterest)
        {
            return true;
        }
    }
}

ဒါကေတာ့ ဆိုပါစို ့Utility class တခုေပါ့ဗ်ာ။
namespace IoCContainer.Model
{
    public class Location
    {
    }
}
ျပီးရင္ သိတဲ့အတိုင္း ကြ်န္ေတာ္တို ့အထက္မွာ ေဆြးေနြးခဲ့သလိုပဲ စိတ္ဝင္စားဖြယ္ေနရာေတြကို စုစည္း ေပးမယ့္ class တစ္ခု create လုပ္ဖို ့လိုတာေပါ့။ အင္း..သူကလည္း data (database) နဲ ့ ဆိုင္တဲ့ေကာင္ဆိုေတာ့ ထံုးစံအတိုင္း model အုပ္စုထဲမွာ ပဲေပါ့ဗ်ာ။ ထားပါ။

namespace IoCContainer.Model.PlaceOfInterests
{
    public interface IPlaceOfInterestDictionary
    {
        IList<PlaceOfInterest> Places();
    }
}

အထူးသတိထားဖို ့က အခုကြ်န္ေတာ္တို ့ေရးေနတာက၊ Enterprise level application တစ္ခုအတြက္ လိုအပ္တဲ့ component တစ္ခု၊ service တစ္ခုကိုေရးေနတာ။ ဒီ service ကို တကမၻာလံုးသံုး လို ့ အဆင္ေျပရမယ္ ဆိုတာ မေမ့ပါနဲ ့။ ျမန္မာျပည္ကိုေရာက္ရင္ ျမန္မာျပည္ေျမပံု ျမန္မာျပည္ကစိတ္ဝင္စားစရာ ေကာင္းတဲ့ ေနရာေတြ၊ UK ေရာက္ရင္ UK ေျမပံု နဲ ့ UK ကစိတ္ဝင္စားစရာ ေကာင္းတဲ့ ေနရာေတြ၊ စသည္ျဖင့္ သက္ဆိုင္ရာ သက္ဆိုင္ရာ ကို execute လုပ္ေပးနိုင္ရပါမယ္။ ဒါေၾကာင့္....Maps ေတြ PlaceOfInterest ေတြ ဟာ မို်းကဲြေပါင္း မ်ားစြာ ပါမယ္ဆိုတာ သတိျပုပါ။

namespace IoCContainer.Model.PlaceOfInterests
{
    public class PlaceOfInterest
    {
    }
}

namespace IoCContainer.Model.PlaceOfInterests
{
    public class EnglishPlaceOfInterestDictionary : IPlaceOfInterestDictionary
    {
        public IList<PlaceOfInterest> Places()
        {
            return new List<PlaceOfInterest>();
        }
    }
}


ကဲအခု ကြ်န္ေတာ္တို ့ အေပၚမွာေရးခဲ့ျပီးျဖစ္တဲ့ ေျမပံုေတြ၊ သက္ဆိုင္စိတ္ဝင္စားစရာေနရာေတြကို လိုအပ္သလို စီမံခန္ ့ခဲြေပးမယ့္ service class တခု ေရးေတာ့မယ္ဗ်ာ။
web, web service, i-phone, android ..စတာတြမွာ run မယ့္ client application ေတြ ၊ တနည္းေျပာရရင္ ဒီ service class ကို သံုးစဲြမယ့္ service consumer class ေတြ က လွမ္း ေခၚမယ့္၊ လွမ္းသံုးမယ့္ class ေပါ့။

using IoCContainer.Model.Maps;
using IoCContainer.Model.PlaceOfInterests;
namespace IoCContainer.Model
{
    public class TouristInformationService
    {
        private IMap _map;
        private IPlaceOfInterestDictionary _placeOfInterestDictionary;


        public TouristInformationService(IMap map, IPlaceOfInterestDictionary placeDic)
        {
            this._map = map;
            this._placeOfInterestDictionary = placeDic;
        }
    }
}

ဒီ TouristInformationService class ထဲမွာ tourist information နဲ ့ ပတ္သက္တဲ့ function ေတြ အမ်ားၾကီးရိွမွာေပါ့ဗ်ာ။ ထားပါ..။ ဒါကေတာ့ auto understood ေပါ့။ အဲဒီ function ေတြကို ေခၚခ်င္ရင္ ဘာလုပ္ရမလဲ။ TouristInformationService object ကို create လုပ္ရမွာေပါ့။

ဘယ္သူကလုပ္မလဲ။ ေခၚမယ့္သူကလုပ္ရမွာေပါ့။
ဘယ္သူကေခၚမွာလဲ။ client ကေပါ့။

ဒါေၾကာင့္ client class မွာ TouristInformationService class ရဲ့ object ကို instantiate/create လုပ္ရမွာေပါ့။
ဒီမွာၾကည့္ဗ်ာ...

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

namespace IoCContainer.ServiceConsumer
{
    public class ClientThatUsesService
    {
        TouristInformationService touInfoService;
        //..
        //..
        //..
        //..
        public void initializeServiceObject()
        {
            IMap _map = new SatelliteMap();
            IPlaceOfInterestDictionary _placeOfInt = new EnglishPlaceOfInterestDictionary();

            touInfoService = new TouristInformationService(_map, _placeOfInt);
            //..
            //..
            //..
        }

        //..
        //..
        //..
    }
}
ကဲ..မိတ္ေဆြတို ့ ျမင္တဲ့အတိုင္းပဲ.

ကိုယ္သံုးမယ့္ TouristInformationService ရဲ့ object ကို instantiate/create လုပ္တဲ့အခါ
ေခၚတဲ့ သံုးတဲ့ client က
TouristInformationService အတြက္ လိုအပ္ေနတဲ့ ၊ TouristInformationService ကမီွခိုေနရတဲ့
ေျမပံုတို ့[Map] စိတ္ဝင္စားစရာေနရာတို ့[PlaceOfInterest] ဆိုတဲ့ object ေတြကို
TouristInformationService Constructor ကတဆင့္ လွမ္း ျပီး ထည့္သြင္းေပးလိုက္လို ့
ဒီလို Architecture ကို
Constructor Dependency Injection လို ့ေခၚတာပါ။

ကဲေကာင္းပါျပီ..
ဒါဆို ဘာျဖစ္လဲေပါ့...။
ကြ်န္ေတာ္တို့ဟာ ဒီ ေဆာ့ဖ္ဝဲကို ဒီဇိုင္းခ်တုန္းက
- service module ေတြ အခ်င္းခ်င္း loosely coupled ျဖစ္ေစဖို့
- service module တစ္ခုခ်င္းစီကို testing လုပ္နိုင္ဖို ့
- maintenance/ enhancement လုပ္တဲ့အခါ module တခုက တခုကို မထိခိုက္ေစပဲ တခုခ်င္းစီကို လြယ္လြယ္ကူကူ ျမန္ျမန္ဆန္ဆန္ လုပ္နိုင္ဖို ့ ဆိုတဲ့ ရည္ရြယ္ခ်က္ေတြနဲ့ လုပ္ခဲ့တာေလ..။

ခုေတာ့ ဒါေတြ သြားျပီေပါ့..။
ဘာေၾကာင့္လဲ....
Client class ဟာ Service class ရဲ့ လိုအပ္တဲ့ module ေတြ class ေတြနဲ ့ tightly coupled ျဖစ္ေနျပီေလ။
၁-ထိပ္ဆံုးက using statement ကိုၾကည့္လိုက္ ။ လိုတဲ့ assembly ေတြကို reference လုပ္ရတယ္။
၂- ျပီးေတာ့လည္း service class ရဲ့ dependency ျဖစ္ေနတဲ့ Map တို ့ PlaceOfInterest တို ့ရဲ့ object ေတြကို ပါ create လုပ္ေပးရတယ္။
၃- ဒါေၾကာင့္ SatelliteMap တို ့ EnglishPlacesOfInterestDictionary class တို ့မွာ တခုခု ေျပာင္းလိုက္တာနဲ ့ client code က break ျဖစ္သြားျပီ..။
၄- ဒါ့အျပင္ SatelliteMap တို ့ EnglishPlacesOfInterestDictionary တို ့ရဲ့ implementation ကို change ခ်င္ရင္ [ဆိုပါစို ့ဗ်ာ USASatelliteMap နဲ ့ USAPlacesOfInterestDictionary ကို ေျပာင္းသံုးမယ္ဆိုရင္] ဒီ Tourist Service ကို သံုးမယ့္ client code ေနရာတိုင္းမွာ လိုက္ change ေနရမွာေပါ့..။

ဒါဆိုရင္ ကိုယ့္ရဲ့ client code က ကိုယ္သံုးမယ့္ service အေၾကာင္းပါမက ကိုယ္သံုးမယ့္ service ရဲ့ dependency ေတြကိုပါ သိဖို ့လိုအပ္ေနျပီေကာဗို် ့....။ tightly coupled ဆိုတာ ဒါကိုေျပာတာေပါ့။

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

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


Reference:
Professional Enterprise .NET [2009 - Wiley Publishing, Inc., Indianapolis, Indiana, USA] by Jon Arking and Scott Millett