Facade Design Pattern | කේතය සරල කරමු | Software Engineering SC

Facade Design Pattern | කේතය සරල කරමු | Software Engineering SC

Simplify Your Code with Facade Design Pattern SC Guide

Software Engineering Field එකේ ඉන්න අපිට හැමදාම වගේ මුහුණ දෙන්න වෙන ප්‍රශ්නයක් තමයි code එක complex වෙන එක. වැඩේ ලොකු වෙනකොට, modules ගොඩක් එකට එකතු වෙනකොට, එක service එකක් තව services ගොඩක් එක්ක කතා කරනකොට අපේ code base එක මහ වල්ගස් වත්තක් වගේ වෙන්න පුළුවන්. ඒ කියන්නේ, code එක තේරුම් ගන්නත් අමාරුයි, maintain කරන්නත් අමාරුයි, අලුත් දෙයක් එකතු කරන්න ගියාමත් ඉවරයක් නැති අවුලක් වෙනවා. මේ වගේ වෙලාවලට තමයි Design Patterns කියන එක අපේ ගැලවුම්කාරයා වෙන්නේ. අද අපි කතා කරන්න යන්නේ ඒ වගේ නිතරම වගේ අපිට උදව් වෙන, code එක simplify කරගන්න පුළුවන් Design Pattern එකක් ගැන – ඒ තමයි Facade Design Pattern එක.

සරලව කිව්වොත්, Facade (උච්චාරණය 'ෆසාඩ්') කියන්නේ complex subsystem එකකට උඩින් තියෙන simple interface එකක්. හිතන්න, ඔයාගේ ගෙදර තියෙන Home Theater system එක ගැන. ඒකේ TV එක, Blu-ray player එක, Amplifier එක, Speakers වගේ devices ගොඩක් තියෙනවා. ඒ හැම එකටම වෙන වෙනම remote control පාවිච්චි කරනවට වඩා, එක Smart Remote එකකින් මේ හැම දේම පාලනය කරන්න පුළුවන් නම් කොච්චර ලේසිද? Facade Pattern එකත් හරියට ඒ වගේ තමයි. Subsystem එකක තියෙන සියලුම complex operations ටික සඟවලා, client එකට අවශ්‍ය කරන පහසු, සරල ක්‍රමවේදයක් (method) විතරක් expose කරනවා.

ඉතින්, මේක කොහොමද අපිට ප්‍රයෝජනවත් වෙන්නේ? කොහොමද මේක implement කරන්නේ? මේ හැම දෙයක්ම අද අපි බලමු. විශේෂයෙන්ම, services කිහිපයක් එකට join කරලා complex task එකක් කරන project එකකදී Facade Pattern එක කොහොමද පාවිච්චි කරන්නේ කියලා practical example එකක් එක්ක කතා කරමු.

Facade Pattern එක කියන්නේ මොකක්ද? (What is Facade Pattern?)

Facade කියන වචනේ තේරුම “ගොඩනැගිල්ලක මුහුණත” කියන එක. මේ pattern එකත් ඒ වගේම තමයි, software system එකක ውስතර complex operations ටික සඟවලා, client එකට පේන්න simple interface එකක් හදනවා. Gamma et al. විසින් රචිත “Design Patterns: Elements of Reusable Object-Oriented Software” කියන පොතේ මේක structural design pattern එකක් විදියට හඳුන්වලා දෙනවා. ඒ කියන්නේ, මේක objects සහ classes කොහොමද එකිනෙක සම්බන්ධ වෙන්නේ කියලා define කරන pattern එකක්.

Facade pattern එකේ ප්‍රධාන අරමුණ වෙන්නේ subsystem එකක තියෙන complexities ටික client code එකෙන් හංගලා, client code එකට ඒ subsystem එකත් එක්ක interaction එක සරල කරන එකයි. ඒ කියන්නේ, client එකට subsystem එකේ තියෙන classes ගොඩක් ගැන, ඒවායේ methods ගැන, ඒවා අතර තියෙන dependencies ගැන දැනගන්න අවශ්‍ය වෙන්නේ නැහැ. Client එකට අවශ්‍ය වෙන්නේ Facade class එකේ තියෙන එක method එකක් විතරයි call කරන්න. ඒ method එක ඇතුලේ Facade class එක විසින් අවශ්‍ය කරන subsystem classes ටික create කරලා, ඒවායේ අවශ්‍ය methods ටික call කරලා, අවසානයේ client එකට අවශ්‍ය result එක return කරනවා.

උදාහරණයක් විදියට, ඔයා film එකක් බලන්න cinema එකට ගියා කියලා හිතන්න. ඔයාට film එක බලන්න නම්, ticket එකක් ගන්න ඕන, popcorn ගන්න ඕන, seating arrangement එකක් බලන්න ඕන, hall එකට යන්න ඕන. මේ හැම දේම ඔයාට තනියම කරන්න පුළුවන් වුණාට, ඒ හැම එකටම වෙන වෙනම කවුන්ටර, තැන්, instructions තියෙනවා. ඒත් cinema එකේ reception desk එකේ ඉන්න කෙනෙක් ඔයාට මේ හැමදේම ഒറ്റ package එකක් විදියට organize කරලා දෙනවා නම් කොච්චර ලේසිද? Facade එකත් හරියට ඒ reception desk එක වගේ තමයි. Client එකට අවශ්‍ය කරන හැම complex task එකක්ම single point of entry එකකින් manage කරනවා.

Facade Pattern එකෙන් අපිට මොනවද ලැබෙන්නේ? (Benefits of Facade Pattern)

මේ Facade Pattern එක පාවිච්චි කරන එකෙන් අපිට ගොඩක් වාසි තියෙනවා. විශේෂයෙන්ම ලොකු software projects වලදී මේකේ වටිනාකම හොඳටම තේරෙනවා. අපි බලමු ඒ වාසි මොනවද කියලා:

  • සරල බව (Simplicity): මේක තමයි ප්‍රධානම වාසිය. Client code එකට complex subsystem එකක් එක්ක deal කරන්න ඕන වෙන්නේ නැහැ. Facade එක simple interface එකක් දෙන නිසා, code එක කියවන්න, තේරුම් ගන්න, සහ පාවිච්චි කරන්න ගොඩක් පහසු වෙනවා.
  • පොදු බව අඩු කිරීම (Reduced Coupling): Client code එක Facade එකත් එක්ක විතරයි connect වෙන්නේ, subsystem එකේ තියෙන classes ගොඩක් එක්ක නෙවෙයි. මේ නිසා subsystem එක ඇතුලේ වෙන changes, client code එකට බලපාන්නේ නැහැ. මේක maintenance වලට සහ future expansions වලට ගොඩක් වැදගත්.
  • නඩත්තු කිරීම පහසු වීම (Easier Maintenance): Subsystem එකක තියෙන operations modify කරන්න ඕන වුණාම, අපිට modify කරන්න වෙන්නේ Facade එක ඇතුලේ තියෙන code එක විතරයි. Client code එකට ඒ වෙනස්කම් බලපාන්නේ නැහැ.
  • පද්ධතියේ ව්‍යුහය පැහැදිලි වීම (Improved System Structure): Facade Pattern එකෙන් system එකට clear layering එකක් හදනවා. Subsystem එකේ internal structure එක hidden වෙන නිසා, system එකේ overall architecture එක පැහැදිලි වෙනවා.
  • API එකක් වගේ ක්‍රියා කිරීම (Acts like an API): Facade එකක් කියන්නේ subsystem එකට තියෙන custom API එකක් වගේ ක්‍රියා කරනවා. ඒ කියන්නේ client එකට subsystem එකේ functionality එක use කරන්න පුළුවන් පැහැදිලි, හොඳින් define කරපු entry point එකක් අපිට ලැබෙනවා.

Facade Pattern එක කවදද පාවිච්චි කරන්නේ? (When to Use Facade Pattern?)

Facade Pattern එක හැම තැනටම ගැලපෙන්නේ නැහැ. ඒත් සමහර අවස්ථාවලදී මේක අනිවාර්යයෙන්ම පාවිච්චි කරන්න ඕන වෙනවා. අපි බලමු ඒ මොන වගේ අවස්ථාද කියලා:

  • Complex subsystem එකකට simple interface එකක් දෙන්න ඕන වෙලාවට: ඔයාගේ system එකේ classes ගොඩක් තියෙන, ඒවා අතර complex dependencies තියෙන subsystem එකක් තියෙනවා නම්, ඒක client එකට expose කරන්න කලින් Facade එකක් හදන එක ගොඩක් හොඳයි.
  • Client එක subsystem එකේ classes ගොඩක් එක්ක direct interaction එකෙන් නවත්වන්න ඕන වෙලාවට: Client code එකට subsystem එකේ internal working එක ගැන දැනගන්න අවශ්‍ය නැතිනම්, Facade එකක් පාවිච්චි කරලා ඒ knowledge requirement එක අඩු කරන්න පුළුවන්.
  • System එක layers වලට බෙදන්න ඕන වෙලාවට: Architecture එකේදී layers වෙන් කරන්න (e.g., presentation layer, business logic layer, data access layer) Facade එකක් පාවිච්චි කරන්න පුළුවන්. Facade එකක් layer එකක entry point එකක් විදියට ක්‍රියා කරන්න පුළුවන්.
  • Existing library එකකට හෝ framework එකකට simple access point එකක් දෙන්න ඕන වෙලාවට: 3rd party library එකක් හෝ framework එකක් ගොඩක් complex නම්, ඒකේ පොදු operations ටික Facade එකක් හරහා expose කරන්න පුළුවන්.

උදාහරණයක් විදියට, imagine an online ordering system. Order එකක් දාද්දී, system එකට inventory service එකත් එක්ක කතා කරන්න වෙනවා, payment service එකත් එක්ක කතා කරන්න වෙනවා, shipping service එකත් එක්ක කතා කරන්න වෙනවා, notification service එකත් එක්ක කතා කරන්න වෙනවා. මේ හැම service එකක්ම වෙන වෙනම call කරනවට වඩා, OrderFacade එකක් හදලා, placeOrder(items, paymentInfo, shippingAddress) වගේ එක method එකකින් මේ හැම දේම handle කරන්න පුළුවන්.

ප්‍රායෝගික උදාහරණයක්: Multi-Service Call එකක් Facade එකකින් සරල කරමු (Practical Example: Simplifying a Multi-Service Call with Facade)

දැන් අපි බලමු practical scenario එකක් හරහා Facade pattern එක කොහොමද ක්‍රියා කරන්නේ කියලා. අපි හිතමු අපිට User Registration process එකක් තියෙනවා කියලා. මේ process එකට tasks කිහිපයක් එක දිගට කරන්න ඕන:

  1. User Account එකක් register කරන්න.
  2. Initial Payment එකක් process කරන්න (e.g., subscription fee).
  3. Welcome Email එකක් send කරන්න.

මේ හැම task එකක්ම වෙනම service එකකින් handle කරනවා කියලා හිතමු.

Subsystem Classes (Subsystems)

මුලින්ම, අපිට මේ tasks handle කරන වෙන වෙනම classes ටික හදාගමු. මේවා තමයි අපේ complex subsystem එකේ components.

class UserManagementService:
    def register_user(self, username, password):
        print(f"User '{username}' registered successfully.")
        return True

class PaymentGatewayService:
    def process_payment(self, user_id, amount):
        print(f"Payment of {amount} processed for user ID '{user_id}'.")
        return True

class EmailService:
    def send_welcome_email(self, email):
        print(f"Welcome email sent to {email}.")
        return True

මේවා අපේ backend එකේ තියෙන services කියලා හිතන්න. Client එකට direct මේ services ටික use කරන්න පුළුවන් වුණාට, එතකොට client code එක complex වෙනවා.

Without Facade (Facade එකක් නැතුව)

Facade එකක් නැතුව, client code එක මේ services ටික call කරන්නේ මෙහෙමයි:

# Client code without Facade

user_service = UserManagementService()
payment_service = PaymentGatewayService()
email_service = EmailService()

username = "dilani_perera"
password = "securepassword123"
email = "[email protected]"
amount = 50.00

print("---- Starting Registration WITHOUT Facade ----")

if user_service.register_user(username, password):
    if payment_service.process_payment(username, amount):
        email_service.send_welcome_email(email)
        print("Registration process WITHOUT Facade completed successfully!")
    else:
        print("Payment failed. Registration incomplete.")
else:
    print("User registration failed. Registration incomplete.")

print("-------------------------------------------")

මේ code එක බලන්න. Client code එකට services තුනක් ගැන දැනගන්න ඕන. ඒ වගේම, ඒ services ටික call කරන්න ඕන sequence එකත් client එකට manage කරන්න වෙනවා. මේ වගේ registration process එකක් system එකේ තැන් ගොඩක පාවිච්චි කරනවා නම්, මේ code block එක හැම තැනම copy paste කරන්න වෙනවා. ඒක හොඳ practice එකක් නෙවෙයි, මොකද service එකක වෙනසක් වුණොත් තැන් ගොඩක change කරන්න වෙනවා.

With Facade (Facade එකක් එක්ක)

දැන් අපි Facade එකක් හදලා මේ process එක කොහොමද simplify කරන්නේ කියලා බලමු. අපි UserRegistrationFacade කියලා class එකක් හදාගමු.

class UserRegistrationFacade:
    def __init__(self):
        self._user_service = UserManagementService()
        self._payment_service = PaymentGatewayService()
        self._email_service = EmailService()

    def register_user_with_payment(self, username, password, email, amount):
        print("Starting user registration process with Facade...")
        if self._user_service.register_user(username, password):
            if self._payment_service.process_payment(username, amount):
                self._email_service.send_welcome_email(email)
                print("User registration with payment completed successfully!")
                return True
        print("User registration with payment failed!")
        return False

දැන් අපේ Facade class එක, subsystem එකේ classes ටික create කරලා, ඒවායේ methods ටික organize කරලා තියෙනවා. Client එකට දැන් අවශ්‍ය වෙන්නේ UserRegistrationFacade එකේ register_user_with_payment කියන එක method එක විතරයි call කරන්න.

# Client code with Facade

registration_facade = UserRegistrationFacade()

new_username = "nuwan_bandara"
new_password = "pass123"
new_email = "[email protected]"
new_amount = 75.00

print("---- Starting Registration WITH Facade ----")

if registration_facade.register_user_with_payment(new_username, new_password, new_email, new_amount):
    print("Nuwan's registration was a success!")
else:
    print("Nuwan's registration failed.")

print("-------------------------------------------")

දැන් බලන්න, client code එක කොච්චර සරලද කියලා. Client එකට UserManagementService, PaymentGatewayService, EmailService කියන classes ගැන දැනගන්න අවශ්‍ය නැහැ. ඒ වගේම, registration process එකේ steps මොනවද කියලවත් client එකට දැනගන්න ඕන වෙන්නේ නැහැ. ඒ හැම දෙයක්ම Facade එක ඇතුලේ manage වෙනවා. මේකෙන් code එකේ readability එක ගොඩක් වැඩි වෙනවා වගේම, maintain කරන්නත් පහසු වෙනවා. උදාහරණයක් විදියට, අනාගතයේදී registration process එකට SMS verification එකක් වගේ අලුත් step එකක් එකතු කරන්න ඕන වුණොත්, අපිට වෙනස් කරන්න වෙන්නේ Facade class එකේ register_user_with_payment method එක විතරයි. Client code එකට ඒකෙන් කිසිම බලපෑමක් වෙන්නේ නැහැ.

මතක තියාගන්න ඕන දේවල් (Things to Remember)

Facade Pattern එක use කරද්දී මතක තියාගන්න ඕන වැදගත් කරුණු කිහිපයක් තියෙනවා:

  • Facade එක subsystem එකට direct access එක නවත්වන්න අවශ්‍ය නැහැ: Facade එක කියන්නේ පහසු interface එකක් මිසක්, subsystem එකේ අනිත් classes වලට direct access එක නවත්වන barrier එකක් නෙවෙයි. Client එකට අවශ්‍ය නම්, Facade එක මගහැරලා direct subsystem classes use කරන්න පුළුවන් වෙන්න ඕන (සමහර complex operations වලට).
  • Facade එක "fat" කරන්න එපා: Facade එක ඕනෑවට වඩා විශාල වෙන්න දෙන්න එපා. ඒක එක cohesive operation එකක් හෝ පොදු task එකක් simplify කරන්න ඕන. Facade එකේ methods ගොඩක් තිබ්බොත්, ඒකත් තව complex subsystem එකක් බවට පත් වෙන්න පුළුවන්.
  • මේක structural pattern එකක්: Facade Pattern එක class හෝ object structures organize කරනවා මිසක්, objects අතර behaviour describe කරන්නේ නැහැ.
  • වෙනත් patterns එක්ක combine කරන්න පුළුවන්: Singleton pattern එක වගේ දේවල් එක්ක Facade එක combine කරන්න පුළුවන්, Facade class එකට single instance එකක් තියෙන්න ඕන නම්.

අවසාන වශයෙන් (In Conclusion)

ඉතින්, Facade Design Pattern එක කියන්නේ complex software systems හදන අපිට නැතිවම බැරි tool එකක්. මේක පාවිච්චි කරලා අපිට code එකේ complexity එක අඩු කරගන්න, maintainability එක වැඩි කරගන්න, සහ code base එක cleaner කරගන්න පුළුවන්. මතක තියාගන්න, හොඳ software design එකක් කියන්නේ ලස්සනට code ලියන එක විතරක් නෙවෙයි, අනිත් අයට තේරුම් ගන්න පුළුවන්, maintain කරන්න පුළුවන්, future changes වලට ඔරොත්තු දෙන විදියට structure කරන එකත් ඒකට අයිතියි.

ඔයාලත් මේ Facade pattern එක ගැන මොනවද හිතන්නේ? ඔයාලගේ project වල මේක පාවිච්චි කරලා තියෙනවද? නැත්නම් මේ වගේ situation එකකට ඔයාලා වෙනත් approach එකක් පාවිච්චි කරනවද? පහළ comment section එකේ අපිට කියන්න. ඔයාලගේ අදහස්, අත්දැකීම් බෙදාගන්න එක අනිත් අයටත් ගොඩක් වටිනවා.

තවත් මේ වගේ ප්‍රයෝජනවත් Design Pattern එකක් ගැන හරි, software engineering topic එකක් ගැන හරි කතා කරන්න, අපේ SC Guide එකත් එක්කම එකතු වෙලා ඉන්න!