لقد واجهت مؤخرًا صعوبات في عملية تعلم واجهة PHP5. قال الكتاب إنها طريقة لتنفيذ الوراثة المتعددة، لكنني ما زلت لا أعرف كيفية تنفيذها. هناك القليل جدًا من المعلومات حول واجهة PHP على الإنترنت، لذلك قمت بالتحقق من Java، وفي الواقع، فهي متماثلة بشكل أساسي. بعد قراءة مقال "توضيح Java (الواجهات والميراث)" ، أدركت فجأة أنني أسيء فهمها منذ البداية. يشير ما يسمى بالميراث المتعدد إلى الواجهات التي ترث الفئات، وليس الفئات التي ترث الواجهات.
ذكرت المقالة تجريد OO تمامًا مثل الجملة الواردة في المقالة - "التجريد هو إزالة جزء الصورة"، فهي حية جدًا عندما فكرت في التجريد، اعتقدت دائمًا أنه من الصعب فهمه، لكن التجريد من السهل أن نفهم الآن نعم، هذا هو بالضبط ما تفعله الواجهات والفئات المجردة.
وهناك العديد من وجهات النظر الأخرى في المقال التي أفادتني كثيرًا، كما هو موضح أدناه:
أعتقد أن جوهر OO هو تجريد الأشياء.
وظيفة الواجهة، باختصار، هي تحديد نوع الفئة. يمكن أن يؤدي إسناد أنواع مختلفة من الفئات إلى واجهات مختلفة إلى إدارتها بشكل أفضل.
الهدف من الميراث أيضًا هو التجريد، وليس إعادة استخدام الكود.
بعد قراءة هذه المقالة، فهمت الآن بشكل أساسي كيفية تطبيق الواجهات والفئات المجردة والميراث.
النص الأصلي هو كما يلي:
توضيح جافا (الواجهات والوراثة) ناقش أخي، وهو طالب دراسات عليا في السنة الثانية في كلية علوم الكمبيوتر، جافا معي. عندما التقينا، كانت هناك عدة أسئلة تدور حول الواجهات. لماذا استخدام الواجهات؟ متى يجب عليك استخدام الواجهات؟ أنا سعيد لأنهم لم يسألوني عن كيفية الاتصال بـ SQL Server باستخدام Java، أو كيفية تطوير تطبيقات J2EE، فهذه الأسئلة قاتلة ويجب تجنبها. هذا العام، لدى كلية علوم الكمبيوتر مشروع تخرج حول J2ME. كان الطلاب الذين اختاروا هذا الموضوع لا يزالون يدرسون حزمة java.util.* مع كشر في نهاية شهر مايو، هذا وهذا... تنهد.
يعتقد معظم الناس أن الغرض من الواجهات هو استبدال الميراث المتعدد. كما نعلم جميعًا، لا تحتوي Java على آلية وراثة متعددة مثل C++، ولكنها يمكنها تنفيذ واجهات متعددة. في الواقع، هذا أمر بعيد المنال، فالواجهات والميراث شيئان مختلفان تمامًا، ولا تملك الواجهات القدرة على استبدال الميراث المتعدد، وليس لديهم مثل هذا الالتزام. وظيفة الواجهة، باختصار، هي تحديد نوع الفئة. يمكن أن يؤدي إسناد أنواع مختلفة من الفئات إلى واجهات مختلفة إلى إدارتها بشكل أفضل. أعتقد أن جوهر OO هو تجريد الكائنات، والواجهة تجسد ذلك بشكل أفضل. السبب وراء مناقشة أنماط التصميم للغات ذات الإمكانيات المجردة فقط (مثل c++ وjava وc# وما إلى ذلك) هو أن ما تدرسه أنماط التصميم هو في الواقع كيفية التجريد بشكل معقول. (مقولة كاوبوي الشهيرة هي "التجريد هو إزالة جزء الصورة"، وهو ما يبدو مزحة، ولكنه في الواقع صحيح).
أبسط أنماط التصميم هو نمط المصنع. في تطبيق بسيط جدًا قمت بإنشائه مؤخرًا، أردت أن أبذل قصارى جهدي لجعل برنامجي قابلاً للتنقل بين قواعد بيانات متعددة. بالطبع، يتضمن هذا العديد من المشكلات، بما في ذلك كيفية توافق SQL من نظم إدارة قواعد البيانات المختلفة هو الصداع. قد نقوم أيضًا بتبسيط المشكلة أولاً والنظر فقط في كيفية ربط قواعد البيانات المختلفة.
لنفترض أن لدي العديد من الفئات، وهي Mysql.java، وSQLServer.java، وOracle.java، وDB2.java، وهي تتصل بقواعد بيانات مختلفة على التوالي، وترجع كائن اتصال بشكل موحد، وجميعها لديها طريقة قريبة لإغلاق الاتصال. تحتاج فقط إلى تحديد فئات مختلفة لنظام إدارة قواعد البيانات الخاص بك، ويمكنك استخدامه. ولكن ما هي قاعدة البيانات التي سيستخدمها المستخدم؟ لا أعرف، ما آمله هو تعديل الكود بأقل قدر ممكن لتلبية احتياجاته. يمكنني تلخيص الواجهة التالية:
package org.bromon.test;
الواجهة العامة DB
{
java.sql.Connection openDB(String url,String user,Stringpassword);
إغلاق باطل () ؛
}
تحدد هذه الواجهة طريقتين فقط بدون أي تعليمات برمجية ذات معنى. يتم إعطاء التعليمات البرمجية المحددة بواسطة الفئة التي تنفذ هذه الواجهة، مثل Mysql.java:
Package org.bromon.test;
استيراد java.sql.*;
الطبقة العامة Mysql تنفذ قاعدة البيانات
{
سلسلة خاصة url = "jdbc:mysql:localhost:3306/test"؛
سلسلة خاصة للمستخدم = "الجذر"؛
كلمة مرور السلسلة الخاصة =””;
اتصال خاص؛
اتصال عام openDB(url،المستخدم،كلمة المرور)
{
// رمز الاتصال بقاعدة البيانات}
إغلاق الفراغ العام ()
{
//إغلاق قاعدة البيانات}
}
هناك بالطبع Oracle.java، وما إلى ذلك. تقوم الواجهة DB بتصنيف هذه الفئات في التطبيق، نقوم بتعريف الكائن مثل هذا:
org.bromon.test.DB myDB؛
استخدم myDB لتشغيل قاعدة البيانات. لا داعي للقلق بشأن ذلك. ما هو الفصل الذي أستخدمه بالفعل هو ما يسمى بمبدأ "المفتوح والمغلق". لكن المشكلة هي أنه لا يمكن إنشاء مثيل للواجهة، myDB=new DB()، مثل هذا الرمز خاطئ تمامًا، يمكننا فقط myDB=new Mysql() أو myDB=new Oracle(). عذرًا، ما زلت بحاجة إلى تحديد الفئة التي سيتم إنشاء مثيل لها، فاستخدام الواجهة غير مجدي. لذلك نحن بحاجة إلى مصنع:
package org.bromon.test;
الطبقة العامة DBFactory
{
اتصال قاعدة بيانات ثابت عام getConn()
{
Return(new Mysql());
}
}
لذلك يصبح رمز الإنشاء: myDB=DBFactory.getConn();
هذا هو المصنع العادي الأساسي (المصنع) من بين 23 وضعًا. فئة المصنع مسؤولة على وجه التحديد عن إنشاء مثيل للفئة ومنطق البرنامج الآخر الذي يعمل على واجهة قاعدة البيانات. تم نقل المسؤوليات إلى فئة المصنع، بالطبع، يمكنك أيضًا الاستمرار في تحديد واجهة المصنع والاستمرار في رفع المسؤوليات، والتي تتطور إلى مصنع مجرد.
الواجهة ليست مسؤولة عن أي عمليات محددة أثناء العملية بأكملها. إذا أرادت برامج أخرى الاتصال بقاعدة البيانات، فهي تحتاج فقط إلى إنشاء كائن قاعدة بيانات، بغض النظر عن كيفية تغير فئة المصنع. هذا هو ما تدور حوله الواجهات - التجريد.
وغني عن القول أن مفهوم الميراث سهل الفهم. لماذا ترث؟ لأنك تريد إعادة استخدام الكود؟ وهذا بالتأكيد ليس سببًا، فالهدف من الميراث هو التجريد، وليس إعادة استخدام الكود. إذا كان الكائن A لديه طريقة run()، فإن الكائن B يريد أيضًا أن يكون لديه هذه الطريقة، لذلك يستخدم شخص ما الفئة B الممتدة A. هذا هو النهج الطائش. إذا قمت بإنشاء مثيل A في B واستدعاء طريقة Run() الخاصة بـ A، فهل يمكن تحقيق نفس الغرض؟ على النحو التالي:
الفئة ب
{
أ أ=جديد أ();
a.run();
}
هذا هو استخدام تجميع الفئات لإعادة استخدام التعليمات البرمجية، وهو النموذج الأولي لنموذج التفويض والممارسة التي دافعت عنها GoF دائمًا.
إذن ما الفائدة من الميراث؟ في الواقع، يرجع السبب في ذلك إلى أسباب تاريخية. لغة OO الأصلية كانت تحتوي فقط على الميراث ولا توجد واجهات، لذلك لا يمكن تحقيق التجريد إلا من خلال الميراث. يرجى ملاحظة أن الهدف الأصلي من الميراث هو التجريد، وليس إعادة استخدام التعليمات البرمجية (على الرغم من أن الميراث له هذا أيضًا). تأثير). يعد هذا أحد أخطر الأخطاء في العديد من كتب Java السيئة. لم أتخلص تمامًا من الظل الذي تسببت فيه. الكتب السيئة ضارة بالناس، وخاصة الكتب التمهيدية. متى يجب عليك استخدام الميراث؟ استخدمه فقط في الفصول المجردة، وحاول عدم استخدامه في مواقف أخرى. لا يمكن إنشاء مثيل للفئات المجردة، فهي توفر فقط قالبًا يوضح المشكلة.
أصل كل الشرور في تطوير البرمجيات، وخاصة بين مبرمجي C++، هو تكرار التعليمات البرمجية بدلا من إعادة استخدامها، وإساءة استخدام الميراث. الغرض من حظر الميراث المتعدد في Java هو إيقاف الاستخدام السيئ للميراث، وهو أسلوب حكيم للغاية، لكن الكثير من الناس لا يفهمونه. يمكن أن تعكس Java التصميم بشكل أفضل، وهو أحد الأسباب التي تجعلني منبهرًا.