December 15, 2025 (4mo ago)

دليل المطور لمبدأ عزل الواجهات

اتقن مبدأ عزل الواجهات (ISP). تعلّم مفاهيم SOLID مع أمثلة عملية باستخدام TypeScript وReact لكتابة شيفرة أنظف وأسهل في الصيانة.

← Back to blog
Cover Image for دليل المطور لمبدأ عزل الواجهات

اتقن مبدأ عزل الواجهات (ISP). تعلّم مفاهيم SOLID مع أمثلة عملية باستخدام TypeScript وReact لكتابة شيفرة أنظف وأسهل في الصيانة.

مبدأ عزل الواجهات (ISP) - TypeScript & React

ملخص: اتقن مبدأ عزل الواجهات (ISP). تعرّف على مفاهيم SOLID مع أمثلة عملية باستخدام TypeScript وReact لكتابة شيفرة أنظف وأسهل في الصيانة.

مقدمة

ينص مبدأ عزل الواجهات (ISP) على أنه لا ينبغي أن يُجبر أي عميل على الاعتماد على طرق لا يستخدمها. عند تطبيقه بشكل جيد، يقلل ISP من الترابط، يبسط الاختبار، ويجعل الشيفرة أسهل في التغيير والفهم. يوضح هذا الدليل أمثلة عملية في TypeScript وReact يمكنك استخدامها اليوم لجعل قاعدة الشيفرة أكثر تجزئة وقابلة للصيانة.


ما هو مبدأ عزل الواجهات؟

مخطط يقارن أداة متعددة الوظائف كواجهة منتفخة بمفك واحد كواجهة مركزة.

تخيل جهاز تحكم بالتلفاز يحتوي على 90 زرًا بينما أنت تحتاج فقط إلى زر "تشغيل". هذا الإحباط يعكس البرمجيات حيث تُجبر فئة على تنفيذ واجهة كبيرة وغير مركزة. يشجع ISP، وهو الحرف "I" في SOLID، على تصميم واجهات صغيرة ومخصصة للعملاء بدلًا من عقدة واحدة تؤدي كل شيء. هذا يتجنب نمط المضاد "الواجهة السمينة" أو "واجهة الإله" ويؤدي إلى أنظمة أوضح وأكثر مرونة.1

لماذا تضر الواجهات السمينة

  • تبعيات غير ضرورية: تصبح الفئات مترابطة بطرق لا تستدعيها، مما يجعل التغييرات غير ذات صلة محفوفة بالمخاطر.
  • حمل معرفي زائد: يجب على المطورين فحص طرق غير ذات صلة للعثور على ما يحتاجونه.
  • تنفيذات فارغة: تُجبر الفئات على عمل طرق مؤقتة غير مستخدمة، ما يضيف كودًا روتينيًا.

الفكرة الأساسية بسيطة: أعطِ كل عميل ما يحتاجه بالضبط، ولا شيء أكثر. هذا يجعل المكونات أسهل للفهم والاختبار والتطور.

الواجهات الأحادية مقابل الواجهات المعزولة

مقارنة جنبًا إلى جنب توضح المقايضات.

AttributeMonolithic Interface (Anti-pattern)Segregated Interfaces (ISP)
CouplingHigh; classes depend on methods they don’t use.Low; clients depend only on needed methods.
CohesionLow; unrelated methods grouped together.High; each interface serves a single role.
MaintainabilityDifficult; small changes ripple widely.Easier; changes affect only relevant clients.
TestabilityHard; mocks become large and brittle.Easier; smaller interfaces are simple to mock.

اختيار ISP يساعد قاعدة الشيفرة لديك على البقاء قابلة للتكيف مع إضافة الميزات أو إعادة هيكلة الكود.

ISP في الممارسة: الانتهاكات الشائعة

الانتهاكات لا تكسر التطبيق لكنها تجعل الصيانة مؤلمة. ابحث عن فئات مليئة بالطرق الفارغة أو مكونات تحتوي على عدد كبير من الخصائص الاختيارية.

مخطط مفاهيمي لـ 'واجهة الإله' يُظهر أدوار المسؤول والمشاهد تتفاعل مع أيقونات مختلفة.

"واجهة الإله" كلاسيكية في TypeScript

// ANTI-PATTERN: A "fat interface" that violates ISP interface IUserActions { createUser(data: UserData): void; editUser(id: string, data: UserData): void; deleteUser(id: string): void; viewUserProfile(id: string): UserProfile; changeUserRole(id: string, newRole: Role): void; publishArticle(article: Article): void; approveComment(commentId: string): void; }

سيحتوي كلاس Viewer المجبور على تنفيذ هذا على طرق بلا معنى أو طرق تطرِح أخطاء. هذا يزيد من تكلفة الصيانة والمخاطر.

خصائص مكونات منتفخة في React

عرض أمامي شائع هو وجود مكوّن عام Card مع العديد من الخصائص الاختيارية. هذا يخلق غموضًا حول مجموعات الخصائص الصالحة ويجبر على عرض شرطيات معقدة.

// ANTI-PATTERN: A bloated props interface interface CardProps { title: string; description?: string; imageUrl?: string; imageAltText?: string; videoUrl?: string; authorName?: string; authorAvatarUrl?: string; publicationDate?: string; articleLink?: string; onClick?: () => void; // ... and many more optional props }

تُهيئ هذه الأنماط المضادة خطوات إعادة الهيكلة الواردة أدناه.

كيفية إعادة الهيكلة: من واجهات أحادية إلى واجهات معزولة

إعادة الهيكلة نحو ISP لا تتطلب إعادة كتابة كبيرة. استخدم تغييرات صغيرة ومركزة لتقسيم المسؤوليات وتوضيح العقود.

مخطط مرسوم بخط اليد يُظهر إعادة هيكلة 'I user Actions' إلى واجهات محددة لـ 'Editor' و 'Viewer'.

1) إصلاح "واجهة الإله" في TypeScript

الخطوة A: تحديد أدوار العملاء. على سبيل المثال: المسؤولون، المحررون، المشاهدون.

الخطوة B: إنشاء واجهات مخصصة لكل دور.

// GOOD: Focused interfaces interface IViewerActions { viewUserProfile(id: string): UserProfile; }

interface IEditorActions { publishArticle(article: Article): void; approveComment(commentId: string): void; }

interface IAdminActions { createUser(data: UserData): void; editUser(id: string, data: UserData): void; deleteUser(id: string): void; changeUserRole(id: string, newRole: Role): void; }

الخطوة C: تنفيذ ما هو ضروري فقط.

class Viewer implements IViewerActions { viewUserProfile(id: string): UserProfile { console.log(Fetching profile for user ${id}...); // ... fetch and return profile } }

يمكن للمسؤول تنفيذ عدة واجهات حسب الحاجة. هذا الفصل يقلل من عمليات إعادة الترجمة غير الضرورية ويوضح من يمتلك كل قدرة.

2) إعادة هيكلة خصائص React المنتفخة باستخدام اتحادات مميزة (discriminated unions)

استخدم اتحادات مميزة حتى يكون لكل متغير من المكوّن عقد واضح. أنواع الاتحاد والمميز في TypeScript مثالية لذلك.2

// GOOD: Base props type BaseCardProps = { title: string; onClick?: () => void; };

// GOOD: Specific variants type ImageCardProps = BaseCardProps & { cardType: 'image'; imageUrl: string; imageAltText: string; };

type ArticleCardProps = BaseCardProps & { cardType: 'article'; description: string; authorName: string; articleLink: string; };

type CardProps = ImageCardProps | ArticleCardProps;

باستخدام هذا النمط، يفرض المحرر فورًا مجموعات الخصائص الصالحة ويمنع التراكيب غير الصالحة.

تدقيق وتطبيق ISP عبر فريقك

إجراء إصلاح لمرة واحدة مفيد، لكن تضمين ISP في ممارسات الفريق يوفر قيمة دائمة. اجمع معايير تدقيق واضحة مع فحوص آلية للحفاظ على صحة الواجهات.

معايير تدقيق واضحة

ضع قائمة مرجعية مشتركة لاكتشاف انتهاكات ISP أثناء المراجعات. أمثلة على الإشارات الحمراء:

  • واجهات تحتوي على العديد من الطرق (تستحق الفحص عندما تتجاوز الخمس إلى السبع طرق).
  • طرق فارغة أو مؤقتة على تنفيذات.
  • أسماء واجهات غامضة تستخدم كلمات مثل "Manager" أو "Handler".
  • خصائص مكونات بها الكثير من الحقول الاختيارية.

النهج الشائع هو اقتران المراجعة اليدوية بأدوات آلية لتوسيع تطبيق القواعد.

أتمتة التطبيق

ESLint والقواعد المخصصة قوية لاكتشاف الأنماط البسيطة، مثل خصائص منتفخة أو فئات تنفذ واجهات وتترك طرقًا غير منفذة.3 يمكن لمساعدي الترميز المعتمدين على الذكاء الاصطناعي أيضًا المساعدة في تمييز روائح التصميم عند مطالبتهم بمراجعة الواجهات والتنفيذات.4

كلا الفحصين الآلي والبشري ذو قيمة: الأدوات توفر الاتساق والسرعة، بينما يلتقط البشر السياق ونية العمل.

AspectManual AuditingAutomated Enforcement
AccuracyHigh for contextual issuesConsistent for defined rules
ConsistencyVaries by reviewerSame rules applied everywhere
SpeedSlow for large codebasesFast, integrates with IDE/CI

استخدم كلاهما: دع الأتمتة تتعامل مع الفحوص الروتينية وركز المراجعين على قرارات التصميم الدقيقة. هذا الاقتران يُحسّن سير عمل TDD لأن الواجهات الأصغر أبسط في المحاكاة والاختبار — مما يدعم دورات Red-Green-Refactor أسرع واختبارات وحدة أوضح.5

ISP والتطوير المدفوع بالذكاء الاصطناعي

مع تزايد اندماج الذكاء الاصطناعي في سير عمل التطوير، تساعد الواجهات الواضحة أدوات مثل نماذج نمط GPT على فهم الكود بشكل أفضل. تقلل الواجهات الصغيرة والمركزة الغموض وتحسّن جودة الشيفرة المولدة، واقتراحات إعادة الهيكلة الآلية، والتوثيق.4

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

أسئلة شائعة حول ISP

هل يعني ISP أن كل طريقة تحتاج إلى واجهة خاصة بها؟

لا. الهدف ليس إنشاء واجهات ذات طريقة واحدة في كل مكان. اجمع الطرق التي تُستخدم دائمًا معًا من قِبل نفس العميل. الهدف هو واجهات مركزة ومتجانسة، وليس تفتيتًا مفرطًا.

ما الفرق بين ISP ومبدأ المسؤولية الواحدة (SRP)؟

ينطبق SRP على الفئات ويقول أن للفئة سبب واحد للتغيير. يطبق ISP على الواجهات ويقول إن العملاء لا ينبغي أن يعتمدوا على طرق لا يستخدمونها. يمكنك اتباع SRP ومع ذلك تنتهك ISP إذا نفذت الفئة واجهة منتفخة.

متى يكون من المقبول تجاهل ISP؟

عادةً عندما لا يمكنك تغيير الواجهة — مكتبات الطرف الثالث أو واجهات برمجة تطبيقات قديمة لا تملكها. أيضًا، إذا احتاج كل عميل حقًا إلى كل الطرق، فقد تكون الواجهة الأكبر متماسكة ومقبولة.


قائمة فحص سريعة لإعادة الهيكلة

  • حدد الأدوار والعملاء لكل واجهة.
  • قسم الواجهات الكبيرة إلى عقود مخصصة لكل دور.
  • استخدم اتحادات TypeScript المميزة لخصائص المكونات المتغيرية.2
  • أضف قواعد لنتقاط واجهات أو خصائص كبيرة الحجم.3
  • اجمع بين الفحوص الآلية ومراجعة الكود لاتخاذ قرارات دقيقة.

ثلاثة أسئلة وجيابات مختصرة (استفسارات شائعة للمطورين)

Q: كيف أكتشف انتهاك ISP بسرعة؟

A: ابحث عن واجهات ذات طرق كثيرة غير مرتبطة، فئات بها تنفيذات فارغة أو تطرح أخطاء، أو مكونات بها عشرات الخصائص الاختيارية. هذه إشارات قوية على أن العقدة يجب أن تُقسَّم.

Q: ما أسرع طريقة لإصلاح "الواجهة السمينة"؟

A: حدد أدوار العملاء المميزة، أنشئ واجهات مركزة لكل دور، وحدّث التنفيذات لتنفيذ ما تحتاجه فقط. قم بالتغيير تدريجيًا لتجنب المخاطر.

Q: كيف أمنع تراجعات ISP في قاعدة شيفرة متنامية؟

A: أضف قواعد lint وفحوص CI لاكتشاف الواجهات الكبيرة وأضف قائمة مراجعة لتصميم الواجهات. اجمع الأتمتة مع تدقيق يدوي دوري.


في Clean Code Guy، نساعد الفرق على تطبيق مبادئ مثل ISP لبناء قواعد شيفرة قابلة للصيانة وجاهزة للذكاء الاصطناعي. احصل على تدقيق مجاني لقاعدة الشيفرة لاكتشاف المشكلات المخفية وتحسين القابلية للصيانة على المدى الطويل.

1.
Robert C. Martin ("Uncle Bob"), SOLID principles overview. [https://blog.cleancoder.com/]
2.
TypeScript handbook — Discriminated unions and advanced types. [https://www.typescriptlang.org/docs/handbook/2/advanced-types.html#discriminated-unions]
3.
ESLint documentation and guides for custom rules. [https://eslint.org/docs/latest/]
4.
GitHub Copilot and AI coding assistants — examples and guidance. [https://github.com/features/copilot]
5.
Martin Fowler — Refactoring and testing practices. [https://martinfowler.com/]
← Back to blog
🙋🏻‍♂️

الذكاء الاصطناعي يكتب الكود.
أنت تجعله يدوم.

في عصر تسريع الذكاء الاصطناعي، الكود النظيف ليس مجرد ممارسة جيدة — إنه الفرق بين الأنظمة التي تتوسع وقواعد الكود التي تنهار تحت وزنها.

دليل المطور لمبدأ عزل الواجهات | Clean Code Guy