لماذا يجب على مطوري Java إعطاء فرصة لـ Grails؟

نشرت: 2022-03-11

تمتلك Java نظامًا بيئيًا نضج خلال سنوات من التطوير ، مما جعله أحد أكثر الأنظمة الأساسية موثوقية. ومع ذلك ، فإنه يفتقر إلى الوسائل اللازمة لإنجاز المهمة بسرعة ، خاصة بالنسبة لأشياء مثل تطبيقات الويب. في محاولة لتجنب الإحباط من هذه الأنواع من المشكلات ، غالبًا ما يختار المطورون لغات التنفيذ وأطر عمل الويب الحديثة الخاصة بهم ، مثل Ruby with Ruby on Rails و Python مع Django وما إلى ذلك. على عكس Java ، توفر هذه المسارات مسارًا أكثر بساطة لإنشاء تطبيق ويب.

لماذا يجب على مطوري Java إعطاء فرصة لـ Grails؟

مطورو ويب Java: تعرف على Grails واكتشف ما فاتك.
سقسقة

لحسن الحظ ، بالنسبة لمطوري Java الراغبين في إنشاء تطبيقات ويب ، هناك طريقة أفضل ، وهي تتضمن Grails. في هذه المقالة ، سنرى كيف أن Grails with Groovy هو بديل قابل للتطبيق في عالم JVM. سننظر في بعض الأمثلة التي يجذب فيها Grails لنا كمطورين لـ Java وقد يغري شخصًا آخر بتجربته أيضًا.

القصة

في شركة ناشئة عملت بها ، كانت لدينا هذه المشكلة بالضبط. كان لدينا تطبيق Spring الذي أصبح العمل معه صعبًا. مع نموها بشكل أكبر وأكبر ، سرعان ما وجدنا أن إعادة البناء وإضافة الوظائف كانت تستغرق وقتًا أطول مما ينبغي. أدى الجمع بين ذلك وبين بعض الدوافع الأخرى إلى اتخاذ قرار بإعادة كتابة تطبيقنا الأساسي. كنا منفتحين أيضًا على تغيير أو استبدال مجموعة التكنولوجيا الحالية. بدا Grails كخيار قابل للتطبيق لأنه يعمل في JVM وهو مبني على أعلى التقنيات التي نعرفها بالفعل. يستخدم لغة البرمجة Groovy ولكن في نفس الوقت يسمح لك بمزجها مع Java. لذلك أخذنا زمام المبادرة.

بأقصى سرعة

هناك شيء واحد يتفوق فيه Grails حقًا وهو تسهيل بدء مشروع جديد. الأمر بسيط مثل تشغيل أمر يقوم بإنشاء هيكل المشروع مع جميع المجلدات اللازمة للفئات التي ستضيفها لاحقًا. تتطلب إضافة فئات النماذج ووحدات التحكم والخدمات وصفحات الويب أقل قدر ممكن من الجهد. الشيء الوحيد الذي تحتاج إلى الاهتمام به هو تسمية الأشياء ووضعها بشكل صحيح. على عكس Java ، لا يوجد فعليًا رمز معياري يجب أن يكون موجودًا لمجرد أنه يجب أن يكون موجودًا. أصبح هذا ممكنًا جزئيًا باستخدام Spring و Hibernate وهما ركيزتان من أعمدة Grails ، بالإضافة إلى مفهوم الترميز عن طريق الاصطلاح. لتشغيل المشروع ، يأتي Grails مرفقًا مع Apache Tomcat كخادم تطوير. كل ما يتعين علينا القيام به هو تشغيل المشروع في IDE الخاص بنا وسيتم تشغيل الخادم مع نشر الكود الخاص بنا. أيضًا ، سيعتني رسم الخرائط العلائقية للكائن (GORM) مع وضع السبات من Grails بإنشاء قاعدة البيانات لنا. لاستخدام قاعدة بيانات موجودة ، نحتاج إلى تكوين خصائص اتصال JDBC أو تركها افتراضيًا لاستخدام مثيل في الذاكرة. بمجرد تشغيل الخادم مع Grails (يستغرق ما يزيد قليلاً عن تطبيق Spring MVC) ، يمكننا تعديل الكود وستحافظ وظيفة النشر السريع على جلسة تصحيح الأخطاء لدينا مجهزة بأحدث إصدار. الفئات الوحيدة التي لا يمكن إعادة تحميلها بهذه الطريقة هي فئات الكيانات.

يمكن أن يتم ملء قاعدة البيانات باستخدام البرامج النصية لـ SQL ، ولكن يمكن أن يصبح ذلك مملاً. تحتوي جميع مشاريع Grails على فصل Bootstrap سيتم تشغيله عند تشغيل تطبيقنا. في هذه الفئة ، يمكننا تخزين البيانات أو تعديلها وبالتالي تهيئة حالة التطبيق لدينا. ثبت أن هذا مفيد جدًا بالنسبة لنا ، لذلك لدينا بعض حالات الاختبار في إصدار التطوير على الفور.

في فئة Bootstrap ، يمكننا أيضًا استخدام شروط "if" للتحقق من نوع البيئة (التطوير والاختبار والإنتاج وما إلى ذلك) وتعديل البيانات وفقًا لذلك.

التلاعب بالبيانات

من الأشياء التي لفتت انتباهنا على الفور مع Grails هي سهولة التعامل مع البيانات. القراءة من قاعدة البيانات مهمة يجب القيام بها مرارًا وتكرارًا. وفي كثير من الأحيان يكون الأمر بسيطًا. مثل جلب واحد أو أكثر من الكيانات التي تفي بمعايير معينة ثم تجميعها. لماذا لا تستخدم مكتشف ديناميكي لذلك؟ إنها طريقة للاستعلام عن البيانات حيث يتم إنشاء الأساليب ديناميكيًا في وقت التشغيل. كل ما عليك فعله هو اتباع اصطلاح تسمية.

 def users = User.findAllByLastNameLikeOrAgeGreaterThan('Doe%', 30)

سيجلب السطر أعلاه جميع كائنات المستخدم التي يبدأ اسمها الأخير بـ "Doe" أو عمر أكبر من 30. نعم ، ليست حالة معقدة للغاية ولكنك تحصل على جوهرها.

ماذا لو أردنا تصفية هذه القائمة بشكل إضافي لتلك التي تحتوي على خاصية "failureLogins" أكبر من 10؟ وماذا لو أردنا فرزها حسب تاريخ إنشائها؟ وماذا لو أردنا الحصول على أسماءهم الأولى متسلسلة أو العثور على الحد الأقصى لعمر المستخدمين الذين تم إرجاعهم؟

 users = users.findAll() { it.failedLogins > 10 } users = users.sort { it.dateCreated } def firstNamesString = users.firstName.join(', ') def maximumAge = users.age.max()

قد تبدو الأمثلة المذكورة أعلاه بسيطة ، لكنها توضح مدى فاعلية Grails في الاستعلام عن البيانات وتصفيتها ومعالجتها. في Java 8 ، يمكنك تحقيق نتائج مماثلة لبعض هذه الحالات ، لكنها لا تزال تتطلب كودًا أكثر من Grails.

أحيانًا أرغب في الإبداع بشكل مختلف

المُنشئ الديناميكي أو مُنشئ الوسيط المُسمى هو ميزة يريدها الكثير منا في Java. من الجيد تحديد المُنشئ الذي تسمح به فئة معينة ، ولكن في كثير من الحالات ، تريد فقط تعيين بعض الخصائص والحصول على مثيل الرتق. يضيف Groovy مُنشئًا خاصًا لكل كيان يأخذ في الأساس أناقة الخريطة كمدخلات ويعين الخصائص بإدخالات الخريطة.

 def Person = new Person(name: 'Batman', age: 57)

يؤدي هذا النهج إلى رمز أكثر تعبيرًا ويتجنب الحاجة إلى كل التعليمات البرمجية المعيارية للمُنشئ.

راجع للشغل هنا بعض الأمثلة عن روعة وأناقة خرائط Groovy:

 def emptyMap = [:] def map = [bread:3, milk:5, butter:2] map['bread'] = 4 map.milk = 6

هذا مثال آخر على كيف يمكن أن تكون الشفرة قصيرة وبسيطة لكنها قوية. يوضح كيف يمكن استخدام التهيئة المضمنة وكيف يمكن معالجة قيم الخريطة بطريقة مشابهة لخصائص الكائن. لا حاجة لاستدعاء طرق Java التقليدية للمعالجة الأساسية ، إلا إذا كنت تريد ذلك حقًا.

نحن بحاجة الى مزيد من القوة!

بالطبع ، لا يوجد إطار عمل يمكنه فعل كل شيء ، ولكن عندما نقوم بملء الفجوات ، يجب أن نرى ما قد يكون متاحًا بالفعل قبل محاولة تنفيذ حلنا الخاص. لتوسيع ترسانتنا من الوظائف القائمة على Grails ، يمكننا استخدام Grails Plugins. يتم تثبيت البرنامج المساعد ببساطة عن طريق إضافة سطر آخر في فئة BuildConfig الموجودة في كل مشروع من مشاريع Grails (ضربات اصطلاح الكود مرة أخرى!).

 compile ':spring-security-core:2.0-RC4'

يضيف السطر أعلاه جوهر أمان Spring إلى تطبيقنا ولا يوجد تقريبًا أي تكوين مطلوب لدمج هذه الوظيفة.

إنه مشابه لاستخدام تبعيات Maven (والتي يمكنك أيضًا الرجوع إليها في نفس فئة التكوين) ، لكن المكونات الإضافية عادة ما تكون كتل أكبر تحتوي على الوظيفة بأكملها.

بعد قولي هذا ، اسمحوا لي أن أخبركم عن قضية كان علينا التعامل معها. كنا بحاجة إلى تنفيذ بحث يمتد عبر العديد من كيانات البيانات. يحتوي Grails على مكون إضافي Elasticsearch وهو سهل الاستخدام. كما ذكرنا سابقًا ، نحتاج فقط إلى الإشارة إلى المكون الإضافي في ملف التكوين ونحن على ما يرام. إذا أردنا البحث عن كيانات من فئة معينة ، فنحن نحتاج فقط إلى إضافة خاصية ثابتة "قابلة للبحث" إلى تلك الفئة. وإذا أردنا ، يمكننا حتى تحديد الخصائص التي سيسمح بالبحث عنها.

 class User { static searchable = { only = name } String name Double salary }

إنه رمز صغير جدًا ، ولكن تحت الغطاء ، سيقوم برنامج Grails والمكوِّن الإضافي Elasticsearch تلقائيًا بفهرسة جميع المستخدمين بالاسم وتمكيننا من البحث بالاسم. مكالمة البحث الفعلية موجزة جدًا أيضًا:

 User.search("${params.query}")

إذا لم نرغب في ذلك ، فلن نضطر أبدًا إلى لمس مؤشر Lucene. كل شيء سوف يتم تلقائيًا بطريقة سحرية بالنسبة لنا. يحتوي المكون الإضافي أيضًا على واجهة برمجة تطبيقات لعرض نتائج البحث - يمكنه تمييز التطابق الموجود داخل النص الذي تم البحث عنه. هذا مجرد مثال على كيف يمكن أن يوفر المكون الإضافي مجموعة ضخمة من الوظائف التي يمكن أن تجعلنا أكثر كفاءة من خلال تجنب حاجتنا إلى تنفيذها بأنفسنا.

ما زلنا بحاجة إلى مزيد من القوة

الإضافات رائعة ، لكن في بعض الأحيان لا نحتاج إلى مكون إضافي كامل ، نريد فقط شيئًا إضافيًا. هل تتذكر آخر مرة أردت فيها الحصول على طريقة إضافية في فئة Java موجودة ولكنك لم ترغب في (أو لا يمكنك) تمديدها / تجاوزها؟ في Groovy ، يمكنك إضافة أساليب وخصائص إلى الفئات الموجودة ، أو حتى حالات معينة منها. على سبيل المثال ، يمكنك إضافة طريقة formatting إلى فئة java.util.Date التي تكون رائعة عندما تريد تنسيق التواريخ باستمرار ولا تريد كتابة فئات استخدام ثابتة أو تحديد عوامل تصفية مختلفة.

 Date.metaClass.formatDate = { delegate.format("dd.MM.yyyy") }

ماذا لو كنت تريد فرز قائمة المستخدمين حسب القيمة المحسوبة وتحتاج هذا فقط في حالة واحدة (على سبيل المثال ، فإن إضافة طريقة جديدة في فئة المستخدم ستكون ملوثة)؟ يمكنك إضافة خاصية في كل من هذه الحالات ثم فرز المجموعة أو تصفيتها حسب تلك الخاصية:

 user.metaClass.computedProp = 312 * 32 * 3

أضاف مؤلفو Groovy بالفعل الكثير من التحسينات إلى بعض فئات Java الأساسية ، لذلك لا يتعين علينا ذلك. فيما يلي بعض الأمثلة.

استخدام "ناقص" لإزالة جميع العناصر من مجموعة موجودة في مجموعة أخرى.

 assert [1, 2, 3, 4, 4, 5] - [2, 4] == [1, 3, 5]

طرق إضافية لمعالجة كائنات java.util.Date التي تكون في المتناول مرات عديدة ، مثل إضافة / طرح أيام من التواريخ أو الحصول على / تعيين حقل معين من التاريخ دون تحويله إلى Calendar أو استخدام مكتبات إضافية.

 def yesterdayAllMyTroublesSeemedSoFarAway = new Date() - 1 def myAwesomeAnniversaryYear = myAwesomeDate[Calendar.YEAR] + 1 myAwesomeDate.set(year: myAwesomeAnniversaryYear, second: 0)

عندما تريد حقًا الحصول على وصفي من خلال معالجة التاريخ ، يمكنك ببساطة استخدام فئة TimeCategory المضافة من Groovy:

 use (TimeCategory) { println 1.minute.from.now println 10.hours.ago def someDate = new Date() println someDate - 3.months }

مطرقة ومسمار

ثم هناك IDEs. تم إعداد GGTS المستندة إلى Eclipse و IntelliJ IDEA للعمل مع Grails. إنهم يفهمون هيكل المشروع (وسيساعدونك في التنقل عبر المجلدات والموارد) ولديهم اختصارات للأوامر التي ستستخدمها غالبًا (على سبيل المثال ، إضافة وحدة تحكم ، وإضافة صفحة ، وتشغيل مشروع ، وما إلى ذلك). باستخدام Grails ، ستنفذ أوامر (لتشغيل مشروع أو إعداد وظيفة إضافية جديدة) وستحتاج إلى تكوينات مختلفة ، والتي تغطيها IDEs أيضًا. يعمل إكمال التعليمات البرمجية بشكل جيد في صفحات قوالب الويب الخاصة بـ Grails حيث ستشير غالبًا إلى وحدات التحكم والإجراءات. هناك أيضًا IDEs أخرى يمكن استخدامها مع Grails مثل Netbeans و TextMate و Emacs وغيرها.

ماذا عن الجانب المظلم؟

تمامًا كما هو الحال مع كل شيء في الحياة ، هناك محاذير من Grails أيضًا. هناك الكثير من السحر الذي يتم القيام به تحت غطاء المحرك والذي يمكن أن يكون شيئًا جيدًا في كثير من الأحيان ، ولكن في بعض الأحيان لن تكون النتيجة كما كنت تتوقع. ستحدث الأخطاء فقط بسبب عدم استخدام الكتابة (نعم ، الأنواع اختيارية في Groovy) وعدم توخي الحذر الكافي. وربما لن تلاحظ أي خطأ إلا بعد فوات الأوان. أيضًا ، من المغري جدًا كتابة سطر واحد لإقناع زملائك في العمل. ونفسك. لكن هذه الأسطر القوية من التعليمات البرمجية قد لا تشرح نفسها بنفسها لزملائك في العمل. أو حتى لنفسك في غضون شهرين. لهذا السبب أعتقد أن Grails تتطلب المزيد من الانضباط في البرمجة أكثر من بعض الأطر التقليدية.

الوقت قيم

لا ينبغي أن تستغرق البرمجة مزيدًا من الوقت لمجرد أن إطار العمل الحالي يتطلب ذلك. خاصة مع تزايد عدد الشركات الناشئة هذه الأيام ، من المهم التركيز على المهام المهمة حقًا وأن تكون فعالاً قدر الإمكان. الوقت هو بالفعل المال والوقت للتسويق أمر بالغ الأهمية. يجب أن تكون قادرًا على التصرف بسرعة وتنفيذ الحل قبل نفاد الوقت ومنافستك تتفوق عليه.

لطالما أخبرني أصدقائي الذين يعملون مع Ruby on Rails أو Python / Django مدى روعة هذه التقنيات. وكان من السخف حقًا التفكير في مقدار الوقت الذي استغرقته في Java لكتابة رمز يخزن شيئًا ما في قاعدة البيانات ويعرضه في صفحة ويب. قد تكون Grails بالفعل إجابة مفيدة. لا يعني ذلك أنه لا يمكنك فعل ذلك باستخدام Java الخالص و Spring MVC و Hibernate. يمكنك. قد يعمل التطبيق الخاص بك بشكل أسرع قليلاً. لكنك ستنجز المهمة بشكل أسرع مع Grails.

ذات صلة: لماذا تحتاج إلى الترقية إلى Java 8 بالفعل