Showing posts with label Design Patterns. Show all posts
Showing posts with label Design Patterns. Show all posts

June 27, 2018

Command Pattern



Behavior Pattern အမျိုးအစားတစ်မျိုးဖြစ်ပါတယ်။ အရင်ဆုံး Command Pattern ကို အသုံးပြုပြီး ဖြေရှင်းနိုင်တဲ့ ပြဿနာတွေကနေ စပြီး လေ့လာကြည့်ကြရအောင်။

Problem

ကျွန်တော်တို့ GUI Application တစ်ခုကို ရေးသားနေပြီး၊ Button Class တစ်ခုကို ရေးသားဖို့လိုအပ်လာပြီဆိုကြပါစို့။ Button ကို Tools Bar မှာလဲ ထားမယ်။ ပြီးတော့ View Form တွေမှာလဲ ထားနိုင်မယ်။ ပြီးတော့ အဲ့ဒီ Button Object ကို အသုံးပြုပြီး copy လုပ်တာတွေ၊ cut လုပ်တာတွေပြီးတော့ Form ကို Submit လုပ်တာတွေ လုပ်ဆောင် စေလိုတဲ့အခါလဲရှိပါမယ်။ ကဲ ဒါဖြင့်ရင် ဘယ်လို ရေးကြမလဲ။ Button Class ထဲမှာ Label အတွက် Text လိုမယ်၊ ပြီးတော့ Icon ပါနိုင်တယ်၊ ပြီးတော့ အဲ့ဒီ Button ကို UI မှာ ဘယ်လို ဖေါ်ပြမလဲ ဆိုတဲ့ draw() ဆိုတဲ့ behavior လဲပါမယ်။ ပြီးတော့ အဲ့ဒီ button ကို Click နှိပ်ရင် ဘာလုပ်မယ်ဆိုတာကို ဖေါ်ပြနိုင်ရမယ်။ ပြီးတော့ Button အပေါ်မှာမူတည်ပြီး အလုပ်လုပ်ပုံတွေတူမှာမဟုတ်ဘူး။ ဒီနေရာမှာ စဉ်းစားမိမှာကတော့ “အမျိုးအစားတော့တူတယ်၊ အလုပ်လုပ်ပုံချင်းတော့မတူဘူး။ Polymorphism ကို သုံးနိုင်တယ်။”​ ဆိုတာပဲ ဖြစ်ပါမယ်။

ရေးကြည့်ကြရအောင်။ Polymorphism အတွက် Abstract Class ကို ရေးထားမယ်။ ပြီးမှ ဘုံအနေနဲ့ အသုံးပြုချင်တာတွေကို အဲ့ဒီ Class ထဲမှာရေးထားပြီး အလုပ်လုပ်ပုံချင်းမတူတဲ့ click() ကိုတော့ Abstract Method နဲ့ ရေးထားမယ်ပေါ့။ အိုကေ ဒါဆိုရင် သင်တန်းမှာ သင်ထားတဲ့ Abstraction ကော Polymorphism ပါ အဆင်ပြေသွားပြီ။
public abstract class Button {
 
 private String text;
 private String icon;

 public Button(String text, String icon) {

  this.text = text;
  this.icon = icon;
 }

 public void draw() {
  System.out.println("Button Text is " + text);
  System.out.println("Button Icon is " + icon);
 }

 public abstract void click();
}
Cut Button လိုချင်တယ်ဆိုရင်လဲ Button ကို Inheritance လုပ်ပြီး click method ကို Override လုပ်လိုက်ရုံပဲ။ ပြီးတော့ Past လဲ လာထား။ ဒါ့ထက်မကလို့ Send Button ဆိုလဲ နောက် Button Class တစ်ခုကို ရေးလိုက်ရုံပဲ။ နိပ်ဟ OOP! ဆိုပြီးတွေးပျော်နေမယ်ထင်ပါတယ်။
ဒါပေမဲ့ ဒီနေရာမှာ တွေးစရာ ၂ ချက်ရှိပါတယ်။ မတူညီတဲ့ Behavior တစ်ခုလိုတိုင်း Button တစ်ခုကို ရေးနေရရင် Button Class တွေအများကြီးဖြစ်လာနိုင်တယ်ဆိုတဲ့ အချက်နဲ့ တကယ်လို့ Cut Behavior ကို CTL + X နဲ့ ရေးချင်လာရင်လဲ Cut Behavior ကို Button မှာကော Short Cut Action မှာပါရေးနေရပါမယ်။ Don’t Repeat Yourself (DRY) ကို အကြီးအကျယ်ချိုးဖေါက်နေမိပါပြီ။ အဲ့ဒီလို ပြဿနာမျိုးကို Command Pattern ကို အသုံးပြုပြီး ဖြေရှင်းနိုင်မှာ ဖြစ်ပါတယ်။

Command Pattern

Command Pattern မှာ Command, Invoker, Receiver နဲ့ Client တို့ပါဝင်ကြပါတယ်။

ဒီနေရာမှာ အဓိက အရေးပါတာကတော့ Command Interface ပဲဖြစ်ပါတယ်။ ဘာလုပ်မှာလဲ ဆိုတာတဲ့ Business Logic ကို Wrap လုပ်ပေးနိုင်ပါတယ်။ အဲ့ဒီ Command Object ကို Invoker ကပိုင်ဆိုင်ပြီး ခိုင်းလိုတဲ့ အရာတွေကို အဲ့ဒီ Object ကို ခိုင်းမှာ ဖြစ်ပါတယ်။


အထက်ပါပုံအတိုင်း Client ကနေ Invoker ကို executeCommand() လို့ခိုင်းလိုက်တာနဲ့ Invoker ကနေ သူ့မှာရှိတဲ့ Command Object ရဲ့ execute() ကိုလုပ်ဆောင် ခိုင်းမှာ ဖြစ်ပါတယ်။ Command1 ကတော့ Command Interface ကို Implement လုပ်ထားတဲ့ Class ဖြစ်ပြီး Business Logic တွေကို ဆောင်ရွက်နိုင်တဲ့ Receiver Object နဲ့ အဲ့ဒီ Receiver Object ကို အလုပ်ခိုင်းရာမှာ အသုံးပြုနိုင်တဲ့ Parameter တွေကို State အနေနဲ့ ပိုင်ဆိုင်ထားပါတယ်။ တကယ်လို Invoker ကနေ execute() လို့ လုပ်ခိုင်းလိုက်ပြီဆိုတာနဲ့ Receiver Object ကို ပြန်ခိုင်းလိုက်ရုံပါပဲ။

 

How to Fix?


အိုကေ ဒီလို Pattern ကို အသုံးပြုလိုက်တာနဲ့ အထက်က ပြဿနာကို ဘယ်လို ဖြေရှင်းနိုင်မလဲ ဆိုတာကို လက်တွေ့ ကုဒ်လေးတွေရေးကြည့်ပြီး လက်တွေ့ ဖြေရှင်းကြည့်ကြရအောင်။

public interface Command {
 void execute();
}

ဒါကတော့ Button ကို click() နှိပ်တဲ့အခါမှာ အလုပ်လုပ်ပေးစေချင်တဲ့ Interface ဖြစ်တယ်။ ပြီးတော့ method တစ်ခုသာပါဝင်ပြီး Command အမျိုးမျိုးအတွက် တူညီတဲ့ ခေါ်ဆိုမှု့ကို သတ်မှတ်ပေးနိုင်ပါတယ်။ Copy Command ကို ရေးချင်တယ်ဆိုရင်လဲ ဒီ Interface ကို Inpmement လုပ်ပြီးရေးရမယ်။ Cut ဆိုရင်လဲ ဒီ Interface ကို Implement လုပ်ရမှာပါပဲ။ ဒါမှသာ Button Class ထဲကနေ ခိုင်းချင်တဲ့ အရာရှိရင် execute() method တစ်ခုကိုပဲ ခေါ်ပြီး ခိုင်းလိုက်ရုံပါပဲ။

public class Button {
 
 private String text;
 private Command command;

 public (String t, Command c) {
  text = t;
  command = c;
 }

 public void click() {
  command.execute();
 }
}

Button Class ကတော့ Command Pattern ရဲ့ Invoker နေရာမှာ တာဝန်ကျပါတယ်။ သူ့ဆီမှာတော့ Command ကို လုပ်ဆောင်ပေးနိုင်တဲ့ Command Object တစ်ခုရှိပါတယ်။ ဘာတွေလုပ်နိုင်တယ်ဆိုတာကိုတော့ Commannd Interface ရဲ့ နောက်ကွယ်မှာ Encapsulate လုပ်ပေးထားနိုင်ပါတယ်။ Button အနေနဲ့ သိစရာလိုတာကတော့ click() နှိပ်လာရင် Command ရဲ့ execute() ကို ခေါ်လိုက်ရုံပဲ ဆိုတာပါပဲ။

public class Editor {

 private String selectedText;
 
 public String getSelectedText() {
  return selectedText;
 }

 public void paste(String text) {
  selectedText = text;
 }
}

public class Clipboard {
 
 private String memo;

 public void save(String text) {
  memo = text;
 }

 public void getSaveData() {
  return memo;
 }
}

အထက်ပါ Editor နဲ့ ClickBoard တွေကတော့ Command Pattern ရဲ့ Receiver Class တွေပဲ ဖြစ်ကြပါတယ်။ သူတို့တွေကတော့ သက်ဆိုင်ရာ Command တွေကနေ ဆက်သွယ် အသုံးပြုကြမှာပါ။
public class CopyCommand implements Command {
 
 private Editor editor;
 private Clipboard clipboard;

 public CopyCommand(Editor e, Clipboard c) {
  editor = e;
  clipboard = c;
 }

 public void execute() {
  String text = editor.getSelectedText();
  clipboard.save(text);
 }
} 

ဆိုကြပါစို့။ Copy Command ကို ရေးပြီဆိုရင် Editor ထဲက Select လုပ်ထားတဲ့ Text ကို ယူပြီး Clipboard မှာ သွားပြီး Save လုပ်ပါမယ်။ တကယ်လို့ Clear Command မှာဆိုရင်လဲ Clipboard ထဲက memo ကို ဖျက်ပစ်ပါမယ်။ သက်ဆိုင်ရာ Command Concrete Object တွေက ဘယ် Receiver ကို သုံးမယ်ဆိုတာကို သိစရာလိုပါတယ်။

public class Application {
 
 private Button clearButton;
 private Button copyButton;

 public void init() {

  Editor editor = new Editor();
  Clipboard clipboard = new Clipboard();

  Command clear = new ClearCommand(clipboard);
  Command copy = new CopyCommand(editor, clipboard);

  clearButton = new Button("Clear", clear);
  copyButton = new Button("Copy", copy);

 }
}

အထက်ပါ Application Class ဟာ Command Pattern ရဲ့ Client နေရာမှာရှိပါတယ်။ Application Class ရဲ့ init method ထဲမှာ Receiver ဖြစ်တဲ့ Editor နဲ့ Clipboard Object တွေကို တည်ဆောက်ပြီး သက်ဆိုင်ရာ Command Object တွေကို တည်ဆောက်ပါတယ်။

Clear Button အတွက်ဆိုရင် ClearCommand Object ကိုပေးပြီတည်ဆောက်ပြီး Copy Button အတွက်ဆိုရင် CopyCommand Object တို့ကို ပေးပါတယ်။ ဒီလိုရေးသားထားတဲ့ အတွက် Short Cut တွေ Menu Item တွေမှာ အဲ့ဒီ Command တွေကို အသုံးပြုစေလိုတယ်ဆိုရင်လဲ ရေးထားပြီးသား Command တွေကို ပြန်ပြီး အသုံးပြုနိုင်ပါတယ်။ Button ထဲမှာသာ Business Logic တွေကို တိုက်ရိုက်ရေးသားထားခဲ့မယ်ဆိုရင် အဲ့ဒီ Logic တွေကို လိုချင်တဲ့ နေရာတိုင်းမှာ ရေးသားနေရမှာ ဖြစ်ပါတယ်။ အခုလို Command အနေနဲ့ ရေးသားလိုက်တဲ့အတွက် အဲ့ဒီ Command တွေကို အခြားနေရာမှာလဲ ပြန်ပြီး အသုံးချနိုင်တာ ဖြစ်ပါတယ်။ တဖန် Command ကိုသာ အသုံးမပြုထားခဲ့ရင် Invoker ဖြစ်တဲ့ Button က Receiver ဖြစ်တဲ့ Editor တို့ Clipboard တို့ကို တိုက်ရိုက်မှီခို အသုံးပြုနေရမှာ ဖြစ်တယ်။ ဤကဲ့သို့ Invoker နဲ့ Receiver တို့ကို Decouple လုပ်ပေးခြင်းအားဖြင့် လွတ်လွတ်လပ်လပ် ပြန်လည်အသုံးပြုနိုင်တဲ့ Component တွေကို ရေးသားစေနိုင်မှာ ဖြစ်ပါတယ်။

Because of Pattern

  • Operation တစ်ခုကို စတင်စေတဲ့ Object နဲ့ တကယ်အလုပ်လုပ်မည့် Object တို့ကို Decouple လုပ်ပေးနိုင်ပါတယ်
  • Open / Close Principle နဲ့ Single Responsibility Principle တို့ကို လိုက်နာစေပြီး Code တွေကို ပြန်လည် အသုံးချနိုင်အောင် ဆောင်ရွက်ပေးနိုင်ပါတယ်
  • ရှုပ်ထွေးတဲ့ လုပ်ဆောင်မှုတွေကို ရိုးရှင်းစွာ လုပ်ဆောင် စေနိုင်ပါတယ်

August 24, 2016

Singleton Pattern

Student Registration ကို ပြုလုပ်သော အပလီတစ်ခုတွင် Student များကို ထိမ်းသိမ်းပေးထားသော StudentRepository Class ကို အသုံးပြုပြီး Student များအား Memory ပေါ်တွင် ထားရှိသည်ဟု ဆိုကြပါစို့။

အဆိုပါ StudentRepository အား StudentRegistView နှင့် StudentListView တို့တွင် အသုံးပြရန်လိုအပ်ပါသည်။ ထိုအခါမျိုးတွင် View တိုင်းတွင် StudentRepository Class အား အသီးသီး Object ဆောက်နေမည် ဆိုပါက StudentRegistView နှင့် StudentListView တို့တွင် သုံးနေသော Object တို့မှာ တူညီမည် မဟုတ်တော့ပေ။ ထို့ကြောင့် StudentRegistView တွေ Register လုပ်လိုက်သော Student Object အား StudentListView တွင် တွေ့နိုင်မည် မဟုတ်တော့ပေ။


ထိုသို့ဖြစ်ရခြင်းမှာ StudentRepository Object ကို new ခေါ်တိုင်း Object ဆောက်ခွင့်ရှိနေသောကြောင့် ဖြစ်ပါသည်။ ထိုအခါမျိုးတွင် Application တစ်ခုလုံးတွင် StudentRepository Object အား တစ်ခုထဲသာ ရှိအောင် ဆောင်ရွက်ထားဖို့လိုအပ်ပါသည်။

ထိုအခါမျိုးတွင် အသုံးဝင်သည်က Singleton Design Pattern ဖြစ်ပါသည်။ Singleton Design Pattern သည် Application တစ်ခုလုံးတွင် Object တစ်ခုသာ ထားရှိလိုသည့်အခါ မျိုးတွင် အကူအညီပေးနိုင်သော Design Pattern ဖြစ်ပါသည်။

Java ဘာသာရပ်တွင် အဓိကအားဖြင့် Singleton ဖြစ်အောင် ရေးသားပုံရေးသားနည်း ၂ မျိုးရှိနိုင်ပါသည်။ ပထမနည်းမှာ Java Object အား တစ်ခုထဲရှိအောင် ဆောင်ရွက်သောနည်းဖြစ်ပြီး ဒုတိယနည်းမှာ နဂိုကထဲက တစ်ခုထဲသာရှိသော enum type ကို အသုံးပြသောနည်း တို့ဖြစ်ကြသည်။


Making Singleton Object


အဓိက ပြဿနာမှာ new ခေါ်တိုင်း Object ဆောက်လို့ရနေသောကြောင့် ဖြစ်သည်။ ထို့ကြောင့် Constructor အား private ဟု ပေးလိုက်ပါက အခြားသော Class များ အတွင်းမှ new ခေါ်ပြီး Object ဆောက်နိုင်တော့မည် မဟုတ်ပေ။
ထို့နောက်တွင် Memory ပေါ်တွင် တစ်ခုထဲရှိအောင် Static Variable ကို အသုံးပြုနိုင်ပါသည်။

ထိုသို့ပြုလုပ်ပါက ထို Object အား New ခေါ်တိုင်း Create လုပ်မရတော့ပဲ တစ်ခုထဲသာရှိသော Static Object ကို ရရှိမည် ဖြစ်ပါသည်။ အပြင်ကလိုချင်တိုင်း တစ်ခုထဲသာရှိသော Object ကို ပြန်ပေးမည်ဆိုပါက အထက်ပါ ပြဿနာကို ဖြေရှင်းနိုင်မည် ဖြစ်သည်။



အထက်တွင် ဖေါ်ပြထားသည့်အတိုင်း INSTANCE Object အား static variable အဖြစ်ထားရှိသောကြောင့် Memory ပေါ်တွင်တစ်ခုထဲသာရှိသော Object ဖြစ်နေပါမည်။ တဖန် Constructor ကို လဲ private အဖြစ်ပြောင်းထားသောကြောင့် Object ကို လိုအပ်သလို Create လုပ်လို့ရမှာ မဟုတ်တော့ပါ။

getInstance method ကို ခေါ်ဆိုပါက တစ်ခုထဲသာရှိသော INSTANCE ကို ပြန်ပေးမည် ဖြစ်သောကြောင့် တစ်ခုထဲသော Object ကို ရရှိမည် ဖြစ်ပါသည်။


Using enum type


Java SE 5 တွင် စတင် အသုံးပြုလာနိုင်ခဲ့သော Enum Type များသည် သဘာဝအရ Static Entity များ ဖြစ်ကြသည်။ ထို့ကြောင့် enum type များကို အသုံးပြုခြင်းအားဖြင့်လဲ Memory ပေါ်တွင် တစ်ခုထဲသာရှိသော Singleton Object များကို ရရှိမည် ဖြစ်ပါသည်။



January 24, 2016

Abstract Factory

ပြီးခဲ့သော အပိုင်းဖြင့် Factory Pattern အကြောင်းကို မိတ်ဆက်ခဲ့၏။ Factory Pattern သည် Object Creation Process အား Client Program များနှင့် Decouple လုပ်နိုင်ပါသည်။ Class တစ်ခု၏ Sub Class များအား လိုအပ်ချက်အပေါ်မူတည်ပြီး Object များကို ဆောက်လုပ်သည့် အပိုင်းအား Factory Method အတွင်းတွင် Encapsulate လုပ်ပေးခဲ့ပါသည်။

Problem

သို့ရာတွင် generate လုပ်ပေးနေသော Class ၏​ Sub Class အမျိုးအစားများတိုးပွားလာသည်နှင့် အမျှ Factory Method အား ပြုပြင်ပြောင်းလည်းရန် လိုအပ်လာမြဲ ဖြစ်ပြန်သည်။ Sub Class အမျိုးအစား များလေလေ Factory Method အတွင်းရှိ if else if နှင့် switch လော့ဂျစ်များ များလာလေလေ ဖြစ်ပါလိမ့်မည်။


ကျွန်တော်တို့ရေးသားသော အပလီကေးရှင်းတစ်ခုတွင် Theme အပေါ်မူတည်ပြီး UI Component များကို ထုတ်လုပ်ပေးရန်လိုအပ်လသည် ဟု ဆိုကြပါစို့။ Theme နည်းနေပါက ကိစ္စမရှိ၊ Theme အသစ်များ ထပ်မံဖြည့်စွက်လိုပါက UIFactory Class အား ပြုပြင်ရန်လိုအပ်ပြီး Factory Method များ အတွင်း Logic များ များပြားလာမည်ဖြစ်ပါသည်။


Solution

အဆိုပါပြဿနာအား ဖြေရှင်းရန် Abstract Factory Pattern ကို အသုံးပြုနိုင်ပါသည်။
အထက်ပါပုံအတိုင်း UIFactory နေရာတွင် AbstractUIFactory class နှင့် အစားထိုးပါမည်။ ပြီးမှ Theme အလိုက် AbstractUIFactory အား Extends လုပ်ထားသော Concrete Class Factory များအား တည် ဆောက်ပါမည်။ အဆိုပါ Concrete Factory များမှ တဆင့် သက်ဆိုင်ရာ Component များ အား Generate လုပ်ပေးပါမည်။ ထိုနည်းအားဖြင့် Theme အသစ်တိုးပွါးမည် ဆိုရင်လည်း Concrete Factory များနှင့် သက်ဆိုင်ရာ Theme အလိုက် Component များအား တည်ဆောက်သွားရုံသာ ဖြစ်သည်။ UIFactory တွင် ပြုပြင်စရာလိုအပ်တော့မည် မဟုတ်ပေ။



Conclusion


Abstract Factory Pattern ကိုအသုံးပြုခြင်းအားဖြင့် Object တည်ဆောက်မှု့ကို Concrete Class များအတွင်းတွင် Encapsulate လုပ်ပေးနိုင်ပါသည်။ ထိုနည်းအားဖြင့် Client အား Object တည်ဆောက်မှု့ မှ ကင်းဝေးစေပါသည်။ 

တဖန် Client မှလဲ Product Family တစ်ခုဆီမှ အခြားတစ်ခုဆီသို့ လွယ်ကူစွာ ပြောင်းလဲ အသုံးပြုနိုင်ပါမည်။ အသုံးပြုလိုသည့် လိုအပ်ချက် အလိုက် သက်ဆိုင်ရာ ConcreteFactory များကို ပြောင်းလဲ အသုံးပြူရုံသာဖြစ်ပါမည်။


ဆက်ပါဦးမည်။ လေးစားစွာဖြင့်
မင်းလွင်

January 10, 2016

Factory Method

ကျွန်တော်တို့ လက်တွေ့ အပလီကေးရှင်းများရေးသားရာတွင် တစ်ယောက်ထဲ အစအဆုံးရေးသားရသည်မှာ နည်းပါးပါသည်။ ထို့ကြောင့် မိမိသည် အခြားသူတစ်ယောက် အသုံးပြုရန် အတွက် Class များကို ရေးသားရသည့် အခါများလည်းရှိသလို အခြားသူများရေးသားထားသော Class များကို အသုံးပြုရသည့် အခါလည်းရှိနိုင်ပါသည်။

Class များသည် Object များကို တည်ဆောက်ရန် ရေးသားရသည်ဟု လည်းပြောနိုင်ပါသည်။ ထို့အပြင် Class တစ်ခုမှ အနေအထား အမျိုးမျိုးနှင့် Object အမျိုးမျိုးကို တည်ဆောက်နိုင်ရန် Constructor များကို ပုံစံအမျိုးမျိုးဖြင့် ထားရှိလေ့ရှိပါသည်။ မိမိရေးသားထားသည့် Class ဆိုပါက မိမိလိုအပ်သော Object ကို အလွယ်တကူတည် ဆောက်နိုင်မည် ဖြစ်သော်လည်း အခြားသူတစ်ယောက်က ရေးသားထားသော Class ဆိုပါက မည်သည့် Constructor ကို အသုံးပြုရမည်ဆိုသည်မှာ စိတ်ရှုပ်စရာပင်ဖြစ်သည်။

ထိုအခါမျိုတွင် Method တစ်ခုကို ခေါ်ဆိုပြီး လိုအပ်သော Object ကို ရရှိမည် ဆိုပါက အစဉ်ပြေမည် ဖြစ်သည်။


Problem


အထက်ပါ Class Diagram အတွင်းတွင် Car Abstract Class အား Inheritance လုပ်ထားသော Car အမျိုးအစား သုံးမျိုးရှိပါသည်။ တဖန် CarSimulator မှ Car Object အား အသုံးပြုနေပါသည်။

CarSimulator အတွင်းမှ TruckCar Object ကို အသုံးပြုလိုပါက Car truck = new TruckCar() ဟု Object ကို တည်ဆောက်ရမည် ဖြစ်သည်။ ဆိုလိုသည်မှာ လိုအပ်သော Object အလိုက် သက်ဆိုင်ရာ Sub Class များနှင့် Object ဆောက်ရမည် ဖြစ်သည်။

အကြောင်းတစ်ခုခုကြောင့် Sub Class မျာ၏ Constructor ကို ပြုပြင်ရန်ဖြစ်လာသည့်အခါ၊ CarSimulator တွင် အကျိုးသက်ရောက်မှု့များကို ဖြစ်ပေါ်စေမည် ဖြစ်သည်။ CarSimulator ကဲ့သို့ Client Program များ အများအပြားရှိမည် ဆိုပါက ပြုပြင်ရမည်မှာ အတော်လေးကို အလုပ်ရှုပ်သွားမည် ဖြစ်ပါသည်။


Solution


ထိုအခါမျိုတွင် အသုံးဝင်သည်မှာ Factory Method Pattern ဖြစ်သည်။ Car Object များကို ထုတ်လုပ်ပေးနိုင်သော Factory တစ်ခုရှိမည် ဆိုပါက အသုံးပြုရလည်းလွယ်ကူမည်။ တဖန် Sub Class များ၏ Object တည်ဆောက်ရာတွင် ပြုပြင်ပြောင်းလည်းမှု့ ဖြစ်ပေါ်မည် ဆိုလည်း အကျိုးသက်ရောက်မည် ဖြစ်သည်။

အထက်ပါ Class Diagram အတွင်းတွင် CarFactory Class တွင် generate method ကို ပြင်ဆင်ထားပြီး Argument အဖြစ်ရယူထားသော String Parameter အလိုက် သက်ဆိုင်ရာ Sub Class Object များကို တည်ဆောက်ပြီး Car Object အဖြစ် ပြန်ပေးမည် ဖြစ်ပါသည်။

ထိုကြောင့် CarSimulator သည် Car Object ကို ရယူလိုပါက CarFactory ၏​ generate method ကို လိုအပ်သော  Parameter ကို ပေးပြီး ခေါ်ဆိုရုံနှင့် ရရှိမည် ဖြစ်သည်။ Car ကို မည်သို့ တည်ဆောက်ရမည် ဆိုသည်ကို Client Program အတွင်းတွင် ရေးသားရန် လိုအပ်တော့မည် မဟုတ်ပါ။

Factory Pattern ကို အသုံးပြုခြင်းအားဖြင့် Client များအတွင်း Dependency Object များကို တည်ဆောက်ရန် မလိုအပ်တော့ပဲ ၎င်းတို့အကြားရှိ Coupling ကို လျော့ချနိုင်ပါသည်။ ထိုကြောင့် Service Class များကို လွယ်ကူစွာ Extends ပြုလုပ်နိုင်မည် ဖြစ်ပါသည်။

  

ဆက်ပါဦးမည်။ လေးစာ:စွာဖြင့်
မင်းလွင်

Mediator Pattern

Object အများကို အသုံးပြုပြီး ၎င်းတို့ကို အပြန်အလှန်ဆက်သွယ်အလုပ်လုပ်စေသော Program ကို ရေးသားရာတွင် Object များ အကြားရှိ ပတ်သက်မှု့သည် ရှူပ်ထွေးသွားလေ့ရှိပါသည်။ Mediator Pattern သည် Object များ၏​ ရှုပ်ထွေးသော Relationship ကို ရှင်းလင်းအောင် ဆောင်ရွက်ပေးနိုင်ပါသည်။


Problem


အောက်ပါ Object Diagram သည် User Object များ အတွင်း အသုံးပြုနေသော Chatting Program တစ်ခုအား ဖေါ်ပြထားခြင်း ဖြစ်ပါသည်။ အားလုံးပေါင်း Object 4 ခု ရှိပြီး၊ တစ်ခုချင်းစီသည် အခြားသော Object 3 ခုနှင့် Relationship တည်ရှိနေပါသည်။ အဆိုပါ Relationship များသည် Object တစ်ခုက အခြားသော Object တစ်ခု၏​ method ကို ခေါ်ဆိုနေသည် ဆိုသည်ကို ဖေါ်ပြနေပါသည်။

အကြောင်းတစ်ခုခုကြောင့် Object တစ်ခုအား ပြုပြင်လိုသော အခါ မည်သို့ဖြစ်မည်နည်း။ ဤကဲ့သို့ Relationship များရှုပ်ထွေးနေပါက အခြားသေား Object များတွင် အကျိုးသက်ရောက်မှု့များကို ဖြစ်ပေါ်စေမည် ဖြစ်သည်။ အခြားသော Object တစ်ခုခုကို ဖြည့်စွက်လိုသည့် အခါတွင်လည်း ၎င်းနှင့် ပတ်သက်မည့် Object များတွင်လည်း ပြောင်းလဲမှု့ တစ်ခုခု ဖြည့်စွက်ရန် လိုအပ်လိမ့်မည် ဖြစ်သည်။

ကုဒ်ကို ပြင်လိုက်ပြီဆိုကထဲက ကျွန်တော်တို့သည် Test လုပ်ရန် လိုအပ်လာပါသည်။ Object တစ်ခုကို ပြင်ရုံနှင့် ၎င်နှင်ပတ်သက်သော Object များအားလုံးကို Test လုပ်နေရမည် ဖြစ်သည်။ ဤသည်မှာ Object များအကြားရှိ Relationship များ ရှုပ်ထွေးနေသောကြောင့် ဖြစ်ပါသည်။



Solution


ဤကဲ့သို့ဖြစ်နေရခြင်းအကြောင်းမှာ Object အကြား Relationship များရှုပ်ထွေးနေသောကြောင့် ဖြစ်ပါသည်။ အဆိုပါ အပြန်အလှန် Relation များအား ကြားခံ Mediator Object တစ်ခုအား ဖြည့်စွက်၍ Relationship များအား Mediator နှင့်သာ ပတ်သက်စေပါမည်။ အခြားသော Object များကို ခိုင်းစေလိုသည့် အခါတွင် Mediator Object ကို ကြားခံ၍ ဆက်သွယ်စေပါမည်။

userA, userB, userC နှင့် userD တို့သည် အချင်းချင် ပတ်သက်စရာ မလိုအပ်တော့ပဲ၊ mediatorObject နှင့်သာ ပတ်သက်ရန်လိုအပ်ပါတော့သည်။ ထို့ကြောင့် အကြောင်းတစ်ခုခုကြောင့် Object တစ်ခုခုကို ပြုပြင်မည် ဆိုလည်း ပတ်သက်သည်မှာ mediatorObject တစ်ခုသာရှိသောကြောင့် Test လုပ်ရမည့် cost သည်လည်း သက်သာသွားပါမည်။ တဖန် object အသစ်တစ်ခု ထပ်မံဖြည့်စွက်မည်ဆိုလည်း mediatorObject နှင့်သာ သက်ဆိုင်မည် ဖြစ်သည်။

OOP Programming Design တွင် မဖြစ်မနေ လိုက်နာရမည်မှာ Object များ ၏ Relationship ကို ရှင်းလင်းအောင်ရေးသားခြင်းပင်ဖြစ်သည်။ Mediator Pattern ကို အသုံးပြုခြင်းအားဖြင့် Object များအကြားရှိ ရှုပ်ထွေးလွန်းသော Relationship များ ကို ရှင်းလင်းအောင်ဆောင်ရွက်ပေးနိုင်ပါသည်။



ဆက်ပါဦးမည်။ လေးစာ:စွာဖြင့်
မင်းလွင်

December 19, 2015

Adaptor Pattern

ကွန်ပြူတာ တစ်လုံးဝယ်လာပါသည်။ Three Pin ပလပ်ခေါင်းဖြစ်နေပြီး အိမ်မှာရှိတာက Two Pin ပလပ်ခုံဖြစ်နေတယ်။ အဲ့ဒီနေရာမှာ Three Pin ကနေ Two Pin ကို ပြောင်းပေနိုင်တဲ့ Adaptor တစ်ခုကို ဝယ်ပြီး Three Pin ကို Two Pin အပေါက်မှာ အသုံးပြုလိုက်တယ်။ အစဉ်ပြေသွားပါတယ်။ ကျွန်တော်တို့ Adpator ကို အသုံးပြုခြင်းအားဖြင့် Three Pin Plug ခေါင်းကို Two Pin ပလပ်ပေါက်မှာ အသုံးပြုသွားနိုင်ပါတယ်။


GoF ရဲ့ Adaptor Pattern ဆိုတာလဲ အဲ့ဒီလိုပါပဲ။ အသွင်မတူညီတဲ့ Class တွေကို မူရင်းပုံစံကို ပြုပြင်စရာမလိုပဲ အသုံးပြုနိုင်အောင် ဆောင်ရွက်ပေးနိုင်သော Pattern ဖြစ်ပါသည်။ အောက်ပါ ပြဿနာအား ဖြေရှင်းကြည့်ပါမည်။


Problem


ကုမ္ပဏီတစ်ခုတွင် အသုံပြုနေသော System တစ်ခုတွင် ဝန်ထမ်းမျာအားကိုယ်စားပြုသော Employee Class နှင့် ၎င်းတို့၏ လစာကို တွက်ချက်ပေးနိုင်သော SalaryCalculator Class တို့ရှိကြပါသည်။ Employee Class အတွင်းတွင် တစ်နာရီ၏ လစာကို ဖေါ်ပြပေးနိုင်သော getPayPerHour method နှင့် အလုပ်လုပ်ခဲ့သော နာရီပေါင်းကို ဖေါ်ပြပေးနိုင်သော getHours method တို့ကို ပိုင်ဆိုင်ကြ၏။ တဖန် SalaryCalculator Class အတွင်းတွင် Employee Class အား အသုံးပြုပြီး လစာကို တွက်ချက်ပေးနိုင်သော getSalary method ကို ပိုင်ဆိုင်ပါသည်။ getSalary method သည် Employee Object အား Argument အနေနှင့်ရယူကာ ၎င်း၏ လစာအား တွက်ချက်ပေးပါသည်။ ကုဒ် အနေနှင့် ကြည့်မည် ဆိုပါက အောက်ပါ အတိုင်းဖြစ်ပါမည်။

public double getSalary(Employee emp) {
 return em.getPayPerHour() * emp.getHours();
}

ထိုနောက် အတန်ကြာမှ ကုမ္ပဏီ ဥက္ကဌဖြစ်သော CEO Class ကို လည်း လက်ရှိ SalaryCalculator Class ၏ getSalary နှင့် အသုံးပြုလိုလာပါသည်။ သို့ရာတွင် CEO သည် နာရီစား မဟုတ်သောကြောင့် getMonthSalary method သာ ရှိပါသည်။


ရှိရင်းစွဲကုဒ်များကိုလည်း မပြုပြင်လိုပါ။ CEO Object များကိုလည်း SalaryCalculator Class ၏​ getSalary method ဖြင့် အသုံးပြုလိုပါသည်။ မည်သို့ပြုလုပ်မည်နည်း။


Solution


ထိုကဲ့သို့သော ပြဿနာများတွင် Adaptor Pattern သည် အသုံးဝင်ပါသည်။ SalaryProgram ၏​ getSalary method သည် Employee Object များဆိုပါက အသုံးပြုနိုင်ပါသည်။ ထို့ကြောင့် Employee Class အား Extends လုပ်ထားသော Class တစ်ခုအား တည် ဆောက်ပြီး ၎င်းအတွင်းတွင် CEO Object အား ပါဝင်စေကာ Employee ၏ getPayPerHour နှင့် getHours တို့အား Override လုပ်ကာ ရေးသားရုံသာ ဖြစ်မည်။ နဂိုရှိရင်းစွဲ Employee ကော၊ SalaryProgram ကော၊ CEO ကိုပါ ပြုပြင်စရာ မလိုပဲ အသုံးပြုနိုင်မည် ဖြစ်ပါသည်။


EmployeeAdaptor အတွင်းရှိ getPayPerHour နှင့် getHours method များ၏​ လုပ်ဆောင်ပုံအား Ceo Object အတွင်းမှ Data များဖြင့် မှန်ကန် အောင်တွက်ချက် ထုတ်ပြပေးမည် ဆိုပါက နဂိုရှိရင်းစွဲ၊ Employee, Ceo နှင့် SalaryCalculator များအား ပြုပြင်စရာ မလိုဘဲ အသုံးပြုနိုင်မည် ဖြစ်သည်။


Conclusion


Adaptor Pattern ဆိုသည်မှာ ဆက်စပ်မှု့မရှိသော နဂိုက အသုံပြုလို့မရသော Object မျာအား ရှိရင်းစွဲ ကုဒ်ကို ပြုပြင်စရာ မလိုပဲ အသုံးပြုနိုင်အောင် ဆောင်ရွက်ပေးနိုင်သော Design Pattern တစ်မျိုးဖြစ်ပါသည်။


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

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 ပြုလုပ်နိုင်ရန် အကူအညီ ပေးနိုင်ပါသည်။


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

Design Patterns

ကျွန်တော်တို့ နေ့စဥ် အပလီကေးရှင်းများ ရေးသားစဉ် ကြုံတွေ့လေ့ရှိသော ပြဿနာများရှိတတ်ကြပါသည်။ ယခင်ကတည်းကလည်း အလားတူ အပလီများကို ရေးသားပြီး ဖြစ်နေလေ့ရှိတတ်ပါသည်။ ထိုကြောင့် ကျွန်တော်တို့ ကြုံတွေ့လေ့ရှိသော ပြဿနာများကို လည် ယခင်လူများလည်း တွေ့ကြုံပြီး ဖြစ်နေတတ်ပါသည်။ ထိုစဥ်က ထိုပြဿနာများကို ဖြေရှင်းခဲ့သော နည်းလမ်းများလဲ ရှိခဲ့ကြပါသည်။

ပြဿနာပုံစံတစ်ခုခုအတွက် ဖြေရှင်းနည်း တစ်ခုခုဖြင့် ဖြေရှင်းခဲ့ကြမည်မှာ မလွဲပေ။ ထိုကဲ့သို့ ပြဿနာများအား ထိုကဲ့သို့ဖြေရှင်းခဲ့ကြသည်ဟု ဖေါ်ပြထားသေား နည်းလမ်းများမှာ Design Pattern များပင်ဖြစ်ကြသည်။

OOP Program များအား ရေးသားရာတွင် Object များ အကြားရှိ Relationship များကြေင့် ကြုံတွေ့လေ့ရှိသော ပြဿနာများနှင့် ဖြေရှင်းနည်းများကို OOP Design Pattern များဟု ခေါ်ဆိုကြပါသည်။

ထင်ရှားသည်မှာ GoF Design Pattern များပင်ဖြစ်ကြသည်။ ၁၉၉၄ခုနှစ်တွင် OOP လောကတွင် Erich Gamma, Ralph Johnson, Richard Helm, John Vlissides တို့ရေးသားခဲ့သော Design Patterns : Elements of Reusable Object-Oriented Software ဟု အမည်ရသော စာအုပ်တစ်အုပ်ထွက်ရှိခဲ့ပါသည်။ OOP အား အခြေခံသော အပလီကေးရှင်းများအား ရေးသားရာတွင် Object Relationship များကြောင့် ဖြစ်လေ့ရှိသော ပြဿနာများနှင့် ဖြေရှင်းနည်းများကို စုစည်းဖေါ်ပြထားပါသည်။ ထိုစာအုပ်မှာ ထွက်ပြီးမကြာခင်မှာပင် GoF Design Patterns ဟု နာမည်ကြီးခဲ့ပါသည်။

American Philosopher တစ်ဦးဖြစ်သော “Abraham Maslow” က ပြောခဲ့ဖူးပါသည်။ သင့်တွင် ဖြေရှင်းစရာ ကရိယာ အနေနှင့် တူ တစ်ခုသာ ရှိမည်ဆိုပါက၊ အရာအားလုံးအား သံများ အဖြစ်သာ ကြည့်မြင်နိုင်မည် ဟု ဆိုပါသည်။

ကျွန်တော်တို့သည် ပြဿနာ ဖြေရှင်းနည်း တစ်နည်းသာ သိမည်ဆိုပါက၊ ကျွန်တော်တို့သည်လည်း ပြဿနာများအား နည်းလမ်းတစ်ခုတည်းဖြင့်သာ ဖြေရှင်းသွားမိပေမည်။ ထို့ကြောင့် ကျွန်တော်တို့သည်လည်း ဖြစ်လေ့ရှိသော ပြဿနာများနှင့်၊ ဖြေရှင်းနည်းများကို ကြိုတင်လေ့လာထားရန် လိုအပ်ပါသည်။

ကြမ်းစုံမှ ကမ်းကုန်အောင် တတ်မည် ဟူသော ဆိုရိုးစကားရှိပါသည်။ GoF Design Pattern များအား Java Programming ဘာသာရပ်ဘက်မှ ကြည့်မြင်ပြီး လွယ်ကူသောနည်းလမ်းများဖြင့် ဖေါ်ပြသွားပါမည်။

GoF Design Pattern များသည် စုစုပေါင်း ၂၃ မျိုးရှိပြီး၊ အမျိုးအစား အလိုက် အောက်ပါအတိုင်း ခွဲခြားထားပါသည်။

Creational Design Patterns


  1. Singleton Pattern
  2. Factory Method
  3. Abstract Factory Pattern
  4. Builder Pattern
  5. Prototype Pattern

Structural Design Patterns

  1. Adaptor Pattern
  2. Composite Pattern
  3. Proxy Pattern
  4. Flyweight Pattern
  5. Facade Pattern
  6. Bridge Pattern
  7. Decorator Pattern

Behavioural Design Patterns

  1. Template Method Pattern
  2. Mediator Pattern
  3. Chain Of Responsibility Pattern
  4. Observer Pattern
  5. Strategy Pattern
  6. Command Pattern
  7. State Pattern
  8. Visitor Pattern
  9. Interpreter Pattern
  10. Iterator Pattern
  11. Iterator Pattern
  12. Momento Pattern

Java Programmer တစ်ယောက် အနေနှင့် အထက်ပါ Design Pattern များအား အလွယ်ကူဆုံးသိရှိနားလည် နိုင်စေရန် နမူနာ ကုဒ်များဖြင့်ရှင်းလင်း ဖေါ်ပြသွားပါမည်။


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