Encapsulation (کپسولهسازی) در کلاسها
کپسولهسازی یکی از اصول پایهای برنامهنویسی شیگرا است که هدف آن پنهان کردن جزییات داخلی یک شیء و محافظت از دادهها در برابر دسترسی و تغییرات غیرمجاز است. به عبارت سادهتر، کپسولهسازی یعنی مخفی کردن اطلاعات داخلی کلاس و ارائه رابطی مشخص (مثلاً متدها) برای تعامل با آن.
چرا کپسولهسازی مهم است؟
- جلوگیری از تغییرات ناخواسته یا اشتباه در دادههای داخلی شیء
- افزایش امنیت و صحت دادهها
- کاهش وابستگی و پیچیدگی در برنامهنویسی
- امکان تغییر پیادهسازی داخلی بدون تاثیر بر کدهای بیرونی که از کلاس استفاده میکنند
انواع مدلهای کپسولهسازی در پایتون
در پایتون، سه سطح دسترسی به ویژگیها (attributes) وجود دارد که هر کدام برای کپسولهسازی و مخفی کردن دادهها کاربرد دارند:
- ویژگیهای عمومی (Public): ویژگیهایی که بدون زیرخط تعریف میشوند و از هر جایی قابل دسترسی و تغییر هستند.
self.attribute
مثال:self.name
- ویژگیهای محافظتشده (Protected): با یک زیرخط شروع میشوند
_attribute
و به صورت قراردادی برای استفاده داخلی کلاس و زیرکلاسها در نظر گرفته میشوند، اما از بیرون کلاس هم قابل دسترسی هستند. بیشتر برای هشدار به برنامهنویس که نباید مستقیم به آنها دسترسی داشت. - ویژگیهای خصوصی (Private): با دو زیرخط شروع میشوند
__attribute
و پایتون آنها را با مکانیزمی به نام name mangling به نام داخلی دیگری تبدیل میکند تا دسترسی مستقیم به آنها سختتر شود و عملاً خصوصی باشند. این ویژگیها فقط داخل کلاس قابل دسترسیاند.
مثال:
class Example:
public_attr = "I'm public"
_protected_attr = "I'm protected"
__private_attr = "I'm private"
obj = Example()
print(obj.public_attr) # خروجی: I'm public
print(obj._protected_attr) # خروجی: I'm protected (قابل دسترسی اما بهتر است دست نزنید)
# print(obj.__private_attr) # خطا: AttributeError
# دسترسی به private با name mangling ممکن است:
print(obj._Example__private_attr) # خروجی: I'm private
خلاصه اینکه، پایتون به صورت رسمی سطح دسترسی ندارد، ولی با این قواعد قراردادی و name mangling امکان کپسولهسازی و مخفیسازی دادهها فراهم میشود.
چگونه در پایتون کپسولهسازی انجام میشود؟
در پایتون، کپسولهسازی با استفاده از ویژگیهای خصوصی (private attributes) انجام میشود. برای خصوصی کردن یک ویژگی یا متد، نام آن را با یک یا دو زیرخط (_) شروع میکنیم:
_attribute
: خصوصیسازی محافظتشده (protected)، به صورت قراردادی برای استفاده داخلی کلاس و زیرکلاسها__attribute
: خصوصی واقعی (name mangling) که دسترسی مستقیم را سختتر میکند
مثال ساده کپسولهسازی
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # مقدار خصوصی
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def withdraw(self, amount):
if 0 <= amount <= self.__balance:
self.__balance -= amount
return amount
else:
print("Insufficient funds")
return 0
def get_balance(self):
return self.__balance
account = BankAccount("Ali", 1000)
account.deposit(500)
print(account.get_balance()) # خروجی: 1500
# دسترسی مستقیم به __balance غیرمستقیم است و خطا میدهد:
# print(account.__balance) # AttributeError
# اما به صورت name mangling قابل دسترسی است (اجتناب شود):
print(account._BankAccount__balance) # خروجی: 1500
کاربردهای کپسولهسازی
- مخفی کردن دادههای حساس (مانند پسورد، موجودی حساب و...)
- ایجاد کنترل بر روی نحوه دسترسی و تغییر دادهها از طریق متدهای کنترلشده
- ایجاد یک API ساده و قابل اطمینان برای کاربران کلاس بدون افشای جزئیات پیچیده داخلی
- جلوگیری از ایجاد خطا یا ناسازگاری دادهها به دلیل تغییرات مستقیم و بدون کنترل
در نتیجه، کپسولهسازی به مدیریت بهتر کد، امنیت بیشتر و نگهداری آسانتر برنامه کمک میکند.