تصميم من أجل التطور

التصميم التطوري هو المفتاح للابتكار المستمر

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

لا تقتصر هذه المشكلة على التطبيقات المتجانسة. يمكن تحلل التطبيق إلى خدمات، ولكن لا يزال يعرض نوع الاقتران المحكم الذي يترك النظام صارمًا وهشًا. ولكن عندما يتم تصميم الخدمات للتطور، يمكن للفرق الابتكار وتقديم ميزات جديدة باستمرار.

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

التوصيات

فرض تماسك عالٍ واقتران فضفاض. تكون الخدمة متماسكة إذا كانت توفر وظائف تنتمي منطقياً إلى بعضها البعض. تقترن الخدمات بشكل غير محكم إذا كان بإمكانك تغيير إحدى الخدمات دون تغيير الخدمة الأخرى. التماسك العالي يعني بشكل عام أن التغييرات في دالة واحدة تتطلب تغييرات في الوظائف الأخرى ذات الصلة، حيث توجد جميع الدالات ذات الصلة في خدمة واحدة. إذا وجدت أن تحديث خدمة يتطلب تحديثات منسقة لخدمات أخرى، فقد يكون ذلك علامة على أن خدماتك غير متماسكة. أحد أهداف التصميم المستند إلى المجال (DDD) هو تحديد تلك الحدود.

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

استخدام المراسلة غير المتزامنة. المراسلة غير المتزامنة هي طريقة لفصل منتِّج الرسالة عن المستهلك. لا يعتمد المنتِّج على استجابة المستهلك للرسالة أو اتخاذ أي إجراء معين. باستخدام بنية pub/sub، قد لا يعرف المنتِّج حتى من يستهلك الرسالة. يمكن أن تستهلك الخدمات الجديدة بسهولة الرسائل دون أي تعديلات على المنتِّج.

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

كشف الواجهات المفتوحة. تجنب إنشاء طبقات ترجمة مخصصة تقع بين الخدمات. بدلاً من ذلك، يجب أن تعرض الخدمة واجهة برمجة تطبيقات بعقد API محدد جيداً. يجب إصدار واجهة برمجة التطبيقات، بحيث يمكنك تطوير واجهة برمجة التطبيقات مع الحفاظ على التوافق مع الإصدارات السابقة. وبهذه الطريقة، يمكنك تحديث خدمة دون تنسيق التحديثات لجميع الخدمات الأولية التي تعتمد عليها. يجب أن تعرض الخدمات المواجهة العامة واجهة برمجة تطبيقات RESTful عبر HTTP. قد تستخدم خدمات الواجهة الخلفية بروتوكول مراسلة على غرار استدعاء إجراء عن بُعد لأسباب تتعلق بالأداء.

التصميم والاختبار مقابل عقود الخدمة. عندما تعرض الخدمات واجهات برمجة التطبيقات المحددة جيداً، يمكنك التطوير والاختبار مقابل واجهات برمجة التطبيقات هذه. وبهذه الطريقة، يمكنك تطوير واختبار خدمة فردية دون تدوير جميع خدماتها التابعة. (بالطبع، لا يزال بإمكانك إجراء اختبار التكامل والتحميل مقابل الخدمات الحقيقية.)

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

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

توزيع الخدمات بشكل مستقل. عندما يتمكن فريق DevOps من توزيع خدمة واحدة بشكل مستقل عن الخدمات الأخرى في التطبيق، يمكن أن تحدث التحديثات بسرعة وأمان أكبر. يمكن طرح إصلاحات الأخطاء والميزات الجديدة بوتيرة أكثر انتظاماً. تصميم كل من التطبيق وعملية الإصدار لدعم التحديثات المستقلة.