كتاب "تعلم Java EE. البرمجة الحديثة للمؤسسات الكبيرة "

الصورة مرحباً هبر!

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

تسلسل التنفيذ


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

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

التنفيذ المتزامن


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

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

تنفيذ غير متزامن


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

طرق EJB غير المتزامنة

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

@Asynchronous @Stateless public class Calculator { public void calculatePi(long decimalPlaces) { //      } } 

خدمة إدارة الأداء

للتنفيذ غير المتزامن للمهام في كائنات CDI المُدارة أو باستخدام أدوات التحكم في التزامن Java SE ، تتضمن Java EE إصدارات مدارة بالحاويات من الدالتين ExecutorService و ScheduledExecutorService. يتم استخدامها لتنفيذ المهام غير المتزامنة في سلاسل الرسائل المدفوعة بالحاويات. يتم تضمين مثيلات ManagedExecutorService و ManagedScheduledExecutorService في رمز التطبيق. يمكن استخدامها لتنفيذ منطقهم الخاص ، ولكن تكون أكثر فعالية عند دمجها مع أدوات التحكم في التزامن Java SE ، مثل القيم المستقبلية المكتملة. يوضح المثال التالي كيفية إنشاء قيم مستقبلية مبطنة باستخدام سلاسل الرسائل المدفوعة بالحاويات:

 import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedExecutorService; import java.util.Random; import java.util.concurrent.CompletableFuture; @Stateless public class Calculator { @Resource ManagedExecutorService mes; public CompletableFuture<Double> calculateRandomPi(int maxDecimalPlaces) { return CompletableFuture.supplyAsync(() -> new Random().nextInt(maxDecimalPlaces) + 1, mes) .thenApply(this::calculatePi); } private double calculatePi(long decimalPlaces) { … } } 

يعرض كائن الحاسبة القيمة المستقبلية التكميلية للنوع المزدوج ، والتي لا يزال من الممكن حسابها عند استئناف سياق الاستدعاء. يمكن طلبها عند اكتمال العمليات الحسابية ، بالإضافة إلى العمليات الحسابية اللاحقة. بغض النظر عن مكان وجود سلاسل محادثات جديدة في تطبيق المؤسسة ، يجب عليك استخدام وظيفة Java EE لإدارتها.

أحداث CDI غير المتزامنة

يمكن أيضًا معالجة أحداث CDI بشكل غير متزامن. في هذه الحالة ، توفر الحاوية أيضًا دفقًا لمعالجة الأحداث. لوصف معالج حدث غير متزامن ، يتم التعليق على الطريقة باستخدامObservesAsync ، ويتم تنشيط الحدث باستخدام طريقة fireAsync (). توضح قصاصات التعليمات البرمجية التالية أحداث CDI غير المتزامنة:

 @Stateless public class CarManufacturer { @Inject CarFactory carFactory; @Inject Event<CarCreated> carCreated; public Car manufactureCar(Specification spec) { Car car = carFactory.createCar(spec); carCreated.fireAsync(new CarCreated(spec)); return car; } } 

يتم استدعاء معالج الأحداث في سلسلة الرسائل الخاصة به المُدارة بواسطة الحاوية:

 import javax.enterprise.event.ObservesAsync; public class CreatedCarListener { public void onCarCreated(@ObservesAsync CarCreated event) { //    } } 

لأسباب التوافق مع الإصدارات السابقة ، يمكن أيضًا معالجة أحداث CDI المتزامنة بطريقة EJB غير المتزامنة. وبالتالي ، يتم تعريف الأحداث والمعالجات على أنها متزامنة ، وطريقة المعالج هي طريقة عمل EJB مع تعليق توضيحي @ Asynchronous. قبل إدخال الأحداث غير المتزامنة في معيار CDI لـ Java EE 8 ، كانت هذه هي الطريقة الوحيدة لتنفيذ هذه الميزة. لتجنب الارتباك في Java EE 8 والإصدارات الأحدث ، من الأفضل تجنب هذا التطبيق.

نطاقات المعالجة غير المتزامنة

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

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

ضبط وقت التنفيذ

يمكن استدعاء سيناريوهات الأعمال ليس فقط من الخارج ، على سبيل المثال ، عبر طلب HTTP ، ولكن أيضًا من داخل التطبيق - وهي مهمة يتم تشغيلها في وقت محدد.

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

 import javax.ejb.Schedule; import javax.ejb.Startup; @Singleton @Startup public class PeriodicJob { @Schedule(minute = "*/10", hour = "*", persistent = false) public void executeJob() { //   10  } } 

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

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

يتم وصف المؤقتات التي يتم إنشاؤها تلقائيًا باستخدام التعليق التوضيحي للجدول باستخدام تعبيرات cron الشبيهة بـ Unix. لمزيد من المرونة ، يتم وصف موقتات EJB برمجياً باستخدام خدمة عداد الوقت المزودة بالحاوية ، والتي تنشئ أساليب رد الاتصال للموقتات والوقت.

يمكن أيضًا وصف المهام الدورية والمؤجلة خارج EJBs باستخدام خدمة الجدولة المدارة بواسطة الحاوية. مثيل من ManagedScheduledExecutorService يقوم بتنفيذ المهام بعد التأخير المحدد أو على فترات محددة يتم تنفيذه في المكونات المدارة. سيتم تنفيذ هذه المهام في سلاسل عمليات مدفوعة بالحاويات:

 @ApplicationScoped public class Periodic { @Resource ManagedScheduledExecutorService mses; public void startAsyncJobs() { mses.schedule(this::execute, 10, TimeUnit.SECONDS); mses.scheduleAtFixedRate(this::execute, 60, 10, TimeUnit.SECONDS); } private void execute() { … } } 

سيؤدي استدعاء الأسلوب startAsyncJobs () إلى تنفيذ وظيفة التنفيذ () على مؤشر الترابط المُدار بعد عشر ثوانٍ من المكالمة ثم كل عشر ثوانٍ بعد الدقيقة الأولى.

عدم التزامن والتفاعلية في JAX-RS

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

 @Path("users") @Consumes(MediaType.APPLICATION_JSON) public class UsersResource { @Resource ManagedExecutorService mes; … @POST public CompletionStage<Response> createUserAsync(User user) { return CompletableFuture.supplyAsync(() -> createUser(user), mes); } private Response createUser(User user) { userStore.create(user); return Response.accepted().build(); } } 

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

عودة مراحل الانتهاء هي تقنية جديدة نسبيًا في JAX-RS API. إذا كنت بحاجة إلى وصف التأخير وفي الوقت نفسه توفير مرونة أكبر مع استجابة غير متزامنة ، فيمكنك تضمين نوع AsyncResponse في الطريقة. يتم توضيح هذا النهج في المثال التالي:

 import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; @Path("users") @Consumes(MediaType.APPLICATION_JSON) public class UsersResource { @Resource ManagedExecutorService mes; … @POST public void createUserAsync(User user, @Suspended AsyncResponse response) { response.setTimeout(5, TimeUnit.SECONDS); response.setTimeoutHandler(r -> r.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).build())); mes.execute(() -> response.resume(createUser(user))); } } 

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

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

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

 import java.util.stream.Collectors; @ApplicationScoped public class WeatherForecast { private Client client; private List<WebTarget> targets; @Resource ManagedExecutorService mes; @PostConstruct private void initClient() { client = ClientBuilder.newClient(); targets = … } public Forecast getAverageForecast() { return invokeTargetsAsync() .stream() .map(CompletableFuture::join) .reduce(this::calculateAverage) .orElseThrow(() -> new IllegalStateException("   ")); } private List<CompletableFuture<Forecast>> invokeTargetsAsync() { return targets.stream() .map(t -> CompletableFuture.supplyAsync(() -> t .request(MediaType.APPLICATION_JSON_TYPE) .get(Forecast.class), mes)) .collect(Collectors.toList()); } private Forecast calculateAverage(Forecast first, Forecast second) { … } @PreDestroy public void closeClient() { client.close(); } } 

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

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

يحتوي أحدث إصدار من JAX-RS على دعم مدمج لمراحل الإنجاز ، مما يقلل من الرمز النمطي في التطبيقات. كما هو الحال مع القيم المبطنة ، ترجع المكالمة على الفور رمز مرحلة الاكتمال للرجوع إليها في المستقبل. يوضح المثال التالي وظائف العميل التفاعلي JAX-RS باستخدام استدعاء rx ():

 public Forecast getAverageForecast() { return invokeTargetsAsync() .stream() .reduce((l, r) -> l.thenCombine(r, this::calculateAverage)) .map(s -> s.toCompletableFuture().join()) .orElseThrow(() -> new IllegalStateException("   ")); } private List<CompletionStage<Forecast>> invokeTargetsAsync() { return targets.stream() .map(t -> t .request(MediaType.APPLICATION_JSON_TYPE) .rx() .get(Forecast.class)) .collect(Collectors.toList()); } 

في المثال أعلاه ، لا تحتاج إلى البحث عن خدمة المنفذين المجدولين - سيدير ​​عميل JAX-RS هذا بنفسه. قبل ظهور طريقة rx () ، استخدم العملاء استدعاء async () صريحًا. تصرفت هذه الطريقة بشكل مماثل ، لكنها أعادت فقط كائنات المستقبل. يعتبر استخدام نهج رد الفعل في العملاء هو الأمثل لمعظم المشاريع.
كما ترى ، يستخدم Java EE خدمة الفنان المدارة بالحاويات.

مفاهيم ومبادئ التصميم في Java EE الحديثة


تعتمد واجهة برمجة تطبيقات Java EE API على الاصطلاحات ومبادئ التصميم التي يتم توضيحها كمعايير. سيجد مهندسو البرمجيات قوالب API المألوفة وأساليب تطوير التطبيقات فيها. الهدف من Java EE هو تعزيز الاستخدام المتناسق لواجهة برمجة التطبيقات.

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

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

كما سنرى في الفصل 7 ، يشير نهج البرمجة هذا إلى الحاجة إلى الاختبار ، لأنه بالنسبة للمبرمجين ، فإن معظم مواصفات Java EE ليست أكثر من التعليقات التوضيحية.

في جميع أنحاء واجهة برمجة التطبيقات ، تم اعتماد مبدأ تصميم يسمى عكس التحكم (IoC) - وبعبارة أخرى ، "لا تتصل بنا ، سنطلق على أنفسنا". هذا ملحوظ بشكل خاص في دوائر التطبيق ، مثل موارد JAX-RS. يتم وصف طرق الموارد باستخدام التعليقات التوضيحية لطريقة Java ، والتي يتم استدعاؤها لاحقًا بواسطة الحاوية في السياق المناسب. وينطبق الشيء نفسه على حقن التبعية ، حيث عليك اختيار المولدات أو مراعاة المهام الشاملة مثل المعترضات. يمكن لمطوري التطبيقات التركيز على تطبيق المنطق ووصف العلاقات ، تاركين تنفيذ التفاصيل الفنية في الحاوية. مثال آخر ، ليس واضحًا جدًا ، هو وصف تحويل كائنات Java إلى JSON والعكس بالعكس من خلال التعليقات التوضيحية JSON-B. لا يتم تحويل الكائنات فقط في شكل صريح ومبرمج ، ولكن أيضًا بشكل ضمني ، بأسلوب تعريفي.

مبدأ آخر يسمح للمهندسين بتطبيق هذه التكنولوجيا بشكل فعال هو البرمجة بالاتفاق. افتراضيًا ، يحدد Java EE سلوكًا محددًا يطابق معظم سيناريوهات الاستخدام. إذا لم يكن ذلك كافيا أو لا يفي بالمتطلبات ، يمكن إعادة تعريف السلوك ، غالبًا على عدة مستويات.
هناك العديد من الأمثلة على برمجة الاتفاقية. أحدها هو استخدام طرق موارد JAX-RS التي تحول وظيفة Java إلى استجابات HTTP. إذا كان السلوك القياسي لـ JAX-RS فيما يتعلق بالاستجابات لا يفي بالمتطلبات ، يمكنك تطبيق نوع الاستجابة. مثال آخر هو تحديد الكائنات المُدارة ، والتي يتم تنفيذها عادةً باستخدام التعليقات التوضيحية. لتغيير هذا السلوك ، يمكنك استخدام واصف beans.xml XML. من الملائم جدًا للمبرمجين أنه في عالم Java EE الحديث ، يتم تطوير تطبيقات المؤسسة بطريقة براغماتية وعالية الأداء لا تتطلب عادةً مثل هذا الاستخدام المكثف لـ XML كما كان من قبل.

بالنسبة إلى إنتاجية المبرمجين ، هناك مبدأ مهم آخر للتطوير في Java EE هو أن هذا النظام الأساسي يتطلب التكامل في حاوية المعايير المختلفة. نظرًا لأن الحاويات تدعم مجموعة معينة من واجهات برمجة التطبيقات - وإذا كانت Java EE API مدعومة بالكامل ، فإن هذا هو الحال تمامًا - فهي تتطلب أيضًا تطبيقات API لتوفير تكامل سلس لواجهات برمجة التطبيقات الأخرى. ميزة هذا النهج هي القدرة على استخدام موارد JAX-RS لتحويل JSON-B وتقنية التحقق من فول بدون تكوين إضافي صريح ، باستثناء التعليقات التوضيحية. في الأمثلة السابقة ، رأينا كيف يمكن استخدام الوظائف المحددة في المعايير الفردية معًا دون بذل جهود إضافية. هذه واحدة من أكبر مزايا منصة Java EE. تضمن المواصفات العامة مجموعة من المعايير الفردية. يمكن للمبرمجين الاعتماد على بعض الميزات والتطبيق المقدم من خادم التطبيق.

سهل الاستخدام كود عالي الجودة


يتفق المبرمجون عمومًا على أنه يجب عليك السعي لكتابة كود عالي الجودة. ومع ذلك ، ليست كل التقنيات مناسبة تمامًا لذلك.

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

هناك الكثير من المؤلفات حول إعادة هيكلة مستوى الكود. - , , . , . , .

- . , , — , , - . — , , . . , , .

, . , .

, , , . , , - . , , , - , . , . 7.

, . , , , . Java EE : , , . .

. , , , . . 6 , .

. , , , . , . , , . , . . , . - .

عن المؤلف


(Sebastian Daschner) — Java-, , Java (EE). JCP, Java EE, JSR 370 374 . Java Java - Oracle.

IT-, JavaLand, JavaOne Jfokus. JavaOne Rockstar JavaOne 2016. Java (Steve Chin) Java, . JOnsen — Java, .


(Melissa McKay) — 15- , . Java-, . , , .

JCrete () JOnsen . IT- , JavaOne4Kids JCrete4Kids. JavaOne 2017 Denver Java User Group.

»
»
»

20% — Java EE

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


All Articles