فكر برمجي
479 subscribers
459 photos
4 videos
70 files
196 links
#فكر_برمجي
Think_Programmatically
قناة تقنية متخصصة في البرمجة وتطوير المهارات. نوفر شروحات مبسطة، موارد مفيدة، وأفكار ملهمة لتحويل شغفك بالتقنية إلى إبداع.
Download Telegram
#015 — Software Design | تصميم البرمجيات

بعد أن نفهم المشكلة، نجمع المتطلبات، نحلل العمليات، ونحدد المخاطر… يأتي سؤال مهم جدًا:
كيف سنحوّل كل هذا الفهم إلى نظام يمكن بناؤه فعليًا؟
هنا تبدأ مرحلة Software Design — تصميم البرمجيات.
التحليل يخبرنا:
WHAT? — ماذا يجب أن يفعل النظام؟
أما التصميم فيجيب:
HOW? — كيف سنبني النظام ليحقق ذلك؟
ولهذا فالتسلسل الطبيعي ليس:
Requirements → Code

بل:
Requirements → Design → Code
في مرحلة التصميم نبدأ بتحديد مكونات النظام، مسؤولية كل مكوّن، طريقة انتقال البيانات، كيفية التواصل بين الأجزاء، نقاط اتخاذ القرار، والقيود التقنية والأمنية والأدائية التي يجب مراعاتها.
وهنا يظهر مفهومان مهمان:

HLD — High-Level Design ينظر إلى الصورة الكبيرة: Architecture، Services، Database، External Systems، وكيف تتواصل المكونات.

بينما LLD — Low-Level Design يدخل إلى التفاصيل: Classes، Methods، Interfaces، Data Structures، Validation، وError Handling.

لكن التصميم الجيد لا يعني إضافة أكبر عدد ممكن من الطبقات والأنماط والمكونات.
بل يعني أن تعطي كل جزء مسؤولية واضحة.
فبدل أن يكون لدينا Component واحد مسؤول عن Login وOrders وPayments وNotifications وكل شيء آخر، نفصل المسؤوليات بطريقة تجعل النظام أوضح وأسهل في التغيير والاختبار.
وهنا تظهر قاعدة مهمة:

High Cohesion + Low Coupling

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

مثال:
لدينا Requirement تقول:
"يجب أن يستطيع العميل إنشاء طلب ودفع قيمته إلكترونيًا."
قد تتحول في التصميم إلى:

Client App → Order Controller → Order Service → Payment Service → Payment Gateway → Database → Notification Service

متطلب واحد فقط، لكنه يحتاج عدة مكونات تتعاون لتحقيق الهدف.
لكن السؤال الأهم:
كيف أعرف أن تصميمي جيد؟

التصميم الجيد عادةً يكون قابلًا للصيانة Maintainable، وقابلًا للتوسع Scalable، وقابلًا للاختبار Testable، وآمنًا Secure، وفعّالًا Performant، وبسيطًا بالقدر المناسب Simple.
لأن التصميم الجيد لا يحل مشكلة اليوم فقط؛ بل يجعل تغيير النظام غدًا أسهل وأقل تكلفة.

وفي المقابل، هناك أخطاء تصميمية شائعة يجب الحذر منها مثل: Overengineering، Tight Coupling، God Class، Premature Optimization، Ignoring Failure Cases، وDesigning Without Requirements.

لذلك:
Good Design ≠ More Complexity
بل:
Good Design = Right Complexity

لا تجعل الكود هو المكان الذي تكتشف فيه تصميم النظام للمرة الأولى.
Think → Design → Then Code
ويمكن تلخيص الرحلة هكذا:
Clear Requirements + Good Design = Cleaner Code

سؤال للنقاش:
لو كنت تصمم متجرًا إلكترونيًا، هل ستضع Orders وPayments وNotifications داخل Service واحدة، أم ستفصل مسؤولياتها؟ ولماذا؟

المنشور القادم:

#016 — Software Architecture
ما الفرق بين التصميم والمعمارية؟ وكيف نحدد الشكل العام للنظام؟

م. طارق العمري
Software Engineer | Backend Developer

#SoftwareEngineering #SoftwareDesign #SystemDesign #HighLevelDesign #LowLevelDesign #HLD #LLD #SeparationOfConcerns #CleanArchitecture #SoftwareArchitecture #SystemAnalysis #RequirementsEngineering #BackendDevelopment #SoftwareDevelopment #SoftwareEngineer #هندسة_البرمجيات #تصميم_البرمجيات #معمارية_البرمجيات #تطوير_البرمجيات
#016 — Software Architecture | معمارية البرمجيات

قبل أن تبدأ في كتابة التفاصيل الصغيرة داخل النظام، هناك سؤال أهم:
كيف سيبدو النظام كاملًا من الأعلى؟
هنا تأتي Software Architecture — معمارية البرمجيات.
المعمارية لا تهتم فقط بالـClasses أو Methods، بل تحدد الصورة الكبرى للنظام:
كيف نقسمه إلى مكونات؟
كيف تتواصل هذه المكونات؟
أين تُخزن البيانات؟
كيف سنتعامل مع الخدمات الخارجية؟
وكيف نجعل النظام قادرًا على التوسع، وآمنًا، ومستقرًا؟

ببساطة:
Architecture = Big Picture
Design = Details

فمثلًا:
Client → API Gateway → Services → Database
هذا قرار معماري.
أما تحديد:
OrderService
createOrder()
cancelOrder()
getOrder()

فهذه تفاصيل أقرب إلى Software Design.
لكن المعمارية لا تعتمد فقط على الوظائف التي يقدمها النظام.
قد تقول المتطلبات
يجب أن يستطيع المستخدم إنشاء طلب.
لكن ماذا لو كان النظام سيخدم مئات الآلاف من المستخدمين؟
ماذا لو تعطل Server؟
ماذا لو توقفت Payment Gateway؟
ماذا لو كان فقدان عملية دفع واحدة غير مقبول؟
هنا تدخل Quality Attributes:

Scalability — قابلية التوسع
Availability — التوفر
Performance — الأداء
Security — الأمان
Reliability — الموثوقية
Maintainability — قابلية الصيانة
وهذه المتطلبات قد تغيّر Architecture النظام بالكامل.
ومن أكثر القرارات التي يواجهها المطورون:
Monolith أم Microservices؟

لا توجد إجابة واحدة تناسب الجميع.
قد يكون Monolith هو الخيار الأفضل لمشروع صغير أو فريق محدود لأنه أبسط في التطوير والنشر والتشغيل.
بينما قد تكون Microservices مناسبة عندما يكبر النظام، وتحتاج الخدمات إلى التوسع والنشر والعمل باستقلالية.
لكن تذكّر:

Microservices
ليست دائمًا أفضل.
لأنها تضيف تحديات في:
التواصل بين الخدمات، إدارة البيانات الموزعة، المراقبة، الاختبارات، النشر، والتعامل مع الأعطال.
لذلك لا تختَر Architecture لأنها "رائجة" او شائعة.
اخترها لأنها تحل مشكلة حقيقية في مشروعك
المعادلة الأهم:
Requirements + Constraints + Trade-offs → Architecture
ولهذا:
Good Architecture ≠ More Services
بل:
Good Architecture =
Right Decisions for the Context
المهندس الجيد لا يبحث عن أعقد Architecture، بل عن أبسط Architecture تستطيع تحقيق متطلبات النظام اليوم، وتسمح له بالتطور غدًا دون أن تتحول إلى عبء على الفريق.
Think Big → Decide Carefully → Design Clearly → Then Code

سؤال للنقاش:
لو كنت ستبدأ متجرًا إلكترونيًا جديدًا مع فريق صغير، هل ستختار Monolith أم Microservices؟ ولماذا؟

التالي في السلسلة:
#017 — Architectural Styles
Monolith، Layered، Microservices، Event-Driven… وما الفرق بينها ومتى نستخدم كل أسلوب؟
م. طارق العمري
Software Engineer | Backend Developer

#SoftwareEngineering #SoftwareArchitecture #Architecture #SystemDesign #SoftwareDesign #Monolith #Microservices #Scalability #BackendDevelopment #SystemArchitecture #SoftwareDevelopment #SoftwareEngineer #هندسة_البرمجيات #معمارية_البرمجيات #تصميم_الأنظمة #تطوير_البرمجيات
كيف تساعدنا مبادئ مثل SRP و OCP و Dependency Inversion على بناء تصميم مرن، قابل للتوسع والتغيير بكل سهولة؟
م.طارق العمري
Software Engineer| Backend Developer

#SoftwareEngineering #DetailedDesign #SoftwareDesign #SystemDesign #CleanArchitecture #SOLID #BackendDevelopment #CleanCode #SoftwareEngineer #هندسة_البرمجيات #التصميم_التفصيلي #تطوير_البرمجيات
#019 — UI/UX Design | تصميم واجهة وتجربة المستخدم

قد يكون النظام قويًا من ناحية البرمجة، سريعًا، وآمنًا…
لكن إذا لم يعرف المستخدم أين يضغط؟ ماذا يفعل؟ وما الخطوة التالية؟ فالتجربة ما زالت سيئة.
وهنا يأتي دور:
UI/UX Design — تصميم واجهة وتجربة المستخدم

الفرق بينهما بسيط:
UX — User Experience
يركز على كيف تعمل التجربة.
هل الخطوات منطقية؟
هل يصل المستخدم إلى هدفه بسهولة؟
هل توجد خطوات زائدة؟
هل رسائل الخطأ واضحة؟
هل يعرف ماذا يفعل بعد ذلك؟

أما:
UI — User Interface
فيركز على كيف تبدو الواجهة.
الألوان، الخطوط، الأزرار، الأيقونات، المسافات، ترتيب العناصر، والحالات البصرية.

بمعنى مختصر:

UX = How it works
UI = How it looks

لكن التصميم الجيد لا يبدأ بالألوان.
يبدأ بسؤال:

من هو المستخدم؟ وماذا يريد أن ينجز؟
فالمستخدم الذي يدخل تطبيقًا لحجز رحلة لا يريد مشاهدة أجمل Animation…

هدفه غالبًا:
Search → Choose → Book → Pay → Confirm

ولهذا نرسم أولًا:
User Flow
أي المسار الذي سيمر به المستخدم للوصول إلى هدفه.
وكل خطوة إضافية يجب أن نسأل عنها:
هل هي ضرورية فعلًا؟
بعد فهم الرحلة ننتقل إلى:

Sketch → Wireframe → Prototype → Visual UI → Development

وهنا قاعدة مهمة جدًا:

Structure First → Style Later
لأن Wireframe سيئًا بألوان جميلة…
يبقى تجربة سيئة.
ثم يأتي دور Visual Hierarchy.

فنستخدم:

Size للحجم.
Contrast للتباين.
Spacing للمسافات.
Alignment للمحاذاة.
Typography للخطوط.
Color لتوجيه الانتباه.

الهدف ليس أن نجعل كل عنصر بارزًا.
بل أن نجعل المستخدم يعرف:
ما المهم الآن؟ وما الذي يجب أن أفعله بعده؟
ثم نحتاج إلى Design System حتى لا تصبح كل شاشة عالمًا مختلفًا.
نحدد نظامًا موحدًا لـ:

Colors — Typography — Buttons — Inputs — Cards — Icons — Spacing — States

لأن:

Consistency reduces confusion.

لكن هناك نقطة غالبًا ما تُنسى:
لا تصمم Happy Path فقط.
صمّم أيضًا للحالات الإستثنائية:

Loading
Empty State
Validation
Error
Success
Disabled

فالمستخدم لا يحكم على النظام فقط عندما يعمل كل شيء بشكل مثالي…
بل أيضًا عندما تحدث مشكلة.

بدل:
Error 504
الأفضل أن تقول للمستخدم:
تعذر إتمام العملية حاليًا.
لم يتم خصم المبلغ. حاول مرة أخرى.
لأن:

A good UX explains what happened and what to do next.
ويمكن تلخيص رحلة UI/UX هكذا:

Understand Users

Define Goals

Map User Flow

Create Wireframes

Build Prototype

Design Visual UI

Handle All States

Test with Users

Improve

والمعادلة الأهم:
User Needs + Clear Flow + Consistent UI = Better Experience

وفي النهاية، المستخدم لا يهتم بعدد الساعات التي قضيتها في التصميم…
هو يهتم بسؤال واحد:
هل استطعت إنجاز ما أريد بسهولة؟

سؤال للنقاش:

لو كان لديك تطبيق حجز يحتاج 9 خطوات لإتمام الحجز، هل تبدأ أولًا بتغيير الألوان؟
أم تبدأ بتحليل الخطوات نفسها وتقليلها؟

سؤال للبحث (:

(Wireframes & Prototypes)
ما الفرق بين Sketch وWireframe وMockup وPrototype؟ ومتى نستخدم كل واحد؟

م. طارق العمري
Software Engineer | Backend Developer

#UIUX #UIDesign #UXDesign #UserExperience #UserInterface #UserFlow #Wireframe #Prototype #DesignSystem #VisualHierarchy #ProductDesign #Usability #SoftwareEngineering #SoftwareDesign #FrontendDevelopment #SoftwareEngineer #هندسة_البرمجيات #تصميم_واجهات #تجربة_المستخدم #تصميم_البرمجيات
#020 — Architectural Patterns | الأنماط المعمارية

عندما يبدأ المشروع يكبر، تظهر أسئلة مهمة:

كيف نقسم النظام؟
كيف نفصل المسؤوليات؟
كيف نجعل التغيير أسهل؟
وكيف نقلل الترابط بين الأجزاء؟

هنا تأتي Architectural Patterns — الأنماط المعمارية.

الـPattern ليس كودًا جاهزًا، بل هو طريقة مجربة لتنظيم النظام وحل مشاكل معمارية متكررة.

ومن أشهر الأنماط:

Layered Architecture
تقسم النظام إلى طبقات واضحة مثل:

Presentation → Application → Business → Data Access → Database

مناسبة للتطبيقات التقليدية عندما نريد بنية واضحة وسهلة الفهم.

MVC — Model View Controller
يفصل بين:

Model
View
Controller

والهدف هو عدم خلط واجهة المستخدم مع منطق النظام.

Clean Architecture
تضع Business Logic في المركز، وتجعل الاعتمادات تتجه للداخل.

الفكرة المهمة:

> منطق الأعمال يجب ألا يعتمد على Framework أو Database معينة.



Hexagonal Architecture — Ports & Adapters
تعزل النظام عن التقنيات الخارجية من خلال Interfaces واضحة.

مثلًا:

PaymentPort

يمكن تنفيذه لاحقًا بواسطة:

Stripe
PayPal
بوابة دفع محلية

دون تغيير Business Logic.

Event-Driven Architecture
بدل أن تستدعي الخدمات بعضها مباشرة، تتفاعل عبر Events.

مثال:

Order Created

ثم تستجيب:

Payment Service
Notification Service
Inventory Service
Analytics Service

وهذا يقلل الترابط ويساعد على التوسع، لكنه يزيد تحديات مثل Debugging وMonitoring وConsistency.

والسؤال الذي يتكرر دائمًا:

ما أفضل Architectural Pattern؟

الإجابة الصحيحة ليست اسم Pattern معين.

لأن:

لا يوجد Pattern مناسب لكل مشروع.

قد يكون Layered هو الأنسب لمشروع بسيط، بينما مشروع آخر يحتاج Clean Architecture، وآخر يعتمد على Event-Driven، وأحيانًا نستخدم أكثر من Pattern داخل نفس النظام.

لذلك لا تختَر بناءً على الشهرة.

اختَر بناءً على:

Problem + Constraints + Context

ثم:

Right Pattern

القاعدة الأهم:

> Choose based on context, not popularity.



المعمارية الجيدة لا تجعل النظام يعمل اليوم فقط، بل تساعده أن يكون أسهل في الصيانة، الاختبار، التوسع، والتغيير مستقبلًا.

Understand → Compare → Choose → Adapt → Build

سؤال للنقاش:

لديك نظام حجز يعتمد على Payment Gateway وSMS Provider وخدمة خرائط خارجية.
أي Architectural Pattern ستستخدم حتى تستطيع تغيير هذه الخدمات مستقبلًا بأقل تأثير على Business Logic؟

المنشور القادم:

#021 — Clean Architecture
كيف نحمي Business Logic من تغيّر Frameworks وقواعد البيانات والخدمات الخارجية؟

م. طارق العمري
Software Engineer | Backend Developer

#SoftwareEngineering #ArchitecturalPatterns #SoftwareArchitecture #SystemDesign #LayeredArchitecture #MVC #CleanArchitecture #HexagonalArchitecture #EventDrivenArchitecture #BackendDevelopment #SoftwareDesign #Scalability #Maintainability #SoftwareEngineer #هندسة_البرمجيات #الأنماط_المعمارية #معمارية_البرمجيات #تصميم_الأنظمة #تطوير_البرمجيات