JavaRush /مدونة جافا /Random-AR /استراحة القهوة رقم 161. كيفية التعامل مع Null في Java باس...

استراحة القهوة رقم 161. كيفية التعامل مع Null في Java باستخدام اختياري

نشرت في المجموعة
المصدر: متوسط ​​ستساعدك هذه المقالة على فهم الغرض من الخيار الاختياري بشكل أفضل عند العمل باستخدام كود Java. استراحة القهوة رقم 161.  كيفية التعامل مع Null في Java باستخدام اختياري - 1عندما بدأت العمل باستخدام كود Java لأول مرة، نُصحت كثيرًا باستخدام الاختياري. ولكن في ذلك الوقت لم يكن لدي فهم يذكر لماذا كان استخدام الاختياري أفضل من تنفيذ معالجة القيم الخالية. في هذه المقالة، أريد أن أشارككم لماذا أعتقد أنه يجب علينا جميعًا استخدام الاختياري أكثر، وكيفية تجنب الإفراط في اختيار التعليمات البرمجية الخاصة بك، الأمر الذي يضر بجودة التعليمات البرمجية.

ما هو اختياري؟

يتم استخدام المعلمة الاختيارية لحمل الكائنات وتمكين المراجع الخالية من التعامل معها بواسطة واجهات برمجة التطبيقات المختلفة. دعونا نلقي نظرة على مقتطف الكود:
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
لدينا مثيل Coffee حيث نحصل على كمية من السكر من مثيل كائن Sugar . إذا افترضنا أن قيمة الكمية لم يتم تعيينها مطلقًا في مُنشئ القهوة ، فإن Coffee.getSugar().getQuantity() ستُرجع NullPointerException . بالطبع، يمكننا دائمًا استخدام عمليات التحقق القديمة الجيدة من القيمة الفارغة لإصلاح المشكلة.
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
الآن يبدو أن كل شيء على ما يرام. ولكن عند كتابة كود Java، من الأفضل أن نتجنب تنفيذ عمليات التحقق من القيمة الفارغة . دعونا نرى كيف يمكن القيام بذلك باستخدام اختياري.

كيفية إنشاء اختياري

هناك ثلاث طرق لإنشاء كائنات اختيارية:
  • of(قيمة T) — إنشاء كائن اختياري غير فارغ. انتبه إلى أن استخدام of() للإشارة إلى كائن فارغ سيؤدي إلى ظهور NullPointerException .

  • ofNullable(قيمة T) - ينشئ قيمة اختيارية لكائن يمكن أن يكون خاليًا.

  • ()empty - ينشئ مثيلًا اختياريًا يمثل مرجعًا إلى null .

// пример использования Optional.of(T Value)
String name = "foo";
Optional<String> stringExample = Optional.of(name)
// пример использования Optional.ofNullable(T Value)
Integer age = null;
Optional<Integer> integerExample= Optional.ofNullable(age)
// пример использования Optional.empty()
Optional<Object> emptyExample = Optional.empty();
لذلك لديك كائن اختياري. الآن دعونا نلقي نظرة على الطريقتين الرئيسيتين للاختياري:
  • isPresent() - تخبرك هذه الطريقة ما إذا كان الكائن الاختياري يحتوي على قيمة غير فارغة.

  • get() - يسترد قيمة الاختياري بالقيمة الحالية. انتبه إلى أن استدعاء get() على خيار اختياري فارغ سيؤدي إلى NullPointerException .

يرجى ملاحظة أنه إذا كنت تستخدم get() و isPresent() فقط عند العمل مع الاختياري، فستفقد الكثير! لفهم هذا، دعونا الآن نعيد كتابة المثال أعلاه باستخدام الاختياري.

تحسين التحقق من القيمة الخالية مع الاختياري

فكيف يمكننا تحسين الكود أعلاه؟ باستخدام الخيار الاختياري، يمكننا فهم وجود كائن باستخدام isPresent() واسترجاعه باستخدام get() . لنبدأ بتعبئة نتيجة Coffee.getSugar() مع اختياري واستخدام طريقة isPresent() . سيساعدنا هذا في تحديد ما إذا كان getSugar() يُرجع قيمة فارغة.
Coffee coffee = new Coffee();
Optional<String> sugar = Optional.ofNullable(coffee.getSugar());
int quantity = 0;
if (sugar.isPresent()) {
  Sugar sugar = sugar.get();
  int quantity = sugar.getQuantity();
}
بالنظر إلى هذا المثال، يبدو أن تعبئة نتيجة Coffee.getSugar() في اختياري لا يضيف أي قيمة، بل يزيد من المتاعب. يمكننا تحسين النتيجة باستخدام ما أعتبره وظائفي المفضلة من الفئة الاختيارية:
  • Map(Function<? super T,? Extends U> Mapper) - يقوم بتعيين القيمة الموجودة في الاختياري للوظيفة المتوفرة. إذا كانت المعلمة الاختيارية فارغة، فستُرجع الخريطة() اختياريًا.فارغة() .

  • orElse(Tother) هو إصدار "خاص" من طريقة get() . يمكنه الحصول على القيمة الموجودة في الاختياري. ومع ذلك، في حالة وجود خيار اختياري فارغ، فسيؤدي ذلك إلى إرجاع القيمة التي تم تمريرها إلى طريقة orElse() .

ستقوم الطريقة بإرجاع القيمة الموجودة في المثيل الاختياري. ولكن إذا كانت المعلمة الاختيارية فارغة، مما يعني أنها لا تحتوي على أي قيمة، فسيقوم orElse() بإرجاع القيمة التي تم تمريرها إلى توقيع الطريقة الخاص بها، والتي تُعرف بالقيمة الافتراضية.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
هذا رائع حقًا - على الأقل أعتقد ذلك. الآن، إذا كنا لا نريد إرجاع القيمة الافتراضية في حالة القيمة الفارغة، فسنحتاج إلى طرح نوع من الاستثناء. orElseThrow(Supplier<? Extends X> ExceptionSupplier) يُرجع القيمة الموجودة في المعلمات الاختيارية، أو يطرح استثناءً إذا كان الاختياري فارغًا.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
كما ترون، يوفر الاختياري العديد من المزايا:
  • ملخصات الشيكات فارغة
  • يوفر واجهة برمجة التطبيقات (API) للتعامل مع الكائنات الفارغة
  • يسمح للنهج التصريحي بالتعبير عما يتم تحقيقه

كيف تصبح فعالاً مع الاختياري

في عملي، أستخدم اختياري كنوع إرجاع عندما تتمكن إحدى الطرق من إرجاع حالة "لا توجد نتيجة". عادةً ما أستخدمه عند تحديد أنواع الإرجاع للطرق.
Optional<Coffee> findByName(String name) {
   ...
}
في بعض الأحيان هذا ليس ضروريا. على سبيل المثال، إذا كان لدي طريقة تُرجع int ، مثل getQuantity() في فئة Sugar ، فقد تُرجع الطريقة 0 إذا كانت النتيجة فارغة لتمثل "بلا كمية". الآن، بعد أن عرفنا ذلك، يمكننا أن نعتقد أنه يمكن تمثيل معلمة السكر في فئة القهوة على أنها اختيارية. للوهلة الأولى، تبدو هذه فكرة جيدة لأنه من الناحية النظرية، لا يلزم وجود السكر في القهوة. ومع ذلك، هذا هو المكان الذي أود أن أتناوله عند عدم استخدام الاختياري. يجب أن نتجنب استخدام الاختياري في السيناريوهات التالية:
  • كأنواع معلمات لـ POJOs ، مثل DTOs . الاختيارات غير قابلة للتسلسل، لذا فإن استخدامها في POJO يعطل إمكانية تسلسل الكائن.

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

  • لتمثيل كائن المجموعة المفقود. يمكن أن تكون المجموعات فارغة، لذلك يجب استخدام مجموعة فارغة ، مثل مجموعة أو قائمة فارغة ، لتمثيل مجموعة بدون قيم.

خاتمة

أصبح الاختياري إضافة قوية لمكتبة جافا. فهو يوفر طريقة للتعامل مع الكائنات التي قد لا تكون موجودة. ولذلك ينبغي مراعاتها عند تطوير الأساليب دون الوقوع في فخ التعاطي. نعم، يمكنك كتابة تعليمات برمجية رائعة تنفذ عمليات فحص فارغة ومعالجة فارغة، لكن مجتمع Java يفضل استخدام الخيار الاختياري. إنه ينقل بشكل فعال كيفية التعامل مع القيم المفقودة، وهو أسهل بكثير في القراءة من عمليات التحقق الخالية الفوضوية، وينتج عنه عدد أقل من الأخطاء في التعليمات البرمجية الخاصة بك على المدى الطويل.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION