System.out.println vs Console.WriteLine
Java မှာ console ကို output ရိုက်ဖို့အတွက် သုံးတယ်။ C# ကတော့ Console.WriteLine ဆိုပြီးသုံးတယ်။ Java ရဲ့ System.out.println က Objecte Oriented Design perspective အရ ဘာတွေ လွဲနေသလဲပေါ့။
Java မှာ System ဆိုတာ class တခု။ အဲ့အထဲကမှ out ဆိုတာ PrintStream အမျိုးအစား public static final variable ပေါ့။
နောက် println ဆိုတာကို PrintStream ထဲမှာ ဒီလိုရေးထားတာ။
public void println(String x) {
if (getClass() == PrintStream.class) {
writeln(String.valueOf(x));
} else {
synchronized (this) {
print(x);
newLine();
}
}
}
public static variable ဆိုတာ တကယ်က Global varible သဘောဆောင်တယ် code smell ပေါ့။
Object Oriented program တွေမှာဆို global variable ကိုအားမပေးကြဘူး။ Memory ပေါ် program အစကနေ အဆုံးထိနေရာယူကြတယ်။
မသုံးတတ်ရင် Global variable တွေက memory leak ဖြစ်နိုင်တယ်( ဒီနေရာမှာ out က ဖြစ်တယ်လို့မဆိုလို).
နောက်တခုက System ရဲ့ out ဆိုတဲ့ variable ကို ယူသုံးတာသည် OO perspective အရကြည့်ရင် encapsulation ကိုချိုးဖောက်တယ် ခုနက global ဆိုတဲ့သဘောနဲ့တူတူပဲ။
ဘာဖြစ်လဲဆိုတော့ depend on abstraction not on implementation ဆိုတာကိုချိုးဖောက်တယ်။
abstraction မဟုတ်ပဲ implementation ဖြစ်တဲ့ PrintStream ကိုတိုက်ရိုက် couple ဖြစ်တဲ့အတွက်ပြုပြင်ရတာ ခက်မယ်. Open Closed Principle ကိုသွားထိတယ်ပေါ့။
နောက်တခုက println implementation မှာ if (getClass() == PrintStream.class) ဆိုပြီး စစ်ထားတာ။
ဒါက ဘာကိုချိုးဖောက်သလဲဆိုတော့ SOLID Principle ထဲက liskov substitution principle ကိုသွားထိတယ်။
ဆိုချင်တာက OO program တွေကို design လုပ်တဲ့အခါ parent reference နေရာမှာ child တွေအစားထိုးသုံးလို့ရဖို့လိုတယ်။
ဒါမှ polymorphism ကိုကောင်းကောင်းသုံးနိုင်မှာဖြစ်တယ်။
child တွေနဲ့ parent reference နေရာ အေးဆေး သုံးမရရင် polymorphism က အဆင်မပြေဘူး။ ဒါဆို open close principle ထဲက open for extension ဆိုတာ မအိုကေဘူး။
ခု getClass() == PrintStream.class ဆိုတာ liskov substitution principle ကိုဖောက်ထားတဲ့သဘောပဲ။
နောက်ဆုံး violate လုပ်တဲ့ rule က demeter law ဆိုတာကိုပဲ။
သူက ဘာပြောလဲဆိုတော့ object တခုရဲ့ method က သုံးလို့ရတဲ့ ကောင်တွေ ဘာတွေလဲဆိုတော့
object ကိုယ်တိုင်ကိုသုံးလို့ရတယ်
method ဆီလာတဲ့ parameter တွေကိုသုံးလို့ရတယ်
m ထဲမှာဆောက်ထားတဲ့ object တွေကိုသုံးလို့ရတယ်
object ရဲ့ attribute တွေသုံးလို့ရတယ်.
နားလည်အောင်ပြောရရင် a.b() ဆိုတဲ့ ၂ ဆင့်လောက်ပဲခေါ်သင့်တယ် a.b.c ဒါမျိုးခေါ်နေတာမျိုး ခွင့်မပေးဘူးပြောတာ။
ဘာလို့ကာထားသလဲဆိုတော့ coupling နည်းအောင် နောက်တခုက collaborator class တွေကို encapsulate ဖြစ်အောင်။
သူများ class ရဲ့ implementation ကို တဆင့်ချင်းလိုက်သုံးနေရတာ ဒါသည် encapsulation ကိုထိန်းမထားဘူးဆိုတဲ့သဘော
ဒါက Java ရဲ့ System.out.println
Console.WriteLine ကတော့ ရှင်းတယ် 😛
ဒါဆို မသုံးရဘူးလားဆိုတော့ logging သုံးလို့ရတဲ့နေရာတွေမှာ မသုံးသင့်ဘူး (performance reason ကြောင့်)
သာမာန် အသေးသုံးတွေမှာသုံးလို့ရတယ် pragmatic ဘက်ကကြည့်ရင်
ဘာလို့ ဝေဘင်လဲဆိုတော့ အားနေလို့ (ကျောင်းသားတွေစာသင်းရင်းနဲ့ ချိန်ထိုးပြတာ)
Original link