ايه الفرق بين ال encapsulation & abstraction
وكيف اطبقهم فى الكود بتاعى
طيب، كما تعرفي الـ Abstraction & encapsulation هي أثنتين من أهم مفاهيم الـ Object-oriented programming - OOP.
في الحياة الواقعية:
بشكل عام خليني في البدأية أشرح لك كيف أنك تواجهي هذين المفهومين في حياتك الواقعية بشكل دوري.
لنقول أنك رحتي لمطعم KFC
لما يجيبوا لك الـ Menu بتكون بالشكل التالي:
وبتختاري الوجبة غالباً إعتماداً على صورتها ومكونها الرئيسي فقط.
و من المستحيل أنه توصلك الـ Menu ومكتوب فيها تفاصيل بالشكل التالي:
لماذا؟
لأن هذه التفاصيل لا تهمك ولا تقوم إلا بتعقيد الأمور فقط لا غير بدلاً من تبسيطها. فأنت كل ما يهمك هو أن تختاري إسم الوجبة ومن ثم تأتي الوجبة وتأكليها بدون أي داعي لأن تعرفي كيف تم تحضيرها وما خلافة.
هذا ببساطة ما يسمى بالـ Abstraction
حيث يتم فية إخفاء التفاصيل الغير مهمة وإظهار التفاصيل الأساسية حيث أنك تقومي بتقديم input (الطلب) وتتوقعي حصولك على output (الوجبة) ولا يهمك ما يحصل بين هاتين العمليتين من تفاصيل.
في الجانب الأخر عندنا المطبخ، فالمطبخ نستطيع أن نقول بأنه هو الوحدة التي تقوم بعمل إحتوى وتجميع لكل هذه المكونات والعناصر التي تدخل في هذه العملية والتي قد تتضمن أيضاً مكونات سرية لا يستطيع أحد الوصول إليها والتلاعب بها بدون أي قيود.
ببساطة نستطيع نقول بأن المطبخ هو الـ Encapsulation.
في الحقيقة يرتبك الكثير بخصوص هذين المفهومين لترابطهما بحيث نستطيع القول بأن الـ encapsulation تحقق الـ abstraction.
هذه هي الفكرة بشكل عام من ناحية KFC ، غداً إن شاء الله أشرح لك الموضوع من الناحية البرمجية وهو بنفس الفكرة لكن سنتطرق لبعض الأمثلة.
تمام شكرا لاهتمام حضرتك ومستنية الباقى
سلام @Howaida
بعد تعرفنا على فكرة الـ Abstraction & encapsulation وقلنا أنه نفس الفكرة تنطبق برمجياً، خلينا في هذا الجزء نشوف متى بيتم تحقيق كل مفهوم من هذه لما تكتبي الكود بتاعك.
في لغة الـ Javascript لما نكون عايزين نعمل object لكائن محدد مثلاً شخص person
بنلم كل الـ properties و الـ Methods بتاعة بداخل هذا الـ object بالشكل التالي:
const person = {
firstName: "Mohammed",
lastName : "Alhakem",
age : 25,
eat(){
//eating method
},
sleep(){
//sleeping method
},
get fullName() {
return `${this.firstName} ${this.lastName }`;
},
};
مجرد قيامك بضم هذه العناصر بداخل وحدة واحدة التي تحتوي هذه العناصر فأنتي قمتي بتطبيق مفهوم الـ encapsulation
هل تذكري هذا الكلام:
المطبخ نستطيع أن نقول بأنه هو الوحدة التي تقوم بعمل إحتوى وتجميع لكل هذه المكونات والعناصر التي تدخل في هذه العملية والتي قد تتضمن أيضاً مكونات سرية لا يستطيع أحد الوصول إليها والتلاعب بها بدون أي قيود.
ببساطة نستطيع نقول بأن المطبخ هو الـ Encapsulation.
تستطيعي تخيل الـ Encapsulation كما تم توضيحة بالصورة التالية:
مصدر الصورة: https://www.scientecheasy.com/2018/06/encapsulation-in-java-real-time-examples-advantages.html
في الصورة أعلاة مثال توضيحي للـ Encapsulation لـ class في لغة الـ Java
نفس الفكرة تنطبق عندنا على لغة الجافاسكريت، الفرق هو أن مفهوم الكلاسات عندنا مختلف ويقوم على الـ Objects، بشكل مبسط عندما قمنا أعلاة بعمل الـ person object وأسندناة للمتغير object فإحنا حققنا الـ Encapsulation.
طيب ماذا عن الـ Abstraction؟
لنفترض انه بنعمل object لسيارة car
بالشكل التالي:
let car = {
model: "2018",
prand: "BMW",
fuel: "gas",
start(){
//start method
},
start(){
//move method
}
};
جميل، لدينا الأن هذا الـ object الذي يمثل سيارة، طيب ماذا لو أردنا أنه نضيف للسيارة owner الي هو المالك ونضيف إسمة وعنوانة ورقم تلفونة مثلاً؟
بسيطة، نقدر نعمل ذلك بالشكل التالي:
const car = {
model: "2018",
prand: "BMW",
fuel: "gas",
ownerName: "Mohammed Alhakem",
ownerAddress: "main street",
ownerPhone: "5555555"
start(){
//start method
},
start(){
//move method
}
};
لكن قيامنا بهذا الشئ قام بإضافة ثلاث properties الي هي:
ownerName | ownerAddress | ownerPhone
المشكلة هي أنه هذه التفاصيل والمعلومات الزائدة الخاصة بالـ owner عقدت الـ object الخاص بالسيارة وقد تسبب تشويش لنا او لمطور أخر.
نريد أن نقوم بتبسيط ذلك والإشارة إلى أن هذا الـسيارة لديها owner فقط بدون وضع تفاصيل هذا الـ owner بداخله object السيارة مباشرة.
فيكيف بإمكاننا القيام بذلك؟
ما رأيك في البدأية بإعتبار المالك owner
كـ object منفصل بحد ذاته، بحيث سيحتوي هذا الـ object تفاصيل المالك كالتالي:
let owner = {
ownerName: "Mohammed Alhakem",
ownerAddress: "main street",
ownerPhone: "5555555"
};
ممتاز، الأن لنقم بإزالة تفاصيل المالك من داخل الـ object الخاص بالسيارة و وإستبدالها بـ property واحدة فقط بإسم owner وأعتبره فارغ null
في الوقت الحالي بالشكل التالي:
let car = {
model: "2018",
prand: "BMW",
fuel: "gas",
owner: null,
start(){
//start method
},
start(){
//move method
}
};
والأن راح اقوم بإنشاء object منفصل للـ owner وأضع فيه التفاصيل:
let owner = {
ownerName: "Mohammed Alhakem",
ownerAddress: "main street",
ownerPhone: "5555555"
};
رائع! أصبح لدي object للسيارة و object للمالك، نريد الان أن نقوم بربطهما بطريقة ما.
راح ارجع للـ obejct الخاص بالسيارة واقوم بعمل setter له يقوم بإسناد مالك لهذه السيارة بالشكل التالي:
let car = {
model: "2018",
prand: "BMW",
fuel: "gas",
owner: null,
start(){
//start method
},
start(){
//move method
},
set theOwner(owner){
this.owner = owner;
}
};
الأن أستطيع إستخدام هذا الـ setter وإضافة الـ owner للـ car بالكود التالي:
car.theOwner= owner
ما الذي قمنا به أعلاة؟
-
قمنا بإنشاء object للسيارة وتحقيق مفهوم الـ Encapsulation من خلال ضم كل الـ props و الـ methods في وحدة واحدة وإسنادها للمتغير car.
-
قمنا بتبسيط الـ interface الخاصة بهذا الـ object وتجنبنا وضع تفاصيل مالك السيارة الـ owner في الـ object الخاص بالـ car بشكل مباشر.
أي قمنا بإضافة الشئ المهم الذي يوضح بأن هناك owner للسيارة وأخفينا تفاصيل هذا الـ owner في object أخر، وبهذا حققنا مفهوم الـ Abstraction
في هذه الصورة توضح كيف انه في الأخير عند طباعة المتغير car
تظهر الـ data الخاصة بالسيارة بأبسط صورة بحيث يتم إيضاح بأن لهذه السيارة مالك owner
بشكل عام حيث انه لا يهمنا في معرفة تفاصيل هذا المالك بقدر ان نعرف بانه يوجد لديها مالك بحيث لا يتم تعبئة الـ object بعناصر غير متصلة بشكل مباشر به.
حاولت أبسط لك الفكرة بأكبر قدر مستطاع من خلال الـ objects بلغة الـ javascript، أتمنى أن تكون الفكرة قد إتضحت.
تمام جدا وضحت كدة
شكرا يا باشمهندس
عفواً