OOP නැතුව Code කරද්දී වෙන අවුල
නිකමට හිතන්න modern කාර් එකක් හදන්න යනවා කියලා. හැබැයි මේකේ හැම කෑල්ලක්ම එකට අලවලා තනි යකඩ ගුලියක් විදිහටයි හදන්නේ. දැන් මේ කාර් එකේ එක headlight එකක් කැඩුනොත් මුළු කාර් එකම කුණු ගොඩට දාන්න වෙනවා. OOP නැතුව code කරනවා කියන්නෙත් අන්න ඒ වගේ වැඩක්. Procedural ක්රමයට lines දහස් ගණනක code ලියලා, එක පොඩි variable එකක් වෙනස් වුනොත් මුළු application එකම කාඩ්බෝඩ් ගෙයක් වගේ කඩන් වැටෙනවා.
Java මේ ප්රශ්නය විසඳන්නේ Object-Oriented Programming (OOP) සංකල්පය හරහායි. OOP කියන්නේ tool එකක් හෝ library එකක් නෙවෙයි: ඒක code කරන විදිහ ගැන හිතන ක්රමවේදයක් (mindset). මේකෙන් කරන්නේ code එක modular, ස්වාධීන කොටස් (Objects) වලට වෙන් කරන එකයි. Java වලින් හරියටම වැඩක් ගන්න නම් OOP වල තියෙන ප්රධාන pillars හතර හරියටම තේරුම් ගන්න ඕනේ. අපි මේවා සරලවම කතා කරමු.
1. Encapsulation: "තමන්ගේ වැඩක් බලාගැනීමේ" සිද්ධාන්තය
ඔබේ bank account එක ගැන හිතන්න. පාරේ යන ඕනෑම කෙනෙකුට බැංකුවේ vault එක ඇතුලට ගිහින් තමන්ට ඕන විදිහට balance එක වෙනස් කරන්න බැංකුවෙන් ඉඩ දෙන්නේ නැහැ. බැංකුව කරන්නේ සල්ලි ටික ආරක්ෂිතව තියලා, ඔබට ඒ ගනුදෙනු කරන්න ආරක්ෂිත ATM එකක් දෙන එකයි. ඔබ සල්ලි දාන්නේ හෝ ගන්නේ ඒ ATM එක හරහායි.
Java වලදී Encapsulation කියන්නේ object එකක් ඇතුලේ තියෙන data (variables) කෙලින්ම පිටතින් access කරන්න බැරි වෙන විදිහට සඟවා තැබීමයි. අපි variables ටික private කරලා, ඒවා access කරන්න public getter සහ setter methods හදනවා. මේකෙන් පිටත code වලට අපේ data විනාශ කරන්න ලැබෙන්නේ නැහැ.
public class BankAccount {
private double balance; // කෙලින්ම access කරන්න බැහැ
public BankAccount(double initialBalance) {
if (initialBalance >= 0) {
this.balance = initialBalance;
}
}
// Getter: data ආරක්ෂිතව කියවීමට
public double getBalance() {
return balance;
}
// Setter: data ආරක්ෂිතව වෙනස් කිරීමට (validation සමඟ)
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("Invalid deposit amount!");
}
}
}
මේ විදිහට balance variable එක encapsulate කිරීම නිසා වෙනත් developer කෙනෙකුට account.balance = -999999; වගේ වැරදි code ලියන්න බැහැ. ඔවුන්ට අනිවාර්යයෙන්ම deposit() method එක හරහාම එන්න වෙනවා. එතකොට අපිට input එක validate කරන්න පුළුවන්.
2. Inheritance: "කම්මැලි developer ගේ සිහිනය"
ලියපු code එකම ආයෙත් ලියන්නේ මොකටද? Inheritance මඟින් දැනට තියෙන class එකක තියෙන attributes සහ methods අලුත් class එකකට උරුම කරලා දෙනවා. දැනට තියෙන class එක parent (superclass) වෙන අතර අලුත් class එක child (subclass) වෙනවා.
උදාහරණයක් විදිහට Cars සහ Motorcycles කියන්නේ Vehicles. ඉතින් engine එක start කරන logic එක මේ දෙකටම වෙන වෙනම ලියන්නේ නැතුව, අපි ඒ පොදු logic එක Vehicle කියන parent class එකේ ලියනවා.
// Parent Class
public class Vehicle {
protected String brand;
public void startEngine() {
System.out.println("Vroom! The engine is running.");
}
}
// Child Class inheriting from Vehicle
public class Car extends Vehicle {
private int numberOfDoors = 4;
public void turnOnAC() {
System.out.println("Air conditioning turned on.");
}
}
මෙතනදී Car class එක Vehicle class එක extends කරන නිසා, Car class එක ඇතුලේ කිසිම අමතර code එකක් ලියන්නේ නැතුවම startEngine() method එක පාවිච්චි කරන්න පුළුවන්. මේකෙන් code duplication නැතිවෙලා code එක පිරිසිදුව තියාගන්න පුළුවන් වෙනවා.
3. Polymorphism: "බහුරූපී" හැසිරීම
Polymorphism කියන්නේ "හැඩතල කිහිපයක් ගැනීම" කියන එකයි. මේකෙන් වෙන්නේ එකම method call එකකට විවිධ classes තමන්ට ආවේණික විදිහට ප්රතිචාර දැක්වීමයි. හිතන්න "Speak" කියන අණ දෙනවා කියලා. බල්ලෙක් බුරනවා, පූසෙක් ඤාව් කියනවා, මිනිහෙක් code compile වෙන්නේ නෑ කියලා කෑගහනවා. අණ එකම වුනත් ක්රියාව වෙනස් වෙනවා.
Java වලදී අපි මේක කරන්නේ child classes වල තියෙන methods override කිරීමෙන්.
public class Animal {
public void makeSound() {
System.out.println("Some generic animal sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof! Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
දැන් මේ හැම animal කෙනෙක්වම පොදුවේ Animal type එකෙන් අරන් වැඩ කරද්දී code එක කොච්චර ලස්සන වෙනවද බලන්න:
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // Output එක: Woof! Woof!
myCat.makeSound(); // Output එක: Meow!
}
}
අපිට makeDogSound() හෝ makeCatSound() කියලා වෙන වෙනම methods ලියන්න අවශ්ය වෙන්නේ නැහැ. Java runtime එකේදීම තීරණය කරනවා කුමන method එකද run කරන්න ඕනේ කියලා. Polymorphism වල තියෙන ලස්සන ඒකයි.
4. Abstraction: "අවශ්ය දේ පමණක් පෙන්වීම"
ඔබ කාර් එකක් පදවද්දී කරන්නේ accelerator එක පාගන එක විතරයි. එතකොට කාර් එක ඉස්සරහට යනවා. හැබැයි ඒ වෙලාවට engine එක ඇතුලේ thermodynamics සිද්ධාන්ත ක්රියාත්මක වෙන හැටි, fuel injection වෙන හැටි ඔබ දැනගන්න ඕනෙද? නැහැ. ඒ සංකීර්ණ ක්රියාවලිය සඟවලා ඔබට සරල interface එකක් (accelerator pedal එක) දීලා තියෙනවා.
Abstraction කියන්නේ අන්න ඒ වගේ සංකීර්ණ implementation details සඟවලා, පරිශීලකයාට අවශ්ය අත්යවශ්ය දේවල් පමණක් පෙන්වීමයි. Java වලදී අපි මේක කරන්නේ abstract classes හෝ interfaces පාවිච්චි කරලයි.
// Abstract Class එකකින් blueprint එක දෙනවා
public abstract class CoffeeMachine {
// Abstract method: මේකේ body එකක් නැහැ, child classes මඟින් ලියන්න ඕනේ
public abstract void brewCoffee();
// Regular method: පොදු ක්රියාකාරීත්වය
public void boilWater() {
System.out.println("Boiling water to 90 degrees...");
}
}
// Concrete Class එකෙන් details ලියනවා
public class EspressoMachine extends CoffeeMachine {
@Override
public void brewCoffee() {
System.out.println("Forcing hot water through finely-ground coffee beans...");
}
}
EspressoMachine එක පාවිච්චි කරන කෙනාට brewCoffee() කියන method එක විතරයි දැනගන්න ඕනේ. ඇතුලාන්තයේ temperature එක check වෙන හැටි හෝ pressure valves ක්රියා කරන හැටි දැනගන්න අවශ්ය නැහැ. Abstraction මඟින් code එකේ සංකීර්ණත්වය ගොඩක් අඩු කරනවා.
සාරාංශය
මේ pillars හතර හරියට ඉගෙන ගත්තම ඔබ නිකන්ම code ලියන කෙනෙක් නෙවෙයි, පිරිසිදු සහ නඩත්තු කරන්න ලෙහෙසි software architecture එකක් නිර්මාණය කරන දක්ෂ software craftsman කෙනෙක් බවට පත්වෙනවා:
- Encapsulation මඟින් අපේ data ආරක්ෂා කරනවා.
- Inheritance මඟින් එකම code එක නැවත නැවත ලිවීම වළක්වනවා.
- Polymorphism මඟින් code එකට නම්යශීලී බවක් ලබාදෙනවා.
- Abstraction මඟින් අනවශ්ය සංකීර්ණත්වය සඟවනවා.
ඊළඟ පාර Java වලින් class එකක් ලියද්දී මේ කරුණු හතර ගැන හිතන්න. එතකොට ඔබට ඉතාමත් පිරිසිදු code එකක් ලියාගන්න පුළුවන් වේවි.


