ما هو السبات؟ أساسيات تطبيق Hibernate Core
نشرت: 2013-04-17السبات هو مشروع إطار عمل جافا مفتوح المصدر. إجراء تخطيط قوي للكائنات وقواعد بيانات الاستعلام باستخدام HQL و SQL.
بشكل عام ، تم تصميم وتنفيذ المكتبات المستخدمة على نطاق واسع بشكل جيد ، ومن المثير للاهتمام أن نتعلم منها بعض أفضل ممارسات الترميز.
دعنا نلقي نظرة داخل المكتبة الأساسية في حالة السبات ونكتشف بعض مفاتيح التصميم الخاصة بها.
في هذا المنشور ، يتم تحليل Hibernate Core بواسطة JArchitect
في تصميمه وتنفيذه.
الحزمة حسب الميزة
Package-by-feature
الحزم لتعكس مجموعة الميزات. يضع جميع العناصر المتعلقة بميزة واحدة (وهذه الميزة فقط) في دليل / حزمة واحدة. ينتج عن هذا حزم ذات تماسك عالٍ ونمطية عالية ، مع الحد الأدنى من الاقتران بين الحزم. يتم وضع العناصر التي تعمل بشكل وثيق معًا بجانب بعضها البعض.
يحتوي Hibernate core على العديد من الحزم ، كل واحدة مرتبطة بميزة معينة hql و sql وغيرها.
اقتران
يعد الاقتران المنخفض أمرًا مرغوبًا فيه لأن التغيير في منطقة واحدة من التطبيق سيتطلب تغييرات أقل خلال التطبيق بأكمله. على المدى الطويل ، يمكن أن يؤدي ذلك إلى تخفيف الكثير من الوقت والجهد والتكلفة المرتبطة بتعديل وإضافة ميزات جديدة إلى أحد التطبيقات.
فيما يلي ثلاث فوائد رئيسية مستمدة من استخدام الواجهات:
- توفر الواجهة طريقة لتحديد عقد يشجع على إعادة الاستخدام. إذا كان الكائن يطبق واجهة ، فإن هذا الكائن يتوافق مع معيار. الكائن الذي يستخدم كائنًا آخر يسمى المستهلك. الواجهة عبارة عن عقد بين كائن ومستهلكه.
- توفر الواجهة أيضًا مستوى من التجريد يجعل البرامج أسهل في الفهم. تسمح الواجهات للمطورين بالبدء في الحديث عن الطريقة العامة التي تتصرف بها التعليمات البرمجية دون الحاجة إلى الدخول في الكثير من التفاصيل التفصيلية.
- تفرض الواجهة اقترانًا منخفضًا بين المكونات ، وهو ما يسهل حماية مستخدم الواجهة من أي تغييرات في التنفيذ في الفئات التي تنفذ الواجهات.
دعنا نبحث عن جميع الواجهات المحددة بواسطة Hibernate Core ، لذلك نستخدم CQLinq
للاستعلام عن قاعدة التعليمات البرمجية.
1 |
from t in Types where t . IsInterface select t |
إذا كان هدفنا الأساسي هو فرض اقتران منخفض ، فهناك خطأ شائع عند استخدام الواجهات التي يمكن أن تقضي على فائدة استخدامها. إنه استخدام الأصناف الملموسة بدلاً من الواجهات ، ولتوضيح هذه المشكلة بشكل أفضل دعنا نأخذ المثال التالي:
تطبق الفئة A واجهة IA التي تحتوي على طريقة الحساب () ، ويتم تنفيذ فئة المستهلك C على هذا النحو
1 2 3 4 5 6 7 8 9 10 11 |
public class C < br > { … . public void calculate ( ) { … . . m_a . calculate ( ) ; … . } A m_a ; } |
الفئة C بدلاً من الإشارة إلى الواجهة IA ، فإنها تشير إلى الفئة A ، وفي هذه الحالة نفقد فائدة الاقتران المنخفضة ، وهذا التنفيذ له عيبان رئيسيان:
- إذا قررنا استخدام تطبيق آخر لـ IA ، فيجب علينا تغيير رمز الفئة C.
- إذا تمت إضافة بعض الطرق إلى A غير الموجودة في IA ، واستخدمها C ، فإننا نفقد أيضًا ميزة العقد لاستخدام الواجهات.
قدم C # إمكانية تنفيذ الواجهة الواضحة للغة لضمان عدم استدعاء طريقة من IA مطلقًا من مرجع إلى فئات محددة ، ولكن فقط من مرجع إلى الواجهة. هذه التقنية مفيدة جدًا لحماية المطورين من فقدان ميزة استخدام الواجهات.
مع JArchitect يمكننا التحقق من هذا النوع من الأخطاء باستخدام CQLinq
، والفكرة هي البحث عن جميع الطرق من الفئات الملموسة المستخدمة مباشرةً بواسطة طرق أخرى.
1 2 3 4 5 6 7 8 9 |
from m in Methods where m . NbMethodsCallingMe > 0 && m . ParentType . IsClass && ! m . ParentType . IsThirdParty && ! m . ParentType . IsAbstract let interfaces = m . ParentType . InterfacesImplemented from i in interfaces where i . Methods . Where ( a = > a . Name == m . Name && a . ParentType ! = m . ParentType ) . Count ( ) > 0 select new { m , m . ParentType , i } |
على سبيل المثال ، الطريقة getEntityPersister من SessionFactoryImpl التي تنفذ واجهة SessionFactoryImplementor معنية بهذه المشكلة.
لنبحث عن طرق تستدعي مباشرة SessionFactoryImpl.getEntityPersister.
1 2 3 |
from m in Methods where m . IsUsing ( "org.hibernate.internal.SessionFactoryImpl.getEntityPersister(String)" ) select new { m , m . NbBCInstructions } |

تستدعي أساليب مثل SessionImpl.instantiate getEntityPersister مباشرةً ، بدلاً من المرور عبر الواجهة ، ما يكسر فائدة استخدام الواجهات. لحسن الحظ ، لا يحتوي قلب السبات على العديد من الطرق التي تواجه هذه المشكلة.
اقتران مع الجرار الخارجية
عند استخدام libs الخارجية ، من الأفضل التحقق مما إذا كان بإمكاننا بسهولة تغيير lib الخاص بطرف ثالث بآخر دون التأثير على التطبيق بأكمله ، فهناك العديد من الأسباب التي يمكن أن تشجعنا على تغيير lib الخاص بطرف ثالث.
يستطيع الليب الآخر:
- احصل على المزيد من الميزات
- اقوى
- أكثر أمنا
لنأخذ مثال antlr lib
الذي يستخدم لتحليل استعلامات hql ، ونتخيل أنه تم إنشاء محلل آخر أقوى من antlr ، هل يمكننا تغيير antlr بواسطة المحلل اللغوي الجديد بسهولة؟
للإجابة على هذا السؤال ، دعنا نبحث عن الطرق من السبات التي نستخدمها مباشرة:
1 2 3 |
from m in Methods where m . IsUsing ( "antlr-2.7.7" ) select new { m , m . NbBCInstructions } |
وأيها استخدمها بشكل غير مباشر:
1 2 3 4 |
from m in Projects . WithNameNotIn ( "antlr-2.7.7" ) . ChildMethods ( ) let depth0 = m . DepthOfIsUsing ( "antlr-2.7.7" ) where depth0 > 1 orderby depth0 select new { m , depth0 } |
تستخدم العديد من الطرق antlr مباشرة مما يجعل نواة السبات مقترنة به بشدة ، وتغيير antlr بآخر ليس بالمهمة السهلة. هذه الحقيقة لا تعني أن لدينا مشكلة في تصميم السبات ، ولكن علينا توخي الحذر عند استخدام مكتبة طرف ثالث والتحقق جيدًا مما إذا كان يجب أن يكون تحرير طرف ثالث منخفضًا أم لا مع التطبيق.
تماسك
ينص مبدأ المسؤولية الفردية على أن الطبقة يجب أن يكون لها سبب واحد فقط للتغيير. يقال أن هذه الفئة متماسكة. تحدد قيمة LCOM
المرتفعة عمومًا فئة ضعيفة التماسك. هناك العديد من مقاييس LCOM. تأخذ LCOM قيمها في النطاق [0-1]. يأخذ LCOMHS (HS اختصارًا لـ Henderson-Sellers) قيمه في النطاق [0-2]. لاحظ أن مقياس LCOMHS يعتبر غالبًا أكثر كفاءة لاكتشاف الأنواع غير المتماسكة.
يجب اعتبار قيمة LCOMHS الأعلى من 1 مقلقة.
في الفصول العامة أكثر اهتمامًا بالتماسك هي الطبقات التي لديها العديد من الأساليب والمجالات.
دعنا نبحث عن أنواع لها العديد من الأساليب والحقول.
1 2 3 4 |
from t in Types where ( t . Methods . Count ( ) > 40 | | t . Fields . Count ( ) > 40 ) && t . IsClass orderby t . Methods . Count ( ) descending select new { t , t . InstanceMethods , t . Fields , t . LCOMHS } |
هناك أنواع قليلة فقط معنية بهذا الاستعلام ، وبالنسبة لجميعهم ، فإن LCOMHS أقل من 1.
استخدام التعليقات التوضيحية
يريح التطوير المستند إلى التعليقات التوضيحية مطوري Java من معاناة التكوين المرهق. ومنحنا ميزة قوية لتحرير الكود المصدري من الكود المعياري. من غير المرجح أن تحتوي الكود الناتج على أخطاء.
دعنا نبحث عن جميع التعليقات التوضيحية المحددة من خلال وضع السبات الأساسي.
1 |
from t in Types where t . IsAnnotationClass && ! t . IsThirdParty select t |
يتم تحديد العديد من التعليقات التوضيحية ، مما يجعل السبات سهل الاستخدام من قبل المطورين ، ويتم تجنب صداع ملفات التكوين.
خاتمة
Hibernate Core هو مثال جيد لمشاريع مفتوحة المصدر للتعلم منها ، لا تتردد في إلقاء نظرة داخلها.