December 18, 2015

Iterator Pattern

ပရိုဂရမ် ဒီဇိုင်းရေးသားခြင်းဆိုသည်မှာ System တစ်ခုလုံးအား သေးငယ်သော Module များ အဖြစ် အစိတ်စိတ် အပိုင်းပိုင်း ပိုင်းကာ ၎င်းတို့၏ ပတ်သက်ပုံအား စဥ်စားခြင်းဟု ဆိုနိုင်မည်ဖြစ်သည်။ အဲ့ဒီနေရာမှာ အရေးကြီးတာကတော့ Module တွေကြားမှာရှိတဲ့ Relationship တွေကို ဘယ်လောက် အထိ ရိုးရှင်းအောင် ဆောင်ရွက်မလဲ ဆိုတဲ့ အချက်ပဲ ဖြစ်ပါတယ်။ အကြောင်းတစ်ခုခုကြောင့် Module တစ်ခုအား ပြုပြင်လိုက်ပါက တတ်နိုင်သလောက် အခြား Module များအာ ထိခိုက်မှု့မရှိအောင် ဆောင်ရွက်ထားနိုင်ဖို့ လိုအပ်ပါသည်။ ထိုအချက်ဟာ OOP တစ်ခုထဲအတွက်သာ မဟုတ် အခြားသေား ပရိုဂရမ်မင်း ဘာသာရပ်များအတွက်လည်း အတူတူပင်ဖြစ်သည်။

OOP အတွက် Module ဟုဆိုပါက Class ဒါမှမဟုတ် Object ကို ဆိုလိုပါသည်။ ထို့အတွက် Class များ၏ Relationship သည် Program တစ်ခု၏ Static Structure အား ဖေါ်ပြနိုင်ပြီး၊ Object များ၏ Relationship သည် Program တစ်ခု၏​ Dynamic Function အာ သတ်မှတ်ပေးနိုင်ပါသည်။

ယခုအခန်းတွင် GoF Design Pattern များ အတွင်းမှ Object များ အကြားရှိ့ Relationship အား ရှင်းလင်းအောင် ဆောင်ရွက်နိုင်သော Iterator Pattern အကြောင်းကို ဖေါ်ပြသွားပါမည်။


Problem


အောက်ပါ ကုဒ်များအား ကြည့်ပါ။ မည်သည့်နေရာတွင် ပြဿနာရှိသနည်း။

int sum = 0;

for (int index=0; index < MAX; index++) {
 sum += array[index];
}

အထက်ပါ ပရိုဂရမ်သည် index အား loop counter အဖြစ် အသုံးပြုပြီး array အတွင်းရှိ element များအား တစ်ခုချင်းထုတ်ယူကာ စုစုပေါင်းအား sum အဖြစ်တွက်ယူရသော ပရိုဂရမ်တစ်ခုဖြစ်ပါသည်။ index ၏ အစတန်ဖိုးသည် 0 ဖြစ်ပြီး အဆုံးတန်ဖိုးသည် MAX - 1 ဖြစ်ပါသည်။


မကြာခဏရေးဖူးမည်လည်း ဖြစ်ပါသည်။ ဘာမှ ပြဿနာမရှိဟုမြင်နိုင်ပါသည်။


သို့ရာတွင် array အားပိုင်ဆိုင်သော Object နှင့် for ဝါကျနှင့် Iterate လုပ်နေသော Object တို့သည် တစ်ခုစီ ဖြစ်နေမည် ဆိုပါက အဆိုပါ Object တို့အကြားရှိ Relationship သည် အတော်လေးကို ရှုပ်ထွေးသွားနိုင်ပါသည်။

ဥပမာအားဖြင့် Object A နှင့် Object B တို့ရှိကြပြီး၊ Objec B အတွင်းတွင် Array Data က တည်ရှိပြီး၊ Object A အတွင်းတွင် Array အတွင်းရှိ Data များကို အသုံးပြုသော for ဝါကျကို ရေးသားထားပါသည်။ ထို အနေအထားမျိုးတွင် Object A သည် Object B မှပိုင်ဆိုင်သော Data ဖွဲ့စည်ပုံသည် Array ဖြစ်ကြောင်း၊ Array Object ၏​ အမည်၊ Array အတွင်းရှိ အစပိုင်း Index နှင့် နောက်ဆုံး Index တို့ကို သိရှိထားရန် လိုအပ်ပါသည်။

တကယ်လို့ index နံပါတ်အား မှားယွင်းအသုံးပြုမိပါကအလုပ်လုပ်နေစဥ် Runtime Exception ကို ဖြစ်ပေါ်စေမည် ဖြစ်သည်။ တဖန် အကြောင်းတစ်ခုခုကြောင့် Object B ၏ Data Structure အား Array မှ အခြားသော ပုံစံတစ်ခုခုသို့ ပြောင်းလဲရန်လိုအပ်ပြီး ပြောင်းလဲ မိပါက Object A သည် မှန်ကန်စွာ အလုပ်လုပ်နိုင်တော့မည် မဟုတ်။


Solution


အဆိုပါ ပြဿနာအား ဖြေရှင်းနိုင်သည်မှာ Iterator Pattern ဖြစ်ပါသည်။ Object တစ်ခု အတွင်းရှိ Data Structure အား private အနေနှင့် ထားရှိပြီး၊ hasNext နှင့် next method တို့ကို ပိုင်ဆိုင်စေကာ Iterate လုပ်နိုင်သော Pattern ဖြစ်ပါသည်။

hasNext method အား ခေါ်ဆိုသည့်အခါ နောက်ထပ် Data ကျန်ရှိသေးပါက true အား return လုပ်စေပြီး နောက်ထပ် မရှိတော့ပါက false အား Return လုပ်စေမည် ဖြစ်ပါသည်။ next method က အစီအစဥ် အတိုင်း လက်ရှိ Object များကို ပြန်ပြီး Return လုပ်ရုံသာ ဖြစ်သည်။

Object A မှ Object B အား နောက်ထပ် Element တွေရှိသေးသလားဆိုတာကို hasNext method ကို ခေါ်ဆိုရုံနှင့်သိရှိနိုင်ပြီး၊ လိုအပ်ပါက next method ဖြင့် နောက်လာမည့် element ကို ရရှိနိုင်မည် ဖြစ်သည်။

မူရင်း Requirement မှာ Object A သည် Object B ၏​ Element များအား ရယူလိုခြင်းသာဖြစ်သောကြောင့်၊ Object B အတွင်းရှိ Data Structure အား သိရှိရန်မလိုအပ်ပေ။ နောက်ဆုံး Object B အတွင်းရှိ Data Structure ပြောင်းလဲ သွားရင်တောင်မှ​ hasNext နှင့် next method များအား မှန်မှန်ကန်ကန် ပံ့ပိုးနေပါက Object A အတွက်ပြဿနာရှိမည် မဟုတ်ပေ။

Iterator Pattern သည် Object တစ်ခုအတွင်းရှိ Element များ အား Iterate ပြုလုပ်ရန်နှင့်၊ အတွင်းပိုင်း Data Structure နှင့် မည်ကဲ့သို့လုပ်ဆောင်နေသည်ဆိုသည့် အချက်ကို Client Program များမှ မမြင်နိုင်အောင် Encapsulate လုပ်ပေးနိုင်ပါသည်။ Iteratation လုပ်မည့် Logic အား Collection Object အတွင်း Embedded ပြုလုပ်ထားပြီး၊ client program အတွင်းမှ အလွယ်တကူ Iterate ပြုလုပ်နိုင်ရန် အကူအညီ ပေးနိုင်ပါသည်။


ဆက်ပါဦးမည်။
မင်းလွင်

No comments:

Post a Comment