എൻക്യാപ്സുലേഷൻ (കമ്പ്യൂട്ടർ പ്രോഗ്രാമിംഗ്)

എൻക്യാപ്സുലേഷൻ എന്നത് ഒരു ക്ലാസിനുള്ളിലെ ഡാറ്റയുടെ മൂല്യങ്ങളോ സ്റ്റേറ്റോ മറച്ചുവെക്കാനുള്ള ഒരു ടെക്നിക്കാണ്. ഇത് ക്ലാസിന് പുറത്തുള്ള ഉപയോക്താക്കളെ (clients) നേരിട്ട് ഡാറ്റ ആക്സസ് ചെയ്യുന്നത് തടയുന്നു. എൻക്യാപ്സുലേഷൻ, പുറത്തുള്ള കോഡിന് ഒരു വസ്തുവിന്റെ ഉള്ളടക്കം എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത് എന്ന് അറിയാതെ തന്നെ, അവയെ എങ്ങനെ ഉപയോഗിക്കാമെന്നുള്ള രീതി മാത്രമേ അനുവദിക്കു. ഇതിലൂടെ, അവയുടെ അകത്തുള്ള വിവരങ്ങൾ നിയന്ത്രിക്കപ്പെടുകയും, ഒരു സിസ്റ്റം സുരക്ഷിതവും എളുപ്പവുമാകുകയും ചെയ്യുന്നു. ഇത്, വെളിപ്പെടുത്താതെയുള്ള വിവരങ്ങൾ (Data Hiding) ഉപയോഗിച്ച് സിസ്റ്റത്തിന് നിയന്ത്രണം നൽകുന്നു, അങ്ങനെ പ്രവർത്തനങ്ങൾ ഇങ്ങനെ മറഞ്ഞിരിക്കുന്നതിലൂടെ തെറ്റായ ഉപയോഗം തടയുന്നു.

എൻക്യാപ്സുലേഷൻ, ഡെവലപ്പർമാർക്ക് സോഫ്‌റ്റ്‌വെയർ എങ്ങനെ പ്രവർത്തിക്കുന്നുവെന്ന് മറച്ച് വെക്കുന്നു, എളുപ്പത്തിൽ ഉപയോഗിക്കാവുന്ന ഒരു  ഇന്റർഫേസ് നൽകുകയും ചെയ്യുന്നു. ഉപയോക്താവിന് അതിന്റെ ഉള്ളടക്കങ്ങൾ എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് അറിയേണ്ടതില്ല, അവർക്ക് അതിനെ എങ്ങനെ ഉപയോഗിക്കാമെന്ന് മാത്രമേ അറിയേണ്ടത്. ഇത് ക്ലാസിന്റെ മെത്തേഡുകൾ വഴി മാത്രമേ ഡാറ്റ ആക്സസ് ചെയ്യാൻ അനുവദിക്കുന്നുള്ളൂ, അത് സുരക്ഷിതവും കൃത്യവുമായ ഡാറ്റ മാനേജ്മെന്റ് ഉറപ്പാക്കുന്നു.

എൻക്യാപ്സുലേഷൻ എന്നത് ഡാറ്റയും അതുമായി ബന്ധപ്പെട്ട കോഡും ഒരു ക്ലാസ്സിൽ ഒന്നിച്ച് നിർത്തി കോഡ് എളുപ്പത്തിൽ മനസ്സിലാക്കാൻ സഹായിക്കുന്നു. ഇതു കൊണ്ട് മറ്റുള്ള പ്രോഗ്രാമർമാർക്ക് കോഡ് എളുപ്പത്തിൽ പഠിക്കാൻ കഴിയുകയും, തിരുത്താനും പരിഷ്കരിക്കാനും കഴിയുന്നു. ഇതാണ് ഡാറ്റയുടെ ഡികപ്ലിംഗ് (decoupling) പ്രോത്സാഹിപ്പിക്കുന്നത്(ഡികപ്ലിംഗ് എന്നത് കോഡിന്റെ വിവിധ ഭാഗങ്ങൾ പരസ്പരം ആശ്രിതമല്ലാതെ പ്രവർത്തിക്കുകയെന്നതാണ്. ഇത് സോഫ്റ്റ്‌വെയർ ഡവലപ്‌മെന്റ്‌ ലോജിക് ഏറ്റവും സുതാര്യവും എളുപ്പവുമായ രീതിയിൽ എഴുതാൻ സഹായിക്കുന്നു).
ഇവിടെ എൻ‌കാപ്‌സുലേഷൻ (Encapsulation)  ഡികപ്ലിംഗ് (Decoupling) എന്നിവ ഉൾപ്പെടുന്ന ഒരു ലളിതമായ ജാവാസ്ക്രിപ്റ്റ് ഉദാഹരണം നൽകുന്നു:
```javascript
// ക്ലാസ്: BankAccount
class BankAccount {
  constructor(balance) {
    let _balance = balance; // പ്രൈവറ്റ് വേരിയബിൾ (എൻകാപ്സുലേഷൻ)

    // പബ്ലിക് മെത്തേഡുകൾ
    this.deposit = (amount) => {
      if (amount > 0) {
        _balance += amount;
        console.log(`പണമിടപാട് ചെയ്തിരിക്കുന്നു: ${amount}. പുതിയ ബാലൻസ്: ${_balance}`);
      } else {
        console.log("തെറ്റായ പണമിടപാട് മൂലമുള്ള തുക!");
      }
    };

    this.withdraw = (amount) => {
      if (amount > 0 && amount <= _balance) {
        _balance -= amount;
        console.log(`പണം പിൻവലിച്ചത്: ${amount}. പുതിയ ബാലൻസ്: ${_balance}`);
      } else {
        console.log("തെറ്റായി പണം പിൻവലിക്കാൻ നൽകിയ തുക!");
      }
    };

    this.getBalance = () => {
      return _balance; // എൻകാപ്സുലേറ്റ് ചെയ്ത ബാലൻസ്
    };
  }
}

// ഉപയോഗം
const account = new BankAccount(1000); // ആരംഭ ബാലൻസ്: 1000
account.deposit(500); // പണമിടപാട് ചെയ്തിരിക്കുന്നു: 500. പുതിയ ബാലൻസ്: 1500
account.withdraw(200); // പണം പിൻവലിച്ചത്: 200. പുതിയ ബാലൻസ്: 1300
console.log("നിലവിലെ ബാലൻസ്:", account.getBalance()); // നിലവിലെ ബാലൻസ് കാണിച്ചിരിക്കുന്നത്: 1300
```
വിശദീകരണം
എൻ‌കാപ്‌സുലേഷൻ:
`_balance` എന്ന വേരിയബിൾ പ്രൈവറ്റ് ആയി മാറ്റി (encapsulation). ഇത് ക്ലാസിന് പുറത്ത് നിന്ന് നേരിട്ട് പ്രവേശിക്കാൻ കഴിയില്ല. `deposit`, `withdraw`, `getBalance` എന്നീ പബ്ലിക് മെത്തേഡുകൾ വഴി മാത്രമേ ബാലൻസ് മാനേജ് ചെയ്യാൻ കഴിയൂ. `_balance` പ്രൈവറ്റ് ആക്കുന്നത്, മറ്റുള്ളവർക്ക് അത് നേരിട്ട് മാറ്റാൻ കഴിയാതിരിക്കാൻ ആണ്. അങ്ങനെ തെറ്റായ മാറ്റങ്ങൾ ഒഴിവാക്കാം.
ഡികപ്ലിംഗ്:
ക്ലാസിന്റെ ഇന്റർണൽ ഇംപ്ലിമെന്റേഷൻ (ഉദാ: `_balance`) ക്ലാസിന് പുറത്തുള്ള ഉപയോക്താക്കളിൽ നിന്ന് വേർതിരിച്ചിരിക്കുന്നു. ക്ലാസിന്റെ ഇന്റേണൽ ലോജിക്ക് മാറ്റം വരുത്തിയാലും, ക്ലാസ്  ഉപയോഗിക്കുന്ന ഉപയോക്താക്കൾക്ക് ബാധകമാകില്ല.
റിസൾട്ട്
ക്ലാസിന്റെ ഡാറ്റ (`_balance`) സുരക്ഷിതമാണ്. നടപ്പാക്കുന്നത് മാറ്റിയാലും, മറ്റ് കോഡുകൾ സ്വതന്ത്രമായി പ്രവർത്തിക്കും. ഇതിനെയാണ് ഡികപ്ലിംഗ് എന്ന് പറയുന്നത്.

എല്ലാ ഒബ്ജക്റ്റ്-ഓറിയന്റഡ് പ്രോഗ്രാമിംഗ് (OOP) സിസ്റ്റങ്ങളും എൻ‌ക്യാപ്‌സുലേഷൻ പിന്തുണയ്ക്കുന്നു, പക്ഷേ എൻക്യാപ്സുലേഷൻ ഊപ്സിൽ(OOPs) മാത്രം പ്രത്യേകമല്ല. അബ്‌സ്ട്രാക്റ്റ് ഡാറ്റാ ടൈപ്പുകൾ, മൊഡ്യൂളുകൾ, ലൈബ്രറികൾ തുടങ്ങിയവയും എൻ‌കാപ്‌സുലേഷൻ നൽകുന്നു. പ്രോഗ്രാമിംഗ് ഭാഷാ സിദ്ധാന്തകർ ഇതിനെ "എക്സിസ്റ്റൻഷ്യൽ ടൈപ്പുകൾ" (existential types) എന്ന ആശയത്തിലൂടെ വിശദീകരിക്കുന്നു.
അർത്ഥം
ഒബ്ജക്റ്റ്-ഓറിയന്റഡ് പ്രോഗ്രാമിംഗ് (OOP) ഭാഷകളിലും മറ്റ് ബന്ധപ്പെട്ട ഫീൽഡുകളിലും, എൻ‌ക്യാപ്‌സുലേഷൻ എന്നത് പ്രധാനമായും രണ്ട് വ്യത്യസ്തമായ ആശയങ്ങളെ സൂചിപ്പിക്കുന്നു. ചില സന്ദർഭങ്ങളിൽ, ഈ രണ്ട് ആശയങ്ങളും ഒന്നിച്ച് ഉപയോഗിക്കാറുണ്ട്:
ഒരു ഒബ്ജക്റ്റിന്റെ ചില ഘടകങ്ങളിലേക്ക് നേരിട്ട് പ്രവേശിക്കുന്നത് നിയന്ത്രിക്കുന്ന ഭാഷാ സംവിധാനമാണ് ഇത്. ഇത് ഒബ്ജക്റ്റിന്റെ എൻക്യാപ്സുലേഷൻ സംരക്ഷിക്കുന്നതിന് സഹായിക്കുന്നു.
ഡാറ്റയും അതിന്റെ പ്രവർത്തനങ്ങളും ഒരുമിച്ച് സൂക്ഷിക്കുന്ന ഒരു രീതി ആണ്. ഇതിലൂടെ ഒരു ഒബ്ജക്റ്റിന്റെ ഡാറ്റയുമായി ബന്ധപ്പെട്ട പ്രവർത്തനങ്ങൾ എല്ലാം ചേർന്ന് ഒന്നാകുന്നതാണ്, അതിനാൽ അത് എളുപ്പത്തിൽ നിയന്ത്രിക്കാനും ഉപയോഗിക്കാനും സാധിക്കും.

ചില പ്രോഗ്രാമിംഗ് ഭാഷകൾ "ഒബ്ജക്റ്റ്-ഓറിയന്റഡ്" സിസ്റ്റത്തെ തിരിച്ചറിയുന്നതിനായി എൻക്യാപ്സുലേഷൻ ഉപയോഗിക്കുന്നു. എന്നാൽ മറ്റു ചില ഭാഷകൾ, എൻക്യാപ്സുലേഷൻ ഒരു സ്വതന്ത്ര സവിശേഷതയായി പരിഗണിക്കുന്നു, ഒബ്ജക്റ്റ്-ഓറിയന്റഡ് പ്രോഗ്രാമിങ്ങിൽ അതിന്റെ പ്രാധാന്യത്തോടു ചേർക്കാതെ തന്നെ. ഇത് ഒബ്ജക്റ്റ്-ഓറിയന്റഡ് സിസ്റ്റങ്ങൾക്കുള്ള വ്യത്യസ്ത സമീപനങ്ങളെക്കുറിച്ച് പറയുന്നു. ലെക്സിക്കൽ ക്ലോഷറുകൾ (Lexical Closures) ഉള്ള പ്രോഗ്രാമിംഗ് ഭാഷകൾ (ഉദാ: JavaScript, Python) എൻ‌ക്യാപ്‌സുലേഷൻ എന്നത് ഒബ്ജക്റ്റ് ഓറിയെന്റഡ് പ്രോഗ്രാമിംഗിൽ നിന്ന് സ്വതന്ത്രമായ (orthogonal) ഒരു ഫീച്ചറായി കാണുന്നു.  ഇവിടെ, ഫംഗ്ഷനുകൾ അവയുടെ സ്കോപ്പിനുള്ളിലെ വേരിയബിളുകൾ മറച്ചുവെക്കാൻ കഴിയും, അത് ഒബ്ജക്റ്റ് ഓറിയെന്റഡ് കൺസെപ്റ്റുകൾ ഇല്ലാതെ തന്നെ എൻ‌ക്യാപ്‌സുലേഷൻ നൽകുന്നു. (ലെക്സിക്കൽ ക്ലോഷർ എന്നത്, ഒരു ഫംഗ്ഷൻ അതിന്റെ ഉള്ളിൽ വരുന്ന വേരിയബിൾസുമായി പ്രവർത്തിക്കുന്ന ഒരു രീതിയാണ്, അവ പുറത്തു നിന്നും നേരിട്ട് പ്രവേശിക്കാൻ സാധിക്കില്ല. ഇത്, പ്രൈവറ്റ് ഡാറ്റ സംഭരിക്കുകയും അതിനെ നിയന്ത്രിക്കാനും പുറത്ത് നിന്നുള്ളവയെ സംരക്ഷിക്കാനും സഹായിക്കുന്നു.)
ഉദാഹരണം ലെക്സിക്കൽ ക്ലോഷർ ഉപയോഗിച്ചിട്ടുള്ള എൻ‌ക്യാപ്‌സുലേഷൻ ജാവാസ്ക്രിപ്റ്റിൽ
function counter() {
    // 'count' എന്ന പ്രൈവറ്റ് വേരിയബിൾ ഈ ഫംഗ്ഷനിൽ എൻ‌ക്യാപ്സുലേറ്റ് ചെയ്തിരിക്കുന്നു
    let count = 0;

    // ഈ ഫംഗ്ഷൻ റിട്ടേൺ ചെയ്യപ്പെടുമ്പോൾ അതിന് 'count' വേരിയബിൾ എക്സസ്സുമുണ്ട്
    return {
        increment: function() {
            count++;
            console.log(count);
        },
        decrement: function() {
            count--;
            console.log(count);
        },
        getCount: function() {
            return count;
        }
    };
}

const myCounter = counter();

myCounter.increment(); // 1
myCounter.increment(); // 2
myCounter.decrement(); // 1
console.log(myCounter.getCount()); // 1
ഇത് എങ്ങനെ പ്രവർത്തിക്കുന്നു?
പ്രൈവറ്റ് സ്റ്റേറ്റ് (count): ഈ ഉദാഹരണത്തിൽ, count എന്ന വേരിയബിൾ പ്രൈവറ്റ് ആണ്, അത് counter() ഫംഗ്ഷനിൽ നിന്നു പുറത്തുകൂടി നേരിട്ട് പ്രവേശിക്കുക സാധ്യമല്ല. ഇത് ലെക്സിക്കൽ ക്ലോഷർ വഴി എൻ‌ക്യാപ്സുലേറ്റ് ചെയ്തിരിക്കുന്നു.

ലെക്സിക്കൽ ക്ലോഷർ വഴി എൻ‌ക്യാപ്‌സുലേഷൻ: count എന്ന വേരിയബിൾ പ്രൈവറ്റ് ആണെങ്കിലും, അതിന്റെ മൂല്യം മാറ്റാൻ നിങ്ങൾക്ക് increment, decrement, getCount എന്ന ഫംഗ്ഷനുകൾ ഉപയോഗിച്ച് മാത്രം അത് നിയന്ത്രിക്കാൻ സാധിക്കും. ഈ രീതിയിൽ, പുറത്തുനിന്നുള്ള പ്രോഗ്രാമുകൾക്ക് count അനുബന്ധമായ നിയന്ത്രണം നൽകുകയും, അതിന്റെ പ്രൈവറ്റ് നില (private state) സംരക്ഷിക്കുകയും ചെയ്യുന്നു.

ഇങ്ങനെ, എൻ‌ക്യാപ്സുലേഷൻ ഒബ്ജക്റ്റ് ഓറിയെന്റഡ് പ്രോഗ്രാമിംഗിൽ നിന്നു സ്വതന്ത്രമായി, ഫംഗ്ഷൻ അടിസ്ഥാനത്തിൽ, ലെക്സിക്കൽ ക്ലോഷർ ഉപയോഗിച്ച് നേടാമെന്ന് ഈ ഉദാഹരണം തെളിയിക്കുന്നു.

ഒബ്ജക്റ്റ് ഓറിയെന്റഡ് പ്രോഗ്രാമിംഗ് ഭാഷകളിലും മറ്റ് ബന്ധപ്പെട്ട മേഖലകളിലും, ഇൻഫർമേഷൻ ഹൈഡിംഗ് (information hiding) എന്നത് ഒരു പ്രത്യേക ആശയമായി കണക്കാക്കപ്പെടുന്നു. രണ്ടാമത്തെ നിർവചനം അനുസരിച്ച്, ക്ലാസുകളിലെ ഘടകങ്ങൾ (components) സ്വയമേവ മറച്ചുവെക്കപ്പെടുന്നില്ല, പകരം ഇത് പ്രോഗ്രാമർമാർക്ക് മാനുവലായി നിയന്ത്രിക്കാനാകും. ഉദാഹരണത്തിന്, പബ്ലിക് (public), പ്രൈവറ്റ് (private), പ്രൊട്ടക്റ്റഡ് (protected) എന്നീ ആക്സസ് മോഡിഫയറുകൾ ഉപയോഗിച്ച് ഡാറ്റയും മെത്തേഡുകളും എങ്ങനെ ആക്സസ് ചെയ്യപ്പെടുന്നുവെന്ന് നിയന്ത്രിക്കാം. ഇത് ഡാറ്റ സുരക്ഷിതമാക്കുകയും ഇംപ്ലിമെന്റേഷൻ വിശദാംശങ്ങൾ മറച്ചുവെക്കുകയും ചെയ്യുന്നു.

എൻക്യാപ്സുലേഷൻ ഡാറ്റയും പ്രവർത്തനങ്ങളും (ഫംഗ്ഷനുകളും) ക്ലാസുകളിൽ ഒത്തുചേർക്കുന്നു. ഒബ്ജക്ട് ഓറിയന്റഡ് ഭാഷകളിൽ ഇത് പിന്തുണയ്ക്കപ്പെടുന്നു, എങ്കിലും മറ്റ് മാർഗങ്ങളും നിലവിലുണ്ട്.

എൻക്യാപ്സുലേഷൻ എന്നത് ആവർത്തനപരമായ അല്ലെങ്കിൽ സങ്കീർണ്ണമായ പ്രക്രിയയെ ഒരു യൂണിറ്റായി ചിട്ടപ്പെടുത്തിയുള്ള പ്രവർത്തനമാണ്. ഓബ്ജക്ട് ഓറിയന്റഡ് പ്രോഗ്രാമിംഗ്(methods, classes) ഇതിനെ പിന്തുണയ്ക്കുന്നു, എന്നാൽ പ്രോസീജ്യുറൽ പ്രോഗ്രാമിങ്ങിലും ഈ നിർവചനം ബാധകമാണ്.

അവലംബം