Orderإحنا مش بنقول row في جدول إحنا بنقول: Order = طلب حقيقي في البزنس عنده:Quantity
Amountومحمي بقواعد (Assertions) مينفعش يبقى مش تمام
الـ Repository مجرد طبقة وسيطة بين عالمين:
👈 Domain → Objects، Rules، Business Logic
👈 Database → Tables، Rows، Arrays، SQL----------------------------------------------------------------------------------------------------------------------
كده إحنا واقفين فين؟
إحنا وصلنا للحالة دي:

و بعد كدا عملنا كدا
save وفي الكنترولر ارجع للريبو باترن الفصل الي فات
كده تمام… شكليًا.
لكن ❗
لسه مفيش Implementation وهنا بيبدأ فصل 2.5
يعني إيه: Mapping entity data to table columns؟
👈 تحويل بيانات الـ Entity من Object إلى Array مناسب للداتابيز
ليييييييييييه
👈 علشان الدومين بيتكلم Object
👈 الداتابيز بتفهم Array
👈 أنا كلمت البزنس بلغته دلوقتي محتاج أكلم الداتابيز بلغتها
وهنا بيظهر دور الـ Repository
👈 يا Repo خد الـ Object وترجمه لـ Array علشان أقدر أكلّم SQL
ال Mapping شكله عامل إزاي؟
👈 زي الترجمة بالظبط cat => قطة
هنا ف ال Implementation بقا اي بيقابل اي
👈 property في الـ Object يقابلها column في الجدول
Entity (Order) Table (orders)
emailAddress quantity
pricePerUnitInCents price
quantityOrdered quantity
وده اسمه Mapping
المشكلة التقنية الحقيقية
الواقع التقني بيقول الدومين شغال بـ Objects SQL شغال بـ Tables / Columns / Rows
SQL محتاج

لكن أنا معايا:

-------------------------------------------------------------------------------------------------
وده اسمه رسميًا Object–Relational Impedance Mismatc و هوه عدم توافق طبيعي بين عالمين مختلفين
و هنستخدم له Mapping الي انتا لسه قارءه فوق علشان نحلها
-------------------------------------------------------------------------------------------------
ازااااي بقا
اولا هيه المشكلة بتظهر فين؟

جوه الـ Repository

السؤال الكبير و المهم جدااااااااااااااااااااااااااااااا
أجيب الـ $data ده منين؟
أنا معايا: Order Object
والـ SQL عايز: columns => values
Listing 2.10 – أول محاولة حقيقية

-------------------------------------------------------------------
كل حاجة واضحة… إلا حتة واحدة $data ييجي منين؟
-------------------------------------------------------------------
في حلّين أساسيين
1️⃣ ORM
2️⃣ Manual Mapping
2.5.1
Using an ORM
Object Relational Mapper يعني إيه؟
أداة تاخد Object تحوّله SQL وترجعه Object
من غير ما تكتب:( mapping بعدين insert او update)
هنستخدم Doctrine ORM
👈 يقرأ الـ Entity
👈 يعرف الـ properties
👈 يعرف اسم الجدول
👈 يعرف الأعمدة
👈 يبني SQL
👈 يحفظ
👈 ويرجع ID

EntityManager يعني إيه؟
هو العقل المدبر يتتبع الـ objects يعرف مين جديد مين اتعدل ينفذ SQL في الآخر
Listing 2.11 – الـ Annotations

دي مش SQL دي Metadata عبارة عن تعليمات بتقول:
ده Entity يتحفظ في جدول اسمه orders الـ property دي تتحفظ في column
مميزات ORM
كود أقل
سرعة في البداية
Tools جاهزة
عيوب ORM
Magic كتير
Debug صعب
مفاجآت أداء
abstraction زيادة
--------------------------------------------------------------------------------------------------
2.5.2 Manual Mapping (المهم بقى)
طب ما نكتب المابنج بإيدنا من غير ORM من غير سحر كل حاجة واضحة
الاختيار الأول – Entity تعمل المابنج (Listing 2.14)
هنخش جوه ال entity و هتكون كدا

وفي الريبو:

المميزات => هنشرحها تحت كمل المقال للاخر
Encapsulation محفوظ
Entity متحكمة في نفسها
Refactoring أسهل
العيب
Entity عرفت أسماء الأعمدة
الاختيار التاني – Repo تعمل المابنج (Listing 2.15)

العيب الكبير =>هنشرحها تحت كمل المقال للاخر
كسر Encapsulation
Repository عرف تفاصيل داخلية
أي تغيير يكسر الاتنين
--------------------------------------------------------------------------------------------------
Entity من حقها تعرف إزاي تتحفظ Mapping مش dependency تشغيلية
mappedData() شغالة من غير DB Core Code لسه Core
--------------------------------------------------------------------------------------------------
يعني إيه Encapsulation أصلًا؟
Encapsulation = التغليف
يعني اي
يعني الكلاس مسؤول عن نفسه هو الوحيد اللي يعرف
تفاصيله الداخلية و أسماء الـ properties و ترتيبهم و منطق التعامل معاهم
واللي برّه الكلاس
يتعامل معاه عن طريق methods واضحة من غير ما يعرف هو متكوّن من إيه جوه
---------------------------------------------------------------------------------------
Encapsulation مش معناها ”مفيش حد يشوف حاجة“
Encapsulation معناها ”إنت اللي تقرر إيه يطلع وإيه يفضل مستخبي“
--------------------------------------------------------------------------------------
إحنا عندنا Entity عارفة كل ال props بتاعتها و دا الي مميزها
الـ properties privateمحدش برّه الكلاس يقدر يلمسهم
ده أول مستوى Encapsulation
Encapsulation الحقيقي مش بس private
Encapsulation = مين مسيطر على الداتا؟
--------------------------------------------------------------------------------------
اما لما خليت الEntity تطلع كل ال props خام كدا و ال Repo هوه الي يعمل ال map ع الداتا عنده
دا الي انا عملته ب الظبط الOrder قال خد كل اللي جوايا زي ما هومن غير فلترة
من غير تحكم
و زي موضحنا فوق الريبو خد الداتا و عمل map ليه بقا ال Encapsulation اتكسر
علشان الـ Repository عرف
👈 اسم الـ property
👈 شكل الـ Entity من جوه
👈 ترتيب الداتا
👈 إن email اسمها emailAddress
👈 إن quantity اسمها quantityOrdered
----------------------------------------------------------------------------------
Repository بقى معتمد على التفاصيل الداخلية
Order بقى مش حر يغيّر نفسه
----------------------------------------------------------------------------------
لو قررت تغيّر:
private string $emailAddress
الي
private string $email
هيحصل إيه؟
👈 Repository يبوظ
👈 مفيش Error واضح
👈 Bug صامت
👈 كسر في السيستم
وده اسمه Encapsulation Leak
يعني التغليف اتفتح، واللي برّه بقى شايف جوه.
ليه ده خطر؟
علشان أي refactor صغير في الـ Entity يكسر الـ Repository من غير ما تحس ومن غير ما الكود يقولك وده عكس هدف الدومين تمامًا.
سؤال طب ما Entity كده عرفت أسماء columns دا كدا مش ده كسر؟
وجود أسماء أعمدة ≠ كسر Encapsulation
ليه؟
علشان Entity ما طلّعتش internals و ما كشفتش properties و قدّمت API واضح و هوه لما عملنا الmappedData
الفرق الجوهري هنا مين متحكم و لو عملت Refactor جوه ال Entity هتأثر ع الي برا ولا لأ ؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟
internalData → Repository
mappedData → Entity
----------------------------------------------------------------------------------
الخلاصة اللي تمسكها بإيدك
كسر Encapsulation يحصل لما
👈 Repository يعرف أسماء properties
👈 Repository يعتمد على شكل الكلاس من جوه
👈 Repository يعمل mapping بنفسه
Encapsulation محفوظ لما:
👈 Entity تتحكم في اللي يطلع
👈 Repository يتعامل مع method مش internals
👈 التغيير جوه Entity ما يكسرش اللي برّه
الجملة الذهبية بقى 🧠
Encapsulation مش إنك تخبّي الداتا
Encapsulation إنك تتحكم في مين يشوف إيه
وده بالظبط اللي حصل في:
mappedData() ✅واتفشل في:
internalData()