Full Guide Into Optionals in Java

حيث أن الـ Java من لغات البرمجة الرائدة واللي بتشتهر بقوتها ومرونتها ومستمرة في سعيها لتحسين تجربة المبرمجين وانها تخلي الـ Code أكثر اتقان، ومن ضمن المميزات الكتيرة اللي ضافتها وخصوصًا في الـ Java 8 هي الـ Optional.
Full Guide Into Optionals in Java
Full Guide Into Optionals in Java

في هذه الصفحة

حيث أن الـ Java من لغات البرمجة الرائدة واللي بتشتهر بقوتها ومرونتها ومستمرة في سعيها لتحسين تجربة المبرمجين وانها تخلي الـ Code أكثر اتقان، ومن ضمن المميزات الكتيرة اللي ضافتها وخصوصًا في الـ Java 8 هي الـ Optional.

Optional Type

الـ Optional هي Type جديد ظهر لأول مرة في الـ Java 8 واللي كان هدفه الأساسي انه يمثل هل الـ Value موجودة ولا لا ؟ بمعنى تاني الـ Optional Object ده ممكن يكون شايل جواه Non-Nullable Value ووقتها هيكون بيمثل فيه Value Present أو شايل جواه Nullable Value ووقتها هيكون بيمثل Empty Value. 

بشكل تاني ممكن نعتبر الـ Optional ده Wrapper أو Container بيشيل جواه الـ Value وبيقدملك مميزات قوية تقدر تتعامل بيها مع الـ Value دي بشكل سهل و Readable من غير تعقيدات سواء كانت Non-Nullable يعني Present أو Nullable بمعنى انه Empty.

طب ايه شكل الـ Optional ؟

public class Main {

    public static void main(String[] args) {
        Optional<ArticleDto> articleDtoOptional = Optional.ofNullable(getArticleById(UUID.randomUUID().toString()));
        System.out.println(articleDtoOptional.isPresent()); // false

        // Throws NullPointerException & Compiler Requires NonNull Value
        Optional<ArticleDto> article = Optional.of(getArticleById(UUID.randomUUID().toString()));
        System.out.println(article.isEmpty());

        Optional<String> authorName = Optional.of("Mahmoud Youssef");
        System.out.println(authorName.isPresent()); // true
        System.out.println(authorName.isEmpty()); // false
    }

    private static ArticleDto getArticleById(String articleId) {
        return null;
    }
}

الـ Optional ليها كذا طريقة عشان تعرفها ، اما من خلال Optional.of واللي بتاخد جواها قيمة غير Nullable وده لإنها بتـ Throw NullPointerException في الـ RunTime وفي الـ Compile Time بتحتاج Non-Null ، يا اما Optional.ofNullable واللي ممكن تاخد جواها قيمة Nullable.

أو من خلال استخدام الـ Declarative Programming Paradigm من خلال الـ Streams واللي بتتيح أكتر من Function بترجع Optional Object زي انك مثلا تدور في List من المقالات وتقول انا عاوز أول مقال بيحقق الشرط ده ويا اما المقال هيبقى موجود يا اما لا .. وهي دي ببساطة فكرة الـ Optional هي جواه Value يا لا. 

public class EqraatechClient {
    private List<ArticleDto> articles = List.of(
            new ArticleDto(UUID.randomUUID().toString(), "Recursion Deep Dive",
                    "Ahmed Anwar", "https://eqraatech.com/recursion-deep-dive"),
            new ArticleDto(UUID.randomUUID().toString(), "Artificial Neural Networks",
                    "Ahmed Mahmoud", "https://eqraatech.com/artificial-neural-networks"),
            new ArticleDto(UUID.randomUUID().toString(), "Records in C#",
                    "Mohamed Magdi", "https://eqraatech.com/records-in-c#"),
            new ArticleDto(UUID.randomUUID().toString(), "Rate Limiting In a Nutshell",
                    "Alaa Elkazaz", "https://eqraatech.com/rate-limiting-in-a-nutshell"),
            new ArticleDto(UUID.randomUUID().toString(), "Java Optional Full Guide",
                    "Mahmoud Youssef", "https://eqraatech.com/java-optional-full-guide")
    );

    public Optional<ArticleDto> getArticleById(String uuid) {
        return articles.stream()
                .filter(article -> article.uuid().equalsIgnoreCase(uuid))
                .findFirst();
    }
}

Copy

بكده عرفنا شكل الـ Optional وعرفنا ممكن نشوفها ازاي في الـ Code بمقدمة بسيطة، وعرفنا انها Wrapper بيشيل جواه Object أو لا. تعالوا نشوف باه مدى قوة الـ Optional في الـ Code Readability والـ Clean Code.

Optional Features

شوفنا في الأمثلة السابقة ان عندنا isEmpty و isPresent ودول بيمثلوا اذا كان الـ Optional شايل جواه Null يعني Empty ولا جواه قيمة فعلية ووقتها Present.

1- ifPresnetOrElse

عشان نفهم أهمية الـ Optional ومدى قوتها في التطبيق العملي ليها, خلونا نشوف المثال ده: 

public class ArticleService {

    private final EqraatechClient eqraatechClient;

    public ArticleService(EqraatechClient eqraatechClient) {
        this.eqraatechClient = eqraatechClient;
    }

    // without optional
    public void sendNotificationsAboutMetaDataUpdates(String articleId) {
        ArticleMetaDataDto articleMetaDataDto = eqraatechClient.getArticleMetaDataByArticleId(articleId);
        if (articleMetaDataDto == null) {
            System.out.println("There is no metadata created for this article yet!");
            return;
        }
        System.out.println("Sending email about changes to owner...");
    }

    // with optional
    public void sendNotificationsAboutMetaDataUpdatesWithOptional4(String articleId) {
        eqraatechClient.getArticleMetaDataByArticleIdWithOptional(articleId)
                .ifPresentOrElse(articleMetaDataDto -> System.out.println("Sending email about changes to owner..."), () -> System.out.println("There is no metadata created for this article yet!"));
    }

}

في المثال اللي فات ده احنا كنا بنستخدم الـ EqraatechClient عشان نبعت Request ونـ Fetch Article MetaData ، وبنحاول نشوف لو كانت موجودة، ده معناه اننا عاوزين نبعت Email للـ Owner ولو مش موجودة فهنبعت Logs أو نعمل أي Logic تاني مختلف. 

لو بصينا على الـ Optional هنلاقي انها Readable أكتر ومش محتاج كل شوية اعمل Null Checks لاني ممكن انساها .. واللي هتخلي الكود طويل على الفاضي. 

ده كان استخدام بسيط جدًا للـ Optional واللي ممكن تعتمد عليه دايما بعد كده بدل الـ If Conditions اللي هتقعد تحطها في كل مكان.

هذا المقال مخصص للأعضاء فقط

اشترك الآن بنشرة اقرأ-تِك الأسبوعية

لا تدع أي شيء يفوتك. واحصل على أحدث المقالات المميزة مباشرة إلى بريدك الإلكتروني وبشكل مجاني!