ما الجديد في CUBA 7

ما الجديد في CUBA 7


قبل ثلاث سنوات ، أعلنا عن الإصدار الرئيسي الثاني المتاح للإطار. كان CUBA 6 هو الإصدار الذي غيّر اللعبة - تم تحويل الترخيص من الملكية إلى Apache 2.0. في تلك الأيام ، لم نتمكن حتى من تخمين أين كان سيأتي بالإطار على المدى الطويل. بدأ مجتمع CUBA ينمو بشكل كبير ، لذلك تعلمنا الكثير من الطرق (وأحيانًا المستحيل) لكيفية استخدام المطورين للإطار. يسعدنا الآن أن نعلن عن CUBA 7 ، والتي نأمل أن تجعل التطوير أكثر تماسكًا وفرحًا لجميع أفراد المجتمع من أولئك الذين بدأوا للتو رحلتهم في CUBA و Java إلى مطوري المشاريع المهرة وخبراء Java.


كوبا


أدوات التطوير


من الواضح أن جزءًا كبيرًا من نجاح CUBA مدينون لـ CUBA Studio . لقد سهّلت بشكل ملحوظ روتين مشروع Java المثمر ، في العديد من الأماكن ، مما أدى إلى تكوينات تافهة في المصممين المرئيين: لا حاجة لمعرفة واجهة برمجة تطبيقات Persistence أو Gradle أو حتى Spring لتطوير تطبيق CRUD كامل وغني بالميزات - سيقوم Studio بعمل ذلك من اجلك


كان Studio عبارة عن تطبيق ويب منفصل وتسببت هذه الحقيقة في بعض القيود الهامة:


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

قررنا الاعتماد على كتف عملاق آخر للتغلب على هذه القيود. تم دمج Studio في IntelliJ IDEA بواسطة JetBrains. يمكنك الآن تثبيته كمكون إضافي لبرنامج IntelliJ IDEA أو تنزيله كحزمة منفصلة منفصلة.


cuba1


هذا يفتح آفاقا جديدة:


  • دعم لغات JVM الأخرى (وكوتلين في المقام الأول)
  • تحسين الساخنة نشر
  • الملاحة بديهية من خلال المشروع بأكمله
  • تلميحات أكثر ذكاء ومولدات الشفرة

الاستوديو الجديد حاليًا قيد التطوير النشط: نقوم بنقل الميزات من الإصدار القديم. تتمثل الخطة قصيرة الأجل أيضًا في إعادة تطبيق المصممين على الويب باستخدام IntelliJ UI الأصلي وتحسين تجربة التنقل في المشروع.


ترقية المكدس


تقليديًا ، تم تحديث الحزمة الأساسية أيضًا بشكل كبير ، مثل Java 8/11 و Vaadin 8 و Spring 5.


cuba2


افتراضيًا ، تستخدم المشروعات الجديدة Java 8 ، ولكن يمكنك تحديد إصدار Java بإضافة العبارة التالية إلى ملف build.gradle:


subprojects { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } 

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


قائمة كاملة من التبعيات المحدثة متوفرة في ملاحظات الإصدار الرسمي.


شاشات جديدة API


يمكن تسمية هذا القسم أيضًا "واجهة برمجة تطبيقات الشاشات الأولى" - حيث أن CUBA لم يسبق له مثيل أي واجهة برمجة تطبيقات معلنة رسميًا في فئة عميل الويب. إنه يأتي من تاريخ الإطار وبعض الافتراضات التي تم وضعها في المرحلة الأولى:


  • النهج المتمحور حول التعريف - كل شيء يمكن وصفه بشكل تعريفي ، يجب الإعلان عنه في واصف الشاشة وعدم ترميزه في وحدة التحكم الخاصة به
  • توفر الشاشات القياسية (المتصفح والمحرر) وظائف عامة ملموسة وليس هناك حاجة لتعديلها

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


cuba3


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


إعلان الشاشة


في إعلان الشاشة CUBA 7 بسيط للغاية:


 @UiController("new-screen") // screen id public class NewScreen extends Screen { } 

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


 @Inject private ScreenBuilders screenBuilders; @Subscribe private void onBeforeClose(BeforeCloseEvent event) { screenBuilders.screen(this) .withScreenClass(SomeConfirmationScreen.class) .build() .show(); } 

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


من قبل ، كان مطلوبًا أيضًا تسجيل واصف شاشة في ملف web-screens.xml وتعيين معرف له. في CUBA 7 ، يتم الاحتفاظ بهذا الملف لأسباب تتعلق بالتوافق ، ولكن إنشاء شاشات بطريقة جديدة لا يتطلب هذا التسجيل.


شاشات دورة الحياة


يقدم API الجديد أحداث دورة حياة الشاشة واضحة وواضحة:


  • التهيئة
  • AfterInit
  • BeforeShow
  • AfterShow
  • BeforeClose
  • AfterClose

يمكن الاشتراك في جميع الأحداث المتعلقة بالشاشة في CUBA 7 على النحو التالي:


 @UiController("new-screen") public class NewScreen extends Screen { @Subscribe private void onInit(InitEvent event) { } @Subscribe private void onBeforeShow(BeforeShowEvent event) { } } 

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


التعامل مع الحدث والمندوبين الوظيفيين


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


لنأخذ مثالًا بسيطًا يحتوي على عنصرين من عناصر واجهة المستخدم: زر وحقل عملة ، بحيث يبدو واصف XML الخاص به كما يلي:


 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" caption="msg://caption" messagesPack="com.company.demo.web"> <layout> <hbox spacing="true"> <currencyField id="currencyField" currency="$" currencyLabelPosition="LEFT"/> <button id="calcPriceBtn" caption="Calculate Price"/> </hbox> </layout> </window> 

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


 @UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen { @Inject private PricingService pricingService; @Inject private CurrencyField<BigDecimal> currencyField; @Subscribe("calcPriceBtn") private void onCalcPriceBtnClick(Button.ClickEvent event) { currencyField.setValue(pricingService.calculatePrice()); } @Subscribe("currencyField") private void onPriceChange(HasValue.ValueChangeEvent<BigDecimal> event) { BigDecimal price = pricingService.calculatePrice(); currencyField.setStyleName(getStyleNameByPrice(price)); } private String getStyleNameByPrice(BigDecimal price) { ... } } 

في المثال أعلاه ، يمكننا رؤية معالجين للأحداث: يتم استدعاء أحدهما عند النقر فوق الزر ويتم تنفيذ واحد آخر عندما يغير حقل العملة قيمته - بهذه البساطة.


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


 @UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen { @Inject private CurrencyField<BigDecimal> currencyField; @Subscribe private void onInit(InitEvent event) { currencyField.addValidator(value -> { if (value.compareTo(BigDecimal.ZERO) <= 0) throw new ValidationException("Price should be greater than zero"); }); } } 

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


 @UiController("demo_MyFirstScreen") @UiDescriptor("my-first-screen.xml") public class MyFirstScreen extends Screen { @Inject private CurrencyField<BigDecimal> currencyField; @Install(to = "currencyField", subject = "validator") private void currencyFieldValidator(BigDecimal value) { if (value.compareTo(BigDecimal.ZERO) <= 0) throw new ValidationException("Price should be greater than zero"); } } 

في الواقع ، نقوم بتفويض منطق التحقق من الصحة من حقل عملتنا إلى طريقة currencyFieldValidator في شاشتنا. قد يبدو هذا معقدًا بعض الشيء ، ومع ذلك ، يعتمد المطورون هذه الميزة بسرعة مذهلة.


بناة الشاشة / الإخطارات / مربعات الحوار


cuba4


تقدم CUBA 7 أيضًا مجموعة من المكونات المفيدة مع واجهات برمجة التطبيقات بطلاقة:


  • يجمع ScreenBuilders بين المصانع بطلاقة لإنشاء عمليات البحث القياسية والمحررين والشاشات المخصصة. يوضح المثال التالي كيف يمكنك فتح شاشة من أخرى. لاحظ أن طريقة build () تُرجع نسخة الشاشة من النوع الصحيح ، دون الحاجة إلى إرسالها بطريقة غير آمنة.


    CurrencyConversions currencyConversions = screenBuilders.screen (هذا)
    .withScreenClass (CurrencyConversions.class)
    .withLaunchMode (OpenMode.DIALOG)
    .build () ؛
    currencyConversions.setBaseCurrency (Currency.EUR)؛
    currencyConversions.show ()؛


  • يوفر مكون شاشات تجريد مستوى أقل لإنشاء وعرض شاشات بدلاً من ScreenBuilders . كما يوفر الوصول إلى المعلومات حول جميع الشاشات المفتوحة في تطبيق CUBA الخاص بك ( الشاشات # getOpenedScreens ) في حال كنت بحاجة إلى تكرارها.


  • تقدم مكونات الإخطارات ومربعات الحوار واجهات سهلة التوضيح. فيما يلي مثال لإنشاء وعرض حوار وإخطار:


    dialogs.createOptionDialog ()
    .withCaption ("مربع حواري الأول")
    .withMessage ("هل ترغب في شكر فريق CUBA؟")
    .مع العمليات (
    DialogAction الجديد (DialogAction.Type.YES) .withHandler (e ->
    الإخطارات. ((
    .withCaption ("شكرا لك!")
    .withDescription ("نحن نقدر جميع أفراد المجتمع")
    .withPosition (Notifications.Position.MIDDLE_CENTER)
    . withHideDelayMs (3000)
    .عرض ()) ،
    DialogAction الجديد (DialogAction.Type.CANCEL)
    )
    .show () ؛



ربط البيانات


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


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


  • أداة تحميل البيانات هي مزود بيانات لحاويات البيانات. لا تحتفظ برامج تحميل البيانات بالبيانات ، بل تمرر جميع معلمات الاستعلام المطلوبة إلى مخزن البيانات وتغذي حاويات البيانات باستخدام مجموعة البيانات الناتجة.
  • يحتفظ حاوية البيانات بالبيانات المحملة (كيان واحد أو عدد من الكيانات) ويوفرها للمكونات التي تدرك البيانات بطريقة تفاعلية: تتعرض جميع التغييرات في الكيانات المُلفوفة لمكونات واجهة المستخدم المقابلة والعكس بالعكس ، وجميع التغييرات في ستؤدي مكونات واجهة المستخدم إلى التغييرات المقابلة في حاوية البيانات الخاصة بها.
  • سياق البيانات هو مدير تعديل بيانات قوي يتتبع التغييرات ويلزم كل الكيانات المعدلة. يمكن دمج الكيان في سياق البيانات ، لذلك سيوفر نسخة من الكيان الأصلي مع الفارق الوحيد ، لكن المهم للغاية: سيتم تتبع وتخزين وتخزين جميع تعديلات الكيان الناتج وكل الكيانات التي يشير إليها (بما في ذلك المجموعات) ارتكبت وفقا لذلك.

يمكن الإعلان عن مكونات البيانات في واصفات الشاشة أو إنشاء مثيل لها برمجيًا باستخدام مصنع متخصص - DataComponents .


متنوع


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


  • تاريخ URL والملاحة . تعمل هذه الميزة على حل مشكلة شائعة جدًا في SPA من خلال زر "الرجوع" في متصفح الويب ، وتوفر طريقة سهلة لتعيين طرق لشاشات التطبيقات وتمكين واجهة برمجة التطبيقات من عكس الحالة الحالية للشاشة في عنوان URL الخاص بها.
  • نموذج بدلاً من FieldGroup . FieldGroup هو مكون مدرك للبيانات لإظهار وتعديل حقول كيان واحد. أنه يجسد واجهة المستخدم الفعلية المعروضة للحقل في وقت التشغيل. بمعنى آخر ، إذا كان لديك حقل " تاريخ" في كيانك ، فسيتم عرضه كحقل تاريخ . ومع ذلك ، إذا كنت ترغب في العمل مع هذا الحقل برمجيًا ، فستحتاج إلى ضخ هذا الحقل إلى وحدة التحكم في الشاشة وإلقائه على النوع الصحيح يدويًا ( DateField في مثالنا ). بعد ذلك ، قمنا بتغيير نوع الحقل الخاص بنا إلى نوع آخر وتعطل تطبيقنا في وقت التشغيل ... يعالج النموذج هذه المشكلة بإعلان نوع الحقل الصريح. العثور على مزيد من المعلومات حول هذا المكون الجديد هنا .
  • تم تبسيط تكامل مكونات جافا سكريبت للجهات الخارجية بشكل كبير ، اتبع الوثائق لتضمين مكونات جافا سكريبت المخصصة في تطبيق CUBA.
  • يمكن الآن تعريف سمات HTML / CSS بسهولة من واصف شاشة xml أو تعيينها برمجيًا. العثور على مزيد من المعلومات هنا .

ميزات الوسيطة


كانت الكتلة السابقة المتعلقة بواجهة برمجة التطبيقات الجديدة للشاشات أكبر مما كنت أتوقع ، لذا سأحاول في هذا القسم أن أكون أنيقًا!


حدث تغيير الكيان


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


هناك أيضًا طريقة للقبض على حدث الكيان المتغير مباشرةً بعد حدوث الالتزام.


اتبع هذا الفصل من الوثائق لمعرفة مثال.


مدير بيانات المعاملات


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


  • يمكنه الانضمام إلى المعاملة الحالية (في حالة استدعاؤها ضمن سياق المعاملات) أو إنشاء المعاملة الخاصة بها.
  • لا يوجد لديه طريقة التزام ، ولكن هناك طريقة الحفظ ، والتي لا تؤدي إلى التزام فوري ، لكنها تنتظر حتى يتم الالتزام بالمعاملة المرفقة.

ابحث عن مثال لاستخدامه هنا .


JPA دورة حياة الاسترجاعات


أخيرًا ، تدعم CUBA 7 عمليات الاسترجاعات لدورة حياة JPA. لعدم تكرار معلومات مكتوبة جيدًا حول ما يمكن أن تستخدمه عمليات الاسترجاعات هذه ، اسمحوا لي أن أشارك هذا الرابط الذي يغطي الموضوع بالكامل.


ماذا عن التوافق؟


cuba5


سؤال عادل لأي إصدار رئيسي ، خاصةً عندما يكون هناك الكثير من التغييرات التي يبدو أنها تخرق! لقد قمنا بتصميم جميع هذه الميزات وواجهات برمجة التطبيقات الجديدة مع مراعاة التوافق مع الإصدارات السابقة:


  • يتم دعم واجهة برمجة التطبيقات للشاشات القديمة في CUBA 7 ويتم تنفيذها عن طريق الجديدة تحت غطاء محرك السيارة :)
  • لقد قدمنا ​​أيضًا محولات لربط البيانات القديم ، والتي تستمر في العمل على الشاشات القديمة.

لذلك ، خبر جيد ، يجب أن يكون مسار الترحيل من الإصدار 6 إلى 7 واضحًا تمامًا.


استنتاج


في ختام هذه النظرة التقنية أود أن أشير إلى أن هناك ابتكارات مهمة أخرى ، خاصة فيما يتعلق بالترخيص:


  • تم الآن تجاوز الحد الأقصى البالغ 10 كيانات لـ Studio
  • التقارير ، BPM ، الرسوم البيانية والخرائط وملحقات البحث عن النص الكامل أصبحت الآن مجانية ومفتوحة المصدر.
  • يوفر الإصدار التجاري من Studio راحة تطوير إضافية مع المصممين المرئيين للكيانات والشاشات والقوائم وعناصر النظام الأساسي الأخرى ، بينما تركز النسخة المجانية على العمل باستخدام الكود
  • يرجى ملاحظة أنه بالنسبة للإصدارات 6.x والإصدارات الأقدم من شروط ترخيص Platform و Studio تظل كما هي!

أخيرًا ، اسمحوا لي أن أشكر أعضاء المجتمع مرة أخرى على كل الدعم والتعليقات. أتمنى أن تحب الإصدار 7! تتوفر القائمة الكاملة للتغييرات بشكل تقليدي في ملاحظات الإصدار .

Source: https://habr.com/ru/post/ar444558/


All Articles