کپسوله سازی در شی گرایی چیست؟ – توضیح به زبان ساده
یکی از مهمترین مفاهیمی که هنگام مطالعه مبحث شیگرایی در برنامهنویسی با آن رو به رو میشوید، کپسولهسازی است. دلیل مهم بودن کپسوله سازی در شی گرایی این است که رویکرد بسیار مناسب و قدرتمندی را برای ذخیرهسازی، پنهانسازی و کار با دادهها در اختیار برنامهنویس قرار میدهد. کپسولهسازی در واقع، امکان دسترسی مستقیم به برخی از قسمتهای یک شی را محدود میکند. در این مطلب از مجله فرادرس، سعی بر این است تا به زبانی ساده به شما بگوییم که کپسوله سازی در شی گرایی چیست و چه کاربردی دارد. همچنین نحوه پیادهسازی و استفاده از آن را نیز بیان میکنیم.
مبحث کپسولهسازی، در کدهایی که مینویسیم مزیتهای فراوانی دارد و میتواند کارایی، امنیت و کیفیت سیستم نرمافزاری را بهبود ببخشد. با کپسوله کردن کدهای خود میتوانیم امنیت آن را افزایش دهیم. به این دلیل که جلوی مواردی همچون دسترسیهای غیرمجاز، دستکاری و لورفتن دادهها را میگیرد. از آنجاییکه بهکارگیری کپسولهسازی میتواند پیچیدگیها و وابستگیهای بین دادهها را کاهش دهد، در نهایت کدهایی خواهید داشت که نگهداری از آنها سادهتر است و به راحتی میتوان کارکرد آنها را متوجه شد و مجدد و در جایی دیگر از برنامه بهکار برد. در این نوشتار، ضمن ارائه تعریفی ساده از مفهوم کپسولهسازی و بیان مثالهای متعدد و واقعی برای درک بهتر آن، مزایا، کاربردها و پیادهسازی این اصل از شیگرایی در پایتون و جاوا را نیز بیان کردهایم.
کپسوله سازی در شی گرایی چیست؟
کپسولهسازی، یکی از اصول برنامهنویسی شیگرا است که طبق آن، دادهها و متدها در قالب واحدهایی نظیر یک کلاس تجمیع شده و به بیان دیگر در یک بسته قرار میگیرند. بدینترتیب، از دسترسیهای غیر مجاز در امان میمانند.
درست مانند کپسولهای دارویی که محتوای آنها را نمیبینیم و مصرف میکنیم، در کپسولهسازی نیز متغیرهای دادهای و متدهای مربوط به آن، در یک مکان بسته و شبیه به کپسول قرار میگیرند. با انجام این کار، عملیات و فرایندهای درونی آن، پنهان شده و تنها مواردی که ضروری هستند قابل مشاهده خواهند بود.
با توجه به محدودیتهایی که «کپسولهسازی» (Encapsulation) در رابطه با دسترسی کاربران به دادهها ایجاد میکند، میتواند گزینه خوبی برای بهکارگیری در مدیریت دادهها و متدهای حساس و امن باشد.
چگونه برنامه نویسی شی گرا را با فرادرس یاد بگیریم؟
در صورتیکه قصد یادگیری مهارت جدیدی را داشته باشید یک از راههای پیش روی شما، استفاده از فیلمهای آموزشی است. با این روش میتوانید مهارت مورد نظر خود نظیر شیگرایی را از هر موقعیت مکانی که لازم باشد یاد بگیرید و در کنار آن، بهطور عملی تمرین کنید. همچنین در صورت نیاز میتوانید بارها و بارها مفاهیم گفته شده را مرور کنید. فرادرس به عنوان یکی از بزرگترین پلتفرمهای آموزشی کشور، فیلمهای آموزشی متعددی را با کیفیتی عالی و بهترین اساتید، در رابطه با اینکه برنامه نویسی شی گرا چیست، منتشر کرده است.
بهطور مثال، در مجموعه فیلمهای آموزش مقدماتی تا پیشرفته برنامهنویسی شیگرا از فرادرس، به فیلمهای آموزشی گوناگونی در رابطه با رویکرد برنامهنویسی OOP دسترسی خواهید داشت.
عناوین برخی از فیلمهای آموزشی موجود در این مجموعه آموزشی که شیگرایی را در زبانهای برنامهنویسی مختلف به شما یاد میدهند، در ادامه آوردهایم.
- فیلم آموزش برنامه نویسی شی گرا در پایتون Python از فرادرس، مفاهم OOP را بهصورت تئوری و عملی در زبان برنامهنویسی محبوب پایتون به شما یاد میدهد.
فیلم آموزش برنامهنویسی شیگرا با کاتلین از فرادرس، علاوه بر آموزش مفاهیم شیگرایی و نحوه استفاده از آن در Kotlin، پروژههای متعددی نظیر پروژه آگهی را با استفاده از وراٍثت پیادهسازی میکند. - فیلم آموزش شیگرایی در سیشارپ از فرادس، OOP را در زبان C# آموزش داده و مفهوم وراثت را با مثال عملی سیستم پرداخت حقوق به شما میآموزد.
- فیلم آموزش برنامهنویسی پیشرفته سیپلاسپلاس از فرادرس، شیگرایی در C++ را به سادهترین شیوه و همچنین بههمراه مثالهای متعدد آموزش میدهد.
- فیلم آموزش رایگان مبانی برنامهنویسی شیگرا در جاوا از فرادرس
برنامهنویسی شیگرا یکی از شیوههای کدنویسی و توسعه اپلیکیشنها محسوب میشود و روش قدرتمند و منعطفی را در این رابطه برای برنامهنویس فراهم میکند. توسعهدهندگان در این شیوه برنامهنویسی بهطور معمول، با کلاسها، اشیا، فیلدهای دادهای و متدها سر و کار دارند. از مزیتهای این نوع برنامهنویسی میتوان به نوشتن کدهای بهینه و قابل استفاده مجدد، کاهش مدتزمان توسعه و هزینههای تمام شده و غیره اشاره کرد. بهطور کلی، OOP را میتوان یکی از مهمترین مهارتهایی دانست که برای توسعه اپلیکیشنهای نوین و امروزی به آن نیاز پیدا میکنید و همچنین، جزو مواردی محسوب میشود که دارا بودن آن، شما را هنگام ورود به بازار کار، از سایرین متمایز میکند. OOP، چهار اصل مهم یعنی کپسولهسازی، وراثت، انتزاع و چندریختی یا پلیمورفیسم را در بر میگیرد. که نخستین مورد را در این نوشتار مورد بررسی قرار دادهایم.
درک کپسوله سازی در شی گرایی با بیان یک مثال از دنیای واقعی
اکنون، به عنوان تعریف رسمی کپسوله سازی در شی گرایی میدانیم که این مفهوم به تجمیع دادهها و متدهای مرتبط با آن در جایی مانند یک Class اشاره دارد تا از این طریق، ضمن محافظت از دادهها، ارتباطات آنها نیز سادهتر شود. در ادامه یک مثال از دنیای واقعی بیان میکنیم تا این مفهوم را بهتر درک کنید.
یک اتومبیل را در ذهن خود تجسم کنید. فارغ از برند و مدلی که برای آن در نظر گرفتهاید، این اتومبیل، مؤلفههای گوناگونی مانند رنگ بدنه، حداکثر سرعت، لاستیک، جعبه دنده، موتور و غیره را در بر میگیرد که در واقع، «خصوصیات کلاس اتومبیل» محسوب میشوند. این اتومبیل همچنین شامل قابلیتهایی مانند حرکت کردن، بوق زدن، هدایت شدن و غیره نیز میشود که این موارد را میتوانید بهعنوان «متدهای کلاس اتومبیل» در نظر بگیرید.
مفهوم کپسولهسازی و بستهبندی مؤلفهها - یا همان خصوصیات گوناگون کلاس اتومبیل بههمراه متدهای درگیر با آنها - در این مثال، به خوبی قابل مشاهده است. به بیان دیگر، هنگامیکه ما این اجزا را تجمیع یا گروهبندی میکنیم، عملیات و فرایندهای درونی اتومبیل از راننده آن انتزاع میشود. یعنی، شما بهعنوان راننده پشت فرمان مینشینید، استارت میزنید، حرکت و رانندگی میکنید. بدون اینکه از نحوه روشن شدن موتور، انتقال نیروی محرکه از موتور و گیربکس به شفتها، چرخها و سایر جزئیات فنی خودرو آگاه باشید. به بیان سادهتر، بهجای درگیر شدن با جزئیات پیچیده، روی موارد مهمتر و بهکارگیری قابلیتهای اصلی سیستم تمرکز میکنید.
شما خیلی راحت میتوانید از رابط یا اینترفیسی که از طریق متدهای کلاس اتومبیل فراهم شده، یعنی مواردی مانند «استارتزدن»، «حرکت کردن» و غیره استفاده کنید تا از این طریق به هدف خود دست پیدا کنید. این مورد که کاربر یا همان راننده مثال ما، برای رسیدن به هدف خود از اینترفیسها استفاده کند در واقع، بیانگر همان مفهوم انتزاع است. بدینترتیب میتوانیم بگوییم که کپسولهسازی و «انتزاع» (ابسترکت | Abstract) در تلاش هستند تا پیادهسازی یک کلاس و اینترفیس آن را بهطور شفافی از هم تفکیک کنند تا ضمن افزایش خوانایی کدها، نگهداری از آن نیز آسانتر شود.
هنگامیکه با دادههای حساس کار میکنید، برای جلوگیری از نشت این اطلاعات و کاهش احتمال دسترسیهای غیر مجاز و تغییرات ناخواسته دادهها میتوانید روی کپسولهسازی حساب کنید. با استفاده از کنترلگرهای دسترسی یا «Access Modifiers» که در پیادهسازی این مفهوم بهکار میروند، میتوانید حوزه دسترسی اینگونه دادهها را به شی اصلی محدود کنید تا سایر کلاسها و اشیا نتوانند دسترسی غیرمجاز داشته باشند و تهدیدی برای اطلاعات شما محسوب شوند.
بهعنوان مثالی دیگر، میتوانید یک حساب بانکی را در نظر بگیرید که در قالب یک Class، کدنویسی شده است. این کلاس، ممکن است فیلدهایی مانند «موجودی» و «شماره حساب» داشته باشد. برای اینکه کنترل کاملی روی تغییرات این فیلدها و نحوه اعتبارسنجی آنها داشته باشید میتوانید آنها را بهصورت private تعریف کرده و کپسوله کنید. همچنین برای انجام کارهای گوناگون مانند واریز به حساب، برداشت از حساب، بررسی باقیمانده موجودی حساب و غیره، متدهایی را میتوانید ایجاد کنید که به صورت عمومی قابل دسترس باشند. بدین ترتیب احتمال نفوذ و لو رفتن اطلاعات حساس کاهش مییابد.
در ادامه، کدهای کپسولهسازی در جاوا را آوردهایم.
1class BankAccount {
2 private double balance;
3 private String accountNumber;
4 public BankAccount(double balance, String accountNumber) {
5 this.balance = balance;
6 this.accountNumber = accountNumber;
7 }
8 public double getBalance() {
9 return balance;
10 }
11 public void deposit(double amount) {
12 balance += amount;
13 }
14 public void withdraw(double amount) {
15 balance -= amount;
16 }
17}
در این برنامه جاوا، مثال کپسوله سازی در شی گرایی در حساب بانکی را پیادهسازی کردهایم و در ادامه نیز، توضیحات مربوط به کدهای آن را آوردهایم.
- خطوط شماره ۱ تا ۱۷: این خطوط بدنه کلاس حساب بانکی یا BankAccount را نشان میدهند.
- خط شماره ۲: در این خط فیلد دادهای balance را تعریف کردهایم که موجودی حساب را نگه میدارد.
- خط شماره ۳: خصوصیت شماره حساب یا accountNumber را نیز در این خط تعریف کردهایم.
توجه داشته باشید که این ۲ داده بهصورت private تعریف شدهاند. یعنی، محدوده دسترسی آنها به خود این کلاس محدود شده است.
- خطوط شماره ۴ تا ۷: در این خطوط متد سازنده کلاس را تعریف کردهایم.
- خط شماره ۸: در این خط، متدgetBalance() را بهصورت عمومی یا public تعریف کردهایم. این متد موجودی حساب را بر میگرداند.
- خط شماره ۱۱: متد عمومی deposit() که واریز به حساب را با مقدار amount انجام میدهد را در این خط تعریف کردهایم. مقدار واریزی، به موجودی حساب افزوده میشود.
- خط شماره ۱۴: در این خط متد عمومی برداشت از حساب، یعنی withdraw را داریم که به میزان amount از موجودی حساب کسر میکند.
همانطور که مشاهده میشود، فیلدهای دادهای را در کلاس خود محصور کردهایم و از خارج شی، تنها میتوان با استفاده از متدهای عمومی، وظایف تعریف شده را انجام داد و با کلاس تعامل داشت.
اهمیت کپسوله سازی در شی گرایی چیست؟
کپسولهسازی نقش مهمی در برنامهنویسی شیگرا دارد و در ادامه به برخی از دلایل اهمیت آن در شیگرایی اشاره کردهایم.
محافظت از اطلاعات موجود
کپسولهسازی میتواند از اطلاعات موجود محافظت کند. این مفهوم شیگرایی میتواند از تغییرات ناخواسته دادهها و بروز خطاها جلوگیری کند. به بیان دیگر، هنگامی که اطلاعات را درون کپسول قرار داده و دسترسی به آن را با private محدود میکنید، احتمال اینکه دادهها بهطور غیرمجاز توسط کاربران تغییر کند، تا حد زیادی کاهش مییابد. زیرا با محدود کردن دادهها، تنها از طریق متدهای تعریف شده در همان کلاس میتوانید به دادهها دسترسی پیدا کرده و آنها را تغییر دهید. بهطور خلاصه، کپسوله سازی در شی گرایی به کاهش احتمال خرابی دادهها یا سالم ماندن دادهها کمک میکند.
مفید بودن هنگام کار با داده های حساس
کپسولهسازی در مواقعیکه با متدها یا دادههای حساس سر و کار داریم میتواند مفید باشد. دلیل آن این است که دسترسی توابع و کاربران به اطلاعات را مدیریت و محدود میکند. در نتیجه، بهخاطر شیوه مناسبی که برای ذخیره، پنهانسازی و مدیریت دادهها ارائه میدهد، مفهومی بسیار مهمی تلقی میشود.
محصور کردن و محافظت از داده ها
شیگرایی، یکی از پارادایمهای برنامهنویسی است که با اشیا و کلاسها سر و کار دارد. کپسولهسازی نیز یکی از اصول مهم آن محسوب میشود. در این سَبک از برنامهنویسی واحدهایی بهنام کلاس داریم که شامل دادهها و متدهای مرتبط با آن دادهها است و با استفاده از این کلاسها میتوانیم اشیا را ایجاد کنیم. به زبان سادهتر، اینکه یک شی شامل چه دادههایی است و چه اقداماتی را میتواند انجام دهد - یعنی همان ویژگیها و متدهای شی - بهوسیله کلاس تعیین میشود. مفهوم کپسولهسازی به محصور کردن دادهها و متدهای یک کلاس اشاره دارد تا از این طریق، از دادهها محافظت شود.
کپسولهسازی را میتوان بهشکل «بستهبندی دادهها در یکجا» تعریف کرد. در این مفهوم، توابع و دادههای مورد استفاده آنها با هم ادغام میشوند. همچنین میتوانید آن را یک سپر یا لایهای محافظ در نظر بگیرید که از دادهها در مقابل دسترسیهای غیرمجاز بیرونی محافظت میکند.
- دادهها و متغیرهایی که در یک کلاس تعریف میکنید، توسط سایر کلاسها قابل مشاهده نیستند و تنها اعضای و متدهایی میتوانند از این دادهها استفاده کنند که در همان کلاس تعریف شده باشند.
- کپسولهسازی را میتوان تلفیقی از پنهانسازی دادهها و انتزاع دانست. در این مفهوم دادههای کلاس و متدهای آن را با هدف اینکه از دید سایر کلاسها پنهان باشد، بهصورت private تعریف میکنیم. بدینترتیب، جزئیات پیادهسازی از کاربر پنهان مانده و تعاملات کاربر با آن از طریق اینترفیسهای عمومی انجام میشود.
- در صورتی که میخواهید کپسولهسازی را پیادهسازی کنید لازم است تا متغیرهای کلاس مورد نظر را به صورت private تعریف کنید. همچنین لازم است تا متدهایی را بهصورت عمومی تعریف کنید که عمل مقداردهی و بازیابی مقدار متغیرها را به شکلی صحیح انجام دهد.
- بهطور معمول از متدهای عمومی Setter و Getter در پیادهسازی آن استفاده میکنند.
مزایای کپسوله سازی در شی گرایی چیست؟
کپسوله سازی در شی گرایی مزیتهای متعددی را برای برنامهنویس در توسعه سیستمهای نرمافزاری بههمراه دارد که در ادامه، برخی از مهمترین آنها را بیان کردهایم.
- فراهم کردن امنیت بیشتر: کپسولهسازی، جزئیات داخلی اشیا را از عوامل بیرونی پنهان میکند. بدینترتیب، از دسترسیها و تغییرات غیرمجاز دادهها، جلوگیری بهعمل میآید.
- تطبیقپذیری آسان: با استفاده از کپسولهسازی میتوان کدها را با نگرانیهای کمتری در مورد بروز مشکلات سازگاری، تغییر داد یا اصلاح کرد. در نهایت کدهایمان به شکل بهتری توسعه خواهند یافت.
- انعطاف بیشتر: کپسولهسازی به شما امکان میدهد تا متغیرها را بهصورت فقط خواندنی یا فقط نوشتنی تعریف کنید و از این طریق، انعطاف بیشتری را در اختیار شما قرار میدهد. بهطور مثال، هنگامیکه میخواهید متغیرها بهصورت فقط نوشتنی باشند باید از اضافه کردن متدهای «Getter» نظیر getName() و getAge() پرهیز کنید.
- بهبود قابلیت استفاده دوباره از کدها: هنگامیکه از کپسولهسازی استفاده میکنید، امکان تغییر و هماهنگی کدهای برنامه با نیازهای جدید، راحتتر میشود. در برنامهنویسی شیگرا شما بهطور معمول میتوانید کلاسی را یکمرتبه تعریف کرده و اشیای آن را به دفعات در طول برنامه استفاده کنید. با ایجاد متدها یا اینترفیسهای عمومی مناسب برای اشیا که ساختار مناسب و قابلفهمی دارند، به سایر برنامهنویسان نیز امکان میدهید تا کارکرد و هدف آن آبجکت را بهخوبی متوجه شده و آن را در سایر برنامههای خود نیز بهکار ببرند.
- بهبود کارایی: کپسولهسازی به برنامهنویسان امکان میدهد تا وابستگیهای موجود بین مؤلفههای اپلیکیشن را کاهش دهند و از این طریق، باعث کاهش پیچیدگی سیستم میشود. این مورد میتواند تعداد نقاط مستعد خطا را کاهش داده و در مقابل، پایداری سیستم را بهبود بخشد.
- بهبود قابلیت نگهداری از کدهای اپلیکیشن: یکی از مزیتهای کپسولهسازی این است که نگهداری از کدهای برنامه و همچنین انجام بهروزرسانیها را برایتان راحتتر میکند. به این دلیل که، میتوانید کدها را بهطور مستقل و مجزا و بدون تداخل با کلاسهای دیگر تغییر دهید.
- پنهانسازی دادهها و امنیت اطلاعات: شما میتوانید دادهها و متدهای آبجکت را بهصورت خصوصی تعریف کرده و از این طریق، وضعیت داخلی شی را از دسترسیهای غیر مجاز حفظ کنید. کپسولهسازی در اینجا به شما اطمینان میدهد که اشیا بهصورت قابل پیشبینی و مجاز مورد استفاده قرار میگیرند. بدینترتیب، امنیت دادههای شی بیشتر شده و به روش غیر مجاز قابل دسترسی یا تغییر نخواهند بود. با استفاده از کپسوله سازی در شی گرایی، نحوه ذخیرهسازی و پیادهسازی کلاسها و بهطور کلی جزئیات داخلی کلاس از کاربر پنهان میشود و آنها تنها از ارسال مقادیر و مقدارهی اولیه آن مطلع هستند.
- افزایش خوانایی کدهای اپلیکیشن: با استفاده از کپسولهسازی، دادهها و متدها در یک کلاس محصور میشوند. این مورد باعث میشود تا خوانایی و درک عملکرد کدها افزایش یابد و بتوانید خیلی سادهتر با آن کار کنید. همچنین، امکان دیباگ و «تست واحد» (Unit Test) کدهای برنامه آسانتر میشود.
- باز بودن دست برنامهنویس برای پیادهسازی جزئیات سیستم: اگر بخواهیم به یکی از مهمترین مزیتهای مفهوم کپسولهسازی برای برنامهنویسان اشاره کنیم، آزادی و انعطافی است که برای توسعه جزئیات سیستم در اختیار او قرار میگیرد. بهعبارت دیگر، دست شما برای توسعه سیستم باز است اما باید حواستان باشد تا اینترفیسی که توسط کاربران قابل مشاهده و دسترسی است، حفظ شود.
معایب کپسوله سازی
علیرغم تمام مزیتها، کپسولهسازی میتواند دارای معایبی نیز باشد که در زیر، به برخی از آنها اشاره کردهایم.
- اگر به درستی از آن استفاده نکنید ممکن است سیستم را پیچیدهتر کند.
- ممکن است باعث سختتر شدن فهمیدن نحوه کارکرد سیستم شود.
- در برخی مواقع میتواند انعطاف در پیادهسازی را کاهش دهد.
اجرای کپسوله سازی در شی گرایی چگونه است؟
زبانهای برنامهنویسی شیگرا، بهوسیله کلمات کلیدی مخصوصی که Access Modifier نامیده میشوند، دسترسیپذیری کلاسها، متدها و سایر اعضای دادهای را مشخص میکنند. در واقع، این کنترلگرهای دسترسی، شما را در پیادهسازی مفهوم کپسولهسازی یاری میدهند.
برای کدنویسی کپسوله سازی در شی گرایی از Access Modifier-هایی مانند public ، private و protected استفاده میشود تا بهکمک آنها بتوانیم محدوده دسترسی دادهها و متدها در کلاس را تعیین کنیم.
بهطور خلاصه، دادهها و متدهایی که بهصورت public تعریف شوند توسط سایر اشیا و از هر جایی قابل دسترس هستند. دسترسی به اعضای تعریف شده بهصورت private، در حد همان کلاس اصلی است و در صورتی که اعضای دادهای بهصورت protected تعریف شوند، افزون بر کلاس خود، در کلاسهای فرزند آن کلاس نیز قابل دسترسی و استفاده هستند.
نحوه پنهان سازی اطلاعات با کپسوله سازی در شی گرایی چگونه است؟
برنامهنویسی شیگرا، چندین «کنترلگر دسترسی» (Access Modifier) در اختیار شما قرار میدهد تا بهکمک آنها، «قابلیت دیده شدن» (Visibility) و «دسترسیپذیری» (Accessibility) دادههای کلاس را مدیریت کرده و همچنین اطلاعات مهم را از دید کاربر پنهان کنید. بهعنوان یک برنامهنویس، برای اینکه بتوانید اینترفیسهای عمومی و غیر عمومی یک شی را از هم تفکیک کنید لازم است تا از این کنترلگرهای دسترسی کمک بگیرید.
در برنامهنویسی شیگرا بهطور کلی، چهار نوع از Access Modifier-ها را در اختیار داریم که عناوین آنها را در ادامه فهرست کردهایم.
- «عمومی» (Public)
- «خصوصی» (Private)
- «محافظت شده» (Protected)
- «پیشفرض» (Default)
بهکمک این Access Modifier-ها میتوانید دامنه مؤلفههایی همچون کلاس، اعضای دادهای، متد سازنده، متغیرها و متدها را محدود کنید. بدینترتیب و با محدودیتهایی که روی دادههای کلاس ایجاد میکنید، توابع خارج از کلاس نمیتوانند بهطور مستقیم به آنها دسترسی داشته باشند.
در ادامه، هر یک از این کنترلگرهای دسترسی را توضیح دادهایم.
کنترلگر دسترسی Public
در صورتیکه از Access Modifier عمومی یا Public استفاده کنید، دادههای کلاس شما بهصورت عمومی قابل دسترس خواهند بود. به بیان سادهتر، اشیا کلاسهای دیگر در صورت لزوم میتوانند به اعضای کلاس شما شامل کلاسها، متدها و دادهها، که بهصورت Public تعریف شدهاند، دسترسی پیدا کنند. در واقع میتوانیم بگوییم که محدوده دسترسی به اعضای Public کلاس بسیار گسترده است. بهطوریکه از بخشهای گوناگون برنامه هم میتوانید به آنها دسترسی داشته باشید.
کنترلگر دسترسی Private
اگر از Access Modifier خصوصی یا Private برای اعلان اعضای کلاس خود استفاده کنید، آنگاه این اعضا تنها درون همان کلاس و توسط متدهای داخلی کلاس قابل دسترسی خواهند بود و اشیا دیگر کلاسها و توابع بیرونی نمیتوانند به این نوع اعضا دسترسی مستقیم داشته باشند.
کنترلگر دسترسی Protected
این Access Modifier هم مانند کنترلگر دسترسی Private است. با این فرق که علاوه بر خود کلاس، زیرکلاسهای مشتق شده از آن نیز میتوانند به اعضای آن دسترسی داشته باشند. البته، این نوع دسترسی به عناصر کلاس والد در کلاسهای فرزند، میتواند به نوع وراثت بستگی داشته باشد.
کنترلگر دسترسی Default
Access Modifier پیشفرض یا Default زمانی به کلاس، اعضای دادهای یا متدهای شما نسبت داده میشود که هیچ کنترلگر دسترسی دیگری را برای آنها انتخاب نکنید. حوزه دسترسی در این Access Modifier تنها همان بسته را شامل میشود. یعنی، تنها کلاسهای موجود در بسته فعلی میتوانند به این نوع مؤلفههای Default دسترسی داشته باشند و آنها را بهکار بگیرند.
جدول دسترسی پذیری
تا اینجا، با Access Modifier-ها آشنا شدهاید. در ادامه تصویری را آوردهایم که دسترسیپذیری به متدها و دادهها را با انواع این کنترلگرها نشان میدهد.
بهطور مثال، متد تعریف شده بهصورت private، تنها در همان کلاس خود قابل دسترسی و استفاده است.
نحوه تست کدهای کپسوله سازی در شی گرایی چگونه است؟
برای آزمودن یا تست کدهای کپسولهسازی، لازم است تا کارایی و دسترسیپذیری متدها و دادهها را با توجه به Access Modifier تعیین شده برای آنها بررسی کنید. برای این کار بهطور معمول از فریمورکهای یونیتتست نظیر JUnit ،NUnit یا PyTest استفاده میشود. با کمک این ابزارها میتوان Test Case-های مربوطه را نوشته و خروجی و عملکرد اشیا و کلاسها را ارزیابی کرد. در ادامه، مثالی از تست کلاس BankAccount در جاوا با فریمورک JUnit را بیان کردهایم.
1import org.junit.Test;
2import static org.junit.Assert.*;
3public class BankAccountTest {
4 @Test
5 public void testConstructor() {
6 BankAccount account = new BankAccount(1000.0, "123456789");
7 assertEquals(1000.0, account.getBalance(), 0.01);
8 }
9 @Test
10 public void testDeposit() {
11 BankAccount account = new BankAccount(1000.0, "123456789");
12 account.deposit(500.0);
13 assertEquals(1500.0, account.getBalance(), 0.01);
14 }
15 @Test
16 public void testWithdraw() {
17 BankAccount account = new BankAccount(1000.0, "123456789");
18 account.withdraw(300.0);
19 assertEquals(700.0, account.getBalance(), 0.01);
20 }
21}
در این برنامه جاوا، کلاس BankAccount که نمونهای از کپسوله سازی در شی گرایی است را تست کردهایم. در ادامه نیز، کدهای آن را توضیح میدهیم.
- خطوط شماره ۱ تا ۲: موارد لازم برای استفاده از کتابخانه JUnit برای تست برنامه را وارد کردهایم.
- خط شماره ۳: در این خط، کلاس BankAccountTest را تعریف کردهایم که برای بررسی عملکرد BankAccount بهکار میرود.
- خط شماره ۵: یک متد برای تست سازنده عمومی کلاس BankAccount بهنام testConstructor() تعریف کردهایم.
- خط شماره ۶: یک شی از کلاس BankAccount بهنام account و با پارامترهای مشخص، ساختهایم.
- خط شماره ۷: در این خط با استفاده از متد assertEquals، عملکرد متد موجودی حساب یعنی account.getBalance() را تست کردهایم.
در اینجا لازم است تا مواردی را در نظر داشته باشید.
- همانطور که میدانید فیلدهایی را در کلاس خود بهصورت private یا خصوصی تعریف کردهایم. در صورتی که دسترسی مستقیم به این فیلدها صورت بگیرد، با خطای کامپایل رو به رو خواهید شد. یعنی اجرای account.balance; یا account.accountNumber; باعث میشود تا با خطای زمان کامپایل مواجه شویم.
- پارامتر سوم متد assertEquals()، تلرانس یا میزان اختلاف قابل قبل بین مقدار واقعی و مقداری که برگردانده میشود را مشخص میکند.
- در صورتی که از هر کدام از این تستکیسها با موفقیت عبور نکنیم، یعنی برنامه ما در آنجا عملکرد صحیحی ندارد و لازم تا آن را بازبینی کنیم.
در ادامه کدها، متدهای عمومی را تست میکنیم.
- خطوط شماره ۱۰ تا ۱۲: در این خط، یک متد بهنام testDeposit() برای تست عملکرد متد واریز به حساب یا deposit() از کلاس BankAccountتعریف کردهایم. در داخل آن، نمونهای جدید میسازیم و سپس، مبلغی را به حساب واریز میکنیم.
- خط شماره ۱۳: در این خط با متد assertEquals()، موجودی حساب را با مقدار جدیدی که باید داشته باشد، بررسی میکنیم.
- خط شماره ۱۶: در این خط بهعنوان یک تستکیس دیگر و با تعریف متد testWithdraw()، عملکرد برداشت از حساب را تست کردهایم. به این صورت که با متد withdraw() مبلغی را از حساب بر میداریم و سپس با متد assertEquals() مقدار باقیمانده یا همان موجودی حساب را با مقدار پیشبینی شده پس از برداشت مقایسه میکنیم.
طراحی ساختار کپسوله سازی در کدنویسی چگونه است؟
در ادامه، موارد گوناگونی که در طراحی مفهوم کپسولهسازی در کد رعایت میشود را بیان کردهایم.
- برای اینکه بتوان ساختار کپسولهسازی در شی گرایی را در کدهای خود ایجاد کرد، لازم است تا از روشهای موجود، با هدف رسیدن به «همبستگی بالا» (High Cohesion) و «وابستگی کم» (Low Coupling) استفاده شود. این خصوصیات باعث میشوند تا کدهایتان خواناتر باشند و بتوان آنها را بهسادگی تغییر داد یا دوباره استفاده کرد. منظور از Cohesion در اینجا، هماهنگی و ارتباط نزدیکی است که بین مؤلفههای شی یا کلاس با هدفی مشترک، وجود دارد. Coupling یا اتصال نیز مقدار وابستگی اشیا و کلاسها را بیان میکند و همچنین میزان اثرگذاری و تعاملاتی که بین آنها وجود دارد.
- یکی از کارهایی که هنگام طراحی ساختار کپسولهسازی میبایست انجام دهید، شناسایی و دستهبندی مناسب و منطقی خصوصیات و متدهای مربوط به هر شی یا کلاس است.
- در این ساختار، Access Modifier عمومی یا public را برای دادهها و متدهایی بهکار ببرید که توسط سایر اشیا مورد نیاز هستند و تعاملها از طریق آنها صورت میگیرد. همچنین، Access Modifier-های private یا protected را برای اعضای دادهای و متدهایی استفاده کنید که فقط در خود شی، مورد نیاز هستند.
- اگر دادههایی دارید که میبایست توسط سایر کلاسها یا اشیا قابل دسترسی یا تغییر باشند، متدهای Getter و Setter را برای این منظور بنویسید. مواردی مانند مدیریت خطاها و اعتبارسنجی نیز میبایست از طریق انجام شوند.
- از کپسولهسازی و انتزاع استفاده کنید و ساختارها و جزئیات پیادهسازی را در پشت اینترفیسی ساده پنهان کنید.
کپسوله سازی در پایتون
پایتون بر خلاف زبانهای شیگرا نظیر C++ و جاوا، Access Modifier-های گفته شده را ندارد و برای این منظور از قراردادهای موجود استفاده میشود.
کنترل گرهای دسترسی در پایتون
در ادامه، نحوه تعریف Access Modifier مختلف در پایتون با قراردادهای موجود را آوردهایم.
- «عمومی» (Public): در حالت عادی تمامی خصوصیات و متدهای یک کلاس، بهصورت عمومی در نظر گرفته میشوند. اگر عضو کلاس خود را بهصورت عمومی تعریف کنیم - یعنی تعریف عادی و پیشفرض - از هر جای برنامه میتوان به آن دسترسی داشت.
- «محافظت شده» (Protected): برای تعیین یک خصوصیت بهصورت protected میبایست پیشوند _ یا زیرخط را به ابتدای نام آن اضافه کنیم. اگر عضو کلاس خود را به این صورت تعریف کنیم، علاوه بر خود آن کلاس، در کلاسهای فرزند آن نیز قابل دسترسی است.
- «خصوصی» (Private): برای اینکه دادههای یک کلاس را بهصورت خصوصی تعریف کنیم، پیشوند__ یا ۲ زیرخط را به ابتدای نام آن اضافه میکنیم. اعضای کلاسی که به این شکل تعریف میشوند، تنها در همان کلاس قابل دسترسی و استفاده هستند.
نمونه کد کپسوله سازی در پایتون
کدهای زیر، کپسولهسازی در پایتون را نشان میدهند.
1class Tree:
2 def __init__(self, height):
3 self.__height = height
4
5 def get_height(self):
6 return self.__height
7
8 def set_height(self, new_height):
9 if not isinstance(new_height, int):
10 raise TypeError("Tree height must be an integer")
11 if 0 < new_height <= 40:
12 self.__height = new_height
13 else:
14 raise ValueError("Invalid height for a pine tree")
15
16
17pine = Tree(20)
18pine.get_height()
برای تعیین متدها و متغیرها بهصورت private، از ۲ علامت زیرخط یا __ بهعنوان پیشوند نام عضو مورد نظر استفاده میکنیم. توجه داشته باشید که در این حالت، عضو مورد نظر از کاربر پنهان میشود. اکنون میتوانیم با تعریف متدهای عمومی Getter و Setter امکان تعامل با این کلاس و بازیابی و تغییر مقدار height را برای کاربر فراهم کنیم.
در یکی از مطالب پیشین مجله فرادرس، کپسولهسازی در پایتون را بههمراه مثال و کد و به زبان ساده توضیح دادهایم.
- برای تمرین بیشتر شیگرایی در پایتون میتوانید فیلم آموزش پروژهمحور شیگرایی در پایتون بههمراه هفت پروژه کاربردی از فرادرس که لینک آن در ادامه آورده شده است را مشاهده کنید.
این فیلم آموزشی، ابتدا مفاهیم پایهای پایتون را به شما یاد میدهد و پس از آن ۷ پروژه کاربردی در حوزه شیگرایی شامل پروژه محاسبه درجه هوا، پروژه منوی رستوران، پروژه کتابخانه، پروژه انسان در محیطهای مختلف، پروژه ثبتنام در مدرسه و پروژه انبارداری را مورد بررسی قرار میدهد.
- همچنین، میتوانید فیلم آموزش رایگان آشنایی با مفاهیم اولیه شی گرایی در پایتون از فرادرس که لینک آن در ادامه آورده شده است را مشاهده کنید.
کپسوله سازی در جاوا
کپسولهسازی، یکی از مفاهیم مهمی است که هنگام برنامهنویسی شیگرا در زبان برنامهنویسی جاوا به آن بر میخورید. در این مفهوم، دادهها و متدهای مربوط به آن را درون واحدهایی مانند یک Class جاوا، محصور میکنید تا از این طریق، از مزیتهای کپسوله سازی در شی گرایی بهرهمند شوید. هنگامیکه در جاوا، دادههای خود را بهشکل گفته شده درون کپسول قرار میدهید، جزئیات پیادهسازی کلاس دیگر از بیرون آن مشخص و قابل دسترس نیست و تنها از طریق یک رابط یا اینترفیس عمومی میتوان با کلاس تعامل داشت.
برای پیادهسازی مفهوم کپسولهسازی در زبان جاوا کنید لازم است تا «متغیرهای نمونه» (Instance Variables) را بهصورت خصوصی یا همان private تعریف کنید. همانطور که پیشتر نیز گفتیم، دادههایی که به این شکل تعریف میشوند، تنها از داخل کلاس قابل دسترسی خواهند بود. اکنون برای اینکه امکان دسترسی به متغیرهای نمونه از بیرون کلاس فراهم شود. متدهای عمومی یا public آورده شده در ادامه را میبایست تعریف کنید تا امکان خواندن و ویرایش مقادیر متغیرهای نمونه از طریق آنها انجام شود.
- «سِتِر» یا Setter: برای دستکاری یا «تغییر مقادیر» استفاده میشود.
- «گِتِر» یا Getter: برای «بازیابی مقادیر» بهکار میرود.
مزیت استفاده از این متدها برای تعامل با اشیا این است که کلاس شما میتواند قوانینی که برای اعتبارسنجی دادهها پیشبینی کرده را اجرا کند و وضعیت داخلی خود را از تغییرات ناخواسته حفظ کند.
پیاده سازی کپسوله سازی در جاوا
در این قسمت، کدهای مربوط به مثال کپسولهسازی در زبان جاوا را بیان کردهایم.
1class Person {
2 private String name;
3 private int age;
4 public String getName() { return name; }
5 public void setName(String name) { this.name = name; }
6 public int getAge() { return age; }
7 public void setAge(int age) { this.age = age; }
8}
9
10public class Main {
11 public static void main(String[] args)
12 {
13 Person person = new Person();
14 person.setName("John");
15 person.setAge(30);
16
17 System.out.println("Name: " + person.getName());
18 System.out.println("Age: " + person.getAge());
19 }
20}
این برنامه، پس از اجرا میبایست خروجی زیر را چاپ کند. یان خروجی شامل «نام» و «سن» شخص است.
Name: John Age: 30
در این برنامه جاوا، کپسوله سازی در شی گرایی را پیادهسازی کردهایم و در ادامه نیز، راهنمای کدهای آن را آوردهایم.
- خطوط شماره ۱ تا ۱۲: این خطوط بدنه کلاس Person را نشان میدهند.
- خط شماره ۲: در این خط، متغیر رشتهای «نام» (name ) را تعریف کردهایم.
- خط شماره ۳: متغیر عددی «سن» (age ) را در این خط تعریف کردهایم.
این ۲ متغیر در واقع، درون کلاس محصور شدهاند و تعریف آنها بهصورت خصوصی private باعث میشود تا بهطور مستقیم از بیرون کلاس قابل دسترسی نباشند.
- خط شماره ۴: متد getName() را در این خط تعریف کردهایم. این متد، یک متد Getter محسوب شده و مقدار name را بر میگرداند.
- خط شماره ۵: در این خط، اعلان متد setName(String name) را آوردهایم. این متد یک متد Setter بهشمار میرود و مقدار name را با توجه به ورودی، تغییر میدهد.
- خط شماره ۶:در این خط، متد getAge() را تعریف کردهایم. این متد یک متد Getter محسوب شده و مقدار age را بر میگرداند.
- خط شماره ۷: در این خط، اعلان متد setAge(int age) را آوردهایم. این متد بهاصطلاح، یک متد Setter بهشمار میرود و مقدار age را با توجه به ورودی، اصلاح میکند.
- خطوط شماره ۱۰ تا ۲۰: این خطوط، بدنه کلاس اصلی Main را نشان میدهند
- خط شماره ۱۳: در این خط، یک نمونه یا شی جدید از کلاس Person ساخته شده که آن را درون person قرار دادهایم.
- خط شماره ۱۴: از طریق نخستین متد Setter یعنی setName("John") مقدار رشتهای John را به name اختصاص دادهایم.
- خط شماره ۱۵: دوباره با متد Setter دوم یعنی setAge(30) مقدار عددی 30 را به age اختصاص دادهایم.
- خط شماره ۱۷: مقدار نام یا name را با متد Getter مربوطه یعنی getName() را دریافت کرده و با فرمت مشخص شده چاپ میکند.
- خط شماره ۱۸: در این خط، مقدار نامage را با متد Getter آن یعنی getAge() گرفته و با فرمت مشخص شده چاپ میکند.
بدینترتیب، دسترسی به دادههای کلاس ما از طریق متدهای عمومی مربوطه انجام میشود و نگرانیهای مربوط به ایجاد ناسازگاری در دادهها کاهش پیدا میکند.
فرق بین انتزاع و کپسوله سازی در شی گرایی چیست؟
برخی از تفاوتهای میان انتزاع و کپسوله سازی در شی گرایی را در زیر، آوردهایم.
- کپسولهسازی فرایندی است که طبق آن، دادهها و متدها در محلی مانند یک کلاس، کپسوله یا محصور میشوند. سپس این کلاس در اختیار کاربر قرار میگیرد تا با استفاده از اینترفیسهای عمومی با آن تعامل داشته باشد. انتزاع، بهدنبال پنهانسازی جزئیات داخلی سیستم است. یعنی آن را بهشکل سادهتری توصیف میکند.
- پنهانسازی دادهها یکی از مهمترین خصوصیات کپسولهسازی است و برای این کار از Access Modifier-ها استفاده میکند. انتزاع باعث کاهش پیچیدگی، بهبود قابلیت نگهداری وتفکیک اینترفیس و پیادهسازی آن میشود.
- دادهها و متدها در کپسولهسازی در مکانی واحد تجمیع میشوند تا از خطرات احتمالی ناشی از دسترسیهای غیرمجاز مصون بمانند. در انتزاع، دادههای غیرضروری پنهان میشوند.
- برای پیادهسازی کپسولهسازی از Access Modifier-هایی مانند private ،protected و public استفاده میشود. برای پیادهسازی انتزاع از رابطها و کلاسهای انتزاعی استفاده میشود.
- دادهها در کپسولهسازی به کمک مدهای Getter و Setter پنهان میشوند. در انتزاع، جزئیات و پیچیدگیهای مربوط به پیادهسازی توسط اینترفیسها و کلاسهای انتزاعی مخفی میشود.
- در کپسولهسازی، با پنهان شدن دادهها رو به رو هستیم و نمیتوان بهطور مستقیم به آنها دسترسی داشته باشد. در انتزاع، به بخش خاصی از دادهها - و نه تمام دادهها با جزئیات آن - دسترسی داریم.
- «بانک»، مثال خوبی از کپسولهسازی است. اطلاعات مهم و ضروری از چشم مشتری پنهان است و تنها میتوان از طریق روشهای فراهم شده (متدهای عمومی Getter و Setter) از امکانات آن استفاده کرد. «اتومبیل» را میتوان مثالی از انتزاع دانست. راننده اتومبیل نیازی به دانستن نحوه کار موتور، گیربکس و دیگر جزئیات فنی ندارد و کافی است تا نحوه هدایت آن با رابط های فراهم شده مانند فرمان، پدالها و غیره را بداند.
مثال هایی از کپسوله سازی در دنیای واقعی
برای درک بهتر کپسولهسازی میتوان از مثالهای واقعی استفاده کرد که در ابتدای این نوشتار نیز به برخی از آنها اشاره کردهایم.
سیستم نسخه نویسی پزشکی
در بسیاری از مراکز درمانی که به سیستم نسخهدهی آنلاین مجهز شدهاند، پزشک پس از معاینه، بررسی وضعیت سلامتی و گرفتن شرح حال شما، داروهای لازم را به منظور درمان شما در برنامه موجود روی سیستم کامپیوتری خود وارد میکند. در اینجا، شما به سیستم پزشک دسترسی ندارید نمیتوانید خودتان نوع داروها، مقدار آنها و دوز ثبت شده را تغییر دهید. به بیان دیگر سیستم نسخهنویسی پزشک کپسولهسازی شده است و نمیتوانید دسترسی غیرمجاز به آن داشته باشید. همچنین، میتوان به این شکل گفت که برای محافظت از بیماران، تنها از طریق اینترفیس عمومی یا همان پزشک میتوانید به این سیستم دسترسی داشته باشید.
سیستم های بانکی
سیستمهای بانکی را میتوان مثال دیگری از کپسولهسازی در نظر گرفت. فرض کنید که قصد انجام یک تراکنش بانکی را دارید و برای این کار از اپلیکشن موبایلی بانک خود استفاده میکنید. با اینکار شما میتوانید از موجودی حساب خود مطلع شده و از امکانات متعدد آن مثل انتقال وجه و غیره استفاده کنید. اما در مقابل، اجازه ندارید که به جزئیات مهم تراکنشها، الگوریتمهای استفاده شده، اطلاعات حساس حسابها و غیره دسترسی پیدا کنید یا آنها را تغییر دهید. به زبان ساده، با استفاده از اینترفیسهایی مانند اپلیکشن موبایلی و غیره که این سیستم بانکی برای شما فراهم کرده میتوانید از امکانات مجاز و تعریف شده بهرهمند شوید. اما به دلیل محصور شدن اطلاعات حساس با هدف حفظ ایمنی سیستمهای بانکی، اجازه دسترسی به اطلاعات حساب دیگران، الگوریتمهای امنیتی، دستکاری موجود حساب خود و غیره را ندارید.
سیستم سفارشدهی غذا در رستوارن
فرض کنید برای صرف غذا به رستوران مراجعه کردهاید. به عنوان مشتری بهطور معمول، سفارش غذای خود را به گارسون میدهید. یا در موارد مدرنتر از اپلیکیشن مربوطه برای سفارش غذای خود استفاده میکنید. در این هنگام شما نیازی به مراجعه مستقیم به آشپزخانه رستوران، اینکه آیا موارد سفارش داده شده موجود هستند یا خیر و غیره ندارید. زیرا این قسمتها با هدف ارائه خدمات بینقص و کسب رضایت مشتری و مدیریت بهتر منابع، توسط رستوران کپسوله شدهاند و اقداماتی مانند مدیریت سفارشهای گرفتهشده، مدیریت موجودی اقلام، تنظیم صورتحسابها و غیره بهصورت بهینه در پشت صحنه آن اتفاق میافتند.
سیستم هوشمند سازی منازل
خانههای مدرن و هوشمند را تصور کنید. فرد وارد خانه میشود و از طریق تبلت خود و اپلیکیشن آن از دمای محیط منزل، میزان رطوبت، دوربینهای امنیتی و غیره مطلع شده و کارهای مختلفی مانند روشن کردن سیستمهای سرمایشی و گرمایشی، کنترل سیستم روشنایی و بسیاری موارد دیگر را انجام میدهد. اما این فرد بهطور مستقیم به پروتکلهای ارتباطی، الگوریتم سیستم و بهطور کلی جزئیات فنی و غیرضروری دسترسی ندارد. به زبان ساده، کاربر از طریق اپلیکیشنی ساده و کاربردی، خیلی راحت از امکانات موجود استفاده میکند. بهطور مثال، لامپی را روشن میکند. در اینجا، جزئیات پیچیده - مانند ارسال فرمان روشن کردن چراغ به سیستم کنترلکننده، فعالسازی رِله و غیره - کپسوله شده است. کپسولهسازی در اینجا تجربه کاربری را بهبود داده و استفاده از سیستم را برای کاربر ساده میسازد.
تقویت مهارت برنامه نویسی شی گرا با فرادرس چگونه است؟
برای تمرین عملی و تقویت مهارتهای خود در زمینه برنامهنویسی شیگرا میتوانید فیلمهای آموزشی فرادرس را مشاهده کنید که لینک آنها را در ادامه، آوردهایم.
- فیلم آموزش پروژهمحور شیگرایی در سیپلاسپلاس و سامانه امور دانشجویی از فرادرس
- فیلم آموزش رفع انواع خطاهای برنامنویسی شیگرایی در متاتریدر از فرادرس
جمعبندی
در این مطلب از مجله فرادرس در رابطه با کپسوله سازی در شی گرایی صحبت کردیم که در واقع یکی از مفاهیم مهم مبحث برنامهنویسی شیگرا محسوب میشود.
کپسولهسازی به زبان ساده، به محصور کردن دادهها و متدهای مرتبط با آن در واحدهایی مانند یک Class اشاره دارد. این مفهوم مزیتهای زیادی را در اختیار برنامهنویس قرار میدهد. بهطور مثال، از دسترسیهای غیر مجاز به دادهها، نشت اطلاعات حساس و تغییر ناخواسته آنها جلوگیری کرده و به بیان دیگر امنیت دادهها را برایتان فراهم میکند.
کپسولهسازی باعث میشود تا دادهها و متدهای شما یکپارچه و بدون خطا باشند تا از این طریق کدهای پایدارتری داشته باشید. کپسولهسازی همچنین به دنبال ماژولار کردن و مقیاسپذیری کدهای شما است. یعنی قطعه کدهایی را بهوجود میآورد که میتوانند در جاهای مختلف برنامه مجدد استفاده شوند.