Proxy Design Pattern | Lazy Loading | Security | SC Guide

කොහොමද යාලුවනේ! අද අපි කතා කරන්න යන්නේ Software Engineering වලට නැතුවම බැරි Design Pattern එකක් ගැන. ඒ තමයි Proxy Design Pattern එක. මේක අපිට අපේ application එකක security එකට හරි, performance එක වැඩි කරගන්න හරි, තව ගොඩක් දේවල් වලට හරිම ප්රයෝජනවත් වෙනවා.
ඔයාලා කෝපි කෝප්පයක් එහෙම තියාගෙන ලෑස්ති වෙන්න, මොකද මේක පොඩ්ඩක් ගැඹුරු වුණත් හරිම රසවත් මාතෘකාවක්!
Proxy Design Pattern එක කියන්නේ මොකක්ද?
සරලවම කිව්වොත්, Proxy Pattern එක කියන්නේ real object එකකට වෙනුවට ඒකේ surrogate හරි placeholder එකක් හරි නිර්මාණය කරන එකට. මේ surrogate එක තමයි proxy එක. අපි real object එකට කෙලින්ම යන්නෙ නැතුව, මේ proxy එක හරහා තමයි අපිට ඕන කරන service එක ලබා ගන්නේ. හරියට අපිට කෙනෙක් එක්ක කෙලින්ම කතා කරන්න බැරි වුණාම, එයාගේ agent කෙනෙක් හරහා කතා කරනවා වගේ වැඩක්.
මේ proxy එකට පුළුවන් real object එකට යන calls intercept කරන්න, ඒ calls වලට අමතර operations එකතු කරන්න, නැත්නම් real object එකට access එක control කරන්න. ඒ කියන්නේ proxy එක හරහා අපි real object එකට යන හැම ඉල්ලීමක්ම manage කරන්න පුළුවන් වෙනවා.
අපි හිතමු ඔයාලට Bank එකක වැඩක් කරගන්න ඕන කියලා. ඔයාලා කෙලින්ම Bank Manager ගාවට යන්නේ නෑනේ. මුලින් customer service officer කෙනෙක් ගාවට යනවා. එයාට පුළුවන් ඔයාලගේ පොඩි පොඩි ප්රශ්න විසඳන්න. එහෙම නැත්නම් එයාට බැරි වැඩකට විතරයි Manager ගාවට යවන්නේ. මෙතන Customer Service Officer කියන්නේ Bank Manager ගේ Proxy එක වගේ. Proxy එකට පුළුවන් lazy loading (අවශ්ය වුණාම විතරක් Manager ගාවට යවනවා), security (කවුද Manager ට කතා කරන්නේ කියලා බලනවා) වගේ දේවල් manage කරන්න.
Proxy Pattern එකේ Structure එක
- Subject Interface: Real Subject එකයි Proxy එකයි දෙකම implement කරන interface එක. මේකෙන් Client එකට ඕන කරන operations define කරනවා.
- Real Subject: Proxy එකෙන් වෙනුවට access කරන actual object එක. මේක තමයි core logic එක තියෙන්නේ.
- Proxy: Real Subject එක වෙනුවට Client එකත් එක්ක interact කරන object එක. Real Subject එකට access එක control කරනවා.
මේක තේරුම් ගන්න අපි පොඩි code snippet එකක් බලමු.
// Subject Interface
interface Image {
void display();
}
// Real Subject
class RealImage implements Image {
private String fileName;
public RealImage(String fileName) {
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName) {
System.out.println("Loading " + fileName + " from disk...");
// Simulate heavy loading operation
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Loaded " + fileName + ".");
}
}
// Proxy
class ProxyImage implements Image {
private String fileName;
private RealImage realImage;
public ProxyImage(String fileName) {
this.fileName = fileName;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(fileName); // Lazy Loading
}
realImage.display();
}
}
// Client Code
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image1 = new ProxyImage("photo_gallery_large_01.jpg");
Image image2 = new ProxyImage("photo_gallery_large_02.jpg");
System.out.println("\nFirst call to image1 display:");
image1.display(); // Image will be loaded for the first time
System.out.println("\nSecond call to image1 display:");
image1.display(); // Image will not be loaded again
System.out.println("\nFirst call to image2 display:");
image2.display(); // Image will be loaded for the first time
}
}
මේ code එකේ ProxyImage
එකෙන් කරන්නේ RealImage
එක load කරන එක අවශ්ය වෙනකල් කල් දාන එකයි. ඒ කියන්නේ අපි display()
method එක call කරනකල් RealImage
object එක create වෙන්නේ නෑ. මේකට අපි කියන්නේ Virtual Proxy හරි Lazy Loading හරි කියලා. මේකෙන් heavy resources manage කරන්න පුළුවන්.
Proxy Pattern එකේ විවිධ වර්ග (Types of Proxies)
Proxy Pattern එක පාවිච්චි කරන්න පුළුවන් විවිධ scenarios තියෙනවා. අපි ඒ කිහිපයක් බලමු:
1. Virtual Proxy (Lazy Loading)
මේක ගැන අපි කලින් කතා කළා. මේකේ ප්රධානම අරමුණ තමයි resource-intensive object එකක් create කරන එක, ඒක ඇත්තටම අවශ්ය වෙනකල් කල් දාන එක. උදාහරණයක් විදියට, විශාල images load කරන විට, database connection එකක් establish කරන විට, නැත්නම් network එකෙන් data retrieve කරන විට මේක ගොඩක් ප්රයෝජනවත් වෙනවා.
ඔයාලා දැකලා ඇති සමහර website වල images load වෙන්නේ අපි page එක scroll කරගෙන පහළට යනකොට විතරයි. මුළු page එකම එක පාර load කරන්නේ නෑ. ඒකෙන් page load time එක අඩු කරගන්න පුළුවන්. ඒ වගේ තැන් වලට මේ Virtual Proxy එක ගොඩක් ගැළපෙනවා.
2. Protection Proxy (Security/Access Control)
මේකේ අරමුණ තමයි real object එකකට access එක control කරන එක. ඒ කියන්නේ යම් user කෙනෙකුට හරි process එකකට හරි real object එකේ certain methods access කරන්න පුළුවන්ද නැද්ද කියලා තීරණය කරන්න මේ proxy එකට පුළුවන්. හරියට security guard කෙනෙක් වගේ වැඩ කරනවා.
උදාහරණයක් විදියට, අපි හිතමු අපිට බැංකු ගිණුමක (BankAccount) ශේෂය බලන්න (getBalance) සහ මුදල් දමන්න (deposit) හා ගන්න (withdraw) පුළුවන් service එකක් තියෙනවා කියලා. හැබැයි සමහර users ලාට (e.g., Guest users) ශේෂය බලන්න විතරක් පුළුවන් වෙන්න ඕන, මුදල් දාන්න හෝ ගන්න බැරි වෙන්න ඕන. එතකොට අපිට Protection Proxy එකක් පාවිච්චි කරන්න පුළුවන්.
// Subject Interface
interface BankAccount {
double getBalance();
void deposit(double amount);
void withdraw(double amount);
}
// Real Subject
class RealBankAccount implements BankAccount {
private double balance;
public RealBankAccount(double initialBalance) {
this.balance = initialBalance;
}
@Override
public double getBalance() {
return balance;
}
@Override
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: " + amount + ". New balance: " + balance);
} else {
System.out.println("Deposit amount must be positive.");
}
}
@Override
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
System.out.println("Withdrew: " + amount + ". New balance: " + balance);
} else {
System.out.println("Insufficient balance or invalid amount.");
}
}
}
// Protection Proxy
class BankAccountProxy implements BankAccount {
private RealBankAccount realAccount;
private String userRole; // e.g., "Admin", "Customer", "Guest"
public BankAccountProxy(RealBankAccount realAccount, String userRole) {
this.realAccount = realAccount;
this.userRole = userRole;
}
@Override
public double getBalance() {
// Anyone can check balance
System.out.println("Proxy: Checking balance...");
return realAccount.getBalance();
}
@Override
public void deposit(double amount) {
if (userRole.equals("Admin") || userRole.equals("Customer")) {
System.out.println("Proxy: Allowing deposit...");
realAccount.deposit(amount);
} else {
System.out.println("Proxy: Access Denied! Only Admin/Customer can deposit.");
}
}
@Override
public void withdraw(double amount) {
if (userRole.equals("Admin") || userRole.equals("Customer")) {
System.out.println("Proxy: Allowing withdrawal...");
realAccount.withdraw(amount);
} else {
System.out.println("Proxy: Access Denied! Only Admin/Customer can withdraw.");
}
}
}
// Client Code
public class BankDemo {
public static void main(String[] args) {
RealBankAccount myAccount = new RealBankAccount(1000.0);
// Customer access
BankAccount customerAccount = new BankAccountProxy(myAccount, "Customer");
System.out.println("\n--- Customer Actions ---");
System.out.println("Balance: " + customerAccount.getBalance());
customerAccount.deposit(200.0);
customerAccount.withdraw(150.0);
// Guest access
BankAccount guestAccount = new BankAccountProxy(myAccount, "Guest");
System.out.println("\n--- Guest Actions ---");
System.out.println("Balance: " + guestAccount.getBalance());
guestAccount.deposit(50.0); // This should be denied
guestAccount.withdraw(30.0); // This should be denied
}
}
මේ උදාහරණයේ BankAccountProxy
එක පාවිච්චි කරලා Guest
user කෙනෙකුට මුදල් දාන්න සහ ගන්න බැරි වෙන විදියට control කරනවා. ඒක තමයි Protection Proxy එකකින් කරන්නේ.
3. Remote Proxy
මේ proxy එක remote object එකකට local representation එකක් provide කරනවා. ඒ කියන්නේ client එකට remote object එකක් එක්ක interact කරන්න පුළුවන් වෙන්නේ local proxy එකක් හරහා. RMI (Remote Method Invocation) වගේ distributed systems වල මේක බහුලව පාවිච්චි කරනවා.
4. Smart Reference Proxy
Real object එකට reference කරන විට අමතර actions කරන proxy එකක්. උදාහරණයක් විදියට, object එකක් lock කරන එක, access count කරන එක වගේ දේවල්. මේක විශේෂයෙන් garbage collection නැති භාෂා වල resource management වලට ප්රයෝජනවත් වෙනවා.
Proxy Pattern එක පාවිච්චි කරන්න ඕන කවද්ද?
ඔබට Proxy Pattern එක පාවිච්චි කරන්න පුළුවන් මේ වගේ අවස්ථාවලදී:
- Lazy Loading: Object එකක් create කරන්න විශාල resources (memory, CPU time) අවශ්ය නම්, ඒක අවශ්ය වෙනකල් කල් දාන්න.
- Access Control: Object එකකට access කරන client ගේ අවසරය (permissions) අනුව access එක control කරන්න.
- Remote Object Access: Distributed system එකක remote object එකකට local access provide කරන්න.
- Logging: Object එකේ method calls log කරන්න.
- Caching: Object එකේ result cache කරලා, එකම request එක ආයෙත් ආවොත් cache එකෙන් result එක දෙන්න.
- Concurrency Control: Multiple clients ලා එකම object එකට access කරනකොට synchronization manage කරන්න.
Proxy Pattern එකේ වාසි සහ අවාසි
වාසි (Advantages):
- Reduced resource consumption: Lazy loading හරහා object එකක් අවශ්ය වෙනකල් create නොකර ඉන්න පුළුවන්.
- Enhanced security: Access control implementation කරන්න පුළුවන්.
- Separation of concerns: Core business logic එකෙන් access control, logging වගේ දේවල් වෙන් කරන්න පුළුවන්.
- Remote access simplification: Client එකට remote objects එක්ක local objects වගේ interact කරන්න පුළුවන්.
- Flexibility: Real object එකේ code එක වෙනස් නොකර අමතර functionality එකතු කරන්න පුළුවන්.
අවාසි (Disadvantages):
- Increased complexity: Proxy Layer එකක් එකතු කිරීමෙන් system එකේ complexity එක වැඩි වෙන්න පුළුවන්.
- Potential performance overhead: Proxy layer එක හරහා යන නිසා method calls වලට පොඩි overhead එකක් එකතු වෙන්න පුළුවන්.
- Debugging challenges: Proxy layer එකක් තියෙන නිසා debugging කරනකොට actual call stack එක trace කරන එක පොඩ්ඩක් අමාරු වෙන්න පුළුවන්.
අවසන් වචනය
Proxy Design Pattern එක කියන්නේ Software Engineering වලදී හරිම වැදගත් සහ ප්රයෝජනවත් tool එකක්. Lazy loading, security, caching වගේ දේවල් වලට මේක බහුලව පාවිච්චි කරනවා. මේක හොඳට තේරුම් ගත්තොත්, ඔයාලට පුළුවන් robust සහ efficient applications නිර්මාණය කරන්න. මතක තියාගන්න, Design Patterns කියන්නේ solution එකක් නෙවෙයි, solution එකකට යන මඟ පෙන්නුම් කරන මාර්ග සිතියමක් වගේ දෙයක්!
ඔයාලත් මේ Proxy Pattern එක ගැන තවදුරටත් හොයලා බලන්න, පුළුවන් නම් ඔයාලගේ project එකක implement කරලා බලන්න. එතකොට concepts ටික හොඳටම තේරෙයි. මේ ගැන ඔයාලට තියෙන අදහස්, ප්රශ්න පහළින් comment කරන්න. අපි ලබන ලිපියෙන් තවත් වැදගත් මාතෘකාවක් ගැන කතා කරමු. ආයෙත් හම්බවෙමු!