في هذه الصفحة
حيث أن الـ 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 اللي هتقعد تحطها في كل مكان.