لذلك ، بعنا العميل منتج برنامج B2B.
في العرض التقديمي ، كان يحب كل شيء ، ولكن أثناء التنفيذ اتضح أن هناك شيئًا ما زال غير مناسب. يمكنك بالطبع أن تقول إنك بحاجة إلى اتباع "أفضل الممارسات" ، وتغيير نفسك إلى منتج ، وليس العكس. قد ينجح هذا إذا كان لديك علامة تجارية قوية (على سبيل المثال ، ثلاثة أحرف كبيرة ، ويمكنك إرسال جميع الأحرف الصغيرة الثلاثة). وإلا ، فسيوضحون لك سريعًا أن العميل حقق كل شيء بفضل عملياته التجارية الفريدة ، ودعونا نغير منتجك بشكل أفضل أو لن ينجح. هناك خيار لرفض والإشارة إلى حقيقة أن التراخيص قد تم شراؤها بالفعل ، وليس هناك مكان للذهاب من الغواصة. لكن في الأسواق الضيقة نسبيا ، لن تنجح هذه الاستراتيجية لفترة طويلة.
لدينا لتعديل.
النهج
هناك عدة طرق أساسية لتكييف المنتج.
وحدة متراصة
يتم إجراء أي تغييرات مباشرةً على الكود المصدر للمنتج ، ولكن يتم تضمينها في خيارات معينة. في مثل هذه المنتجات ، كقاعدة عامة ، هناك أشكال وحشية ذات إعدادات ، والتي من أجل عدم الخلط ، يتم تخصيص أرقامها أو أكوادها. عيب هذا النهج هو أن شفرة المصدر تتحول إلى معكرونة كبيرة ، حيث يوجد العديد من حالات الاستخدام المختلفة بحيث تصبح طويلة ومكلفة للغاية للمحافظة عليها. يتطلب كل خيار لاحق موارد أكثر وأكثر. أداء مثل هذا المنتج يترك أيضا الكثير مما هو مرغوب فيه. وإذا كانت اللغة المكتوبة بالمنتج لا تدعم الممارسات الحديثة مثل الميراث وتعدد الأشكال ، يصبح كل شيء محزنًا للغاية.
نسخة
يتم إعطاء العميل رمز المصدر الكامل للمنتج مع ترخيص لتعديله. غالبًا ما يخبر هؤلاء البائعون العميل أنهم لن يقوموا بتكييف المنتج بأنفسهم ، لأنه سيكون مكلفًا للغاية (سيكون من المربح أن يبيع البائع تراخيص أكثر من الاتصال بالخدمات). لكن لديهم جهات خارجية مألوفة تستعين بموظفين غير مكلفين وعالي الجودة نسبياً في مكان ما في دول ثالثة على استعداد لمساعدتهم. هناك أيضًا حالات يتم فيها إجراء التحسينات مباشرةً من قِبل متخصصي العميل (إذا كان لديهم وحدات توظيف). في مثل هذه الحالات ، يتم أخذ الكود المصدري كنقطة انطلاق ، ولن يكون للشفرة المعدلة أي اتصال بما كان في الأصل ، وستعيش حياته الخاصة. في هذه الحالة ، يمكنك إزالة ما لا يقل عن نصف المنتج الأصلي واستبداله بمنطقك الخاص.
الاندماج
هذا هو مزيج من أول نهجين. ولكن في ذلك ، يجب على المطور الذي يصحح الكود أن يتذكر دائمًا: "دمج قادم". عند إصدار إصدار جديد من المنتج المصدر ، سيتعين عليه في معظم الحالات دمج التغييرات يدويًا في المصدر والرمز المعدل. المشكلة هي أنه في أي صراع ، سيكون من الضروري أن نتذكر سبب إجراء بعض التغييرات ، وقد يكون هذا منذ وقت طويل جدًا. وإذا تم تنفيذ إعادة هيكلة الكود في المنتج الأصلي (على سبيل المثال ، تمت إعادة ترتيب كتل الأكواد ببساطة) ، فسيستغرق الدمج وقتًا طويلاً للغاية.
نمطية
منطقيا النهج الأكثر صحة. لا يخضع تغيير التعليمات البرمجية المصدر للمنتج في هذه الحالة ، وتتم إضافة وحدات إضافية تعمل على توسيع الوظيفة. ومع ذلك ، من أجل تنفيذ مثل هذا المخطط ، يجب أن يكون لدى المنتج بنية تسمح بتوسيعه بهذه الطريقة.
وصف
مع مزيد من الأمثلة
سأعرض كيف نوسع المنتجات المطورة على أساس منصة
lsFusion المفتوحة
والمجانية .
العنصر الأساسي للنظام هو الوحدة. الوحدة النمطية هي ملف نصي بملحق
lsf ، والذي يحتوي على
كود lsFusion . في كل وحدة ، يتم الإعلان عن منطق المجال (الوظائف والفئات والإجراءات) ومنطق العرض (النماذج ، المستكشف). تقع الوحدات ، كقاعدة عامة ، في الأدلة ، مقسومة على مبدأ منطقي. المنتج عبارة عن مجموعة من الوحدات النمطية التي تقوم بتنفيذ وظائفها وتخزينها في مستودع منفصل.
الوحدات مترابطة. تعتمد إحدى الوحدات على وحدة أخرى إذا كانت تستخدم منطقها (على سبيل المثال ، تشير إلى الخصائص أو النماذج).
عندما يظهر عميل جديد ، يتم تشغيل مستودع منفصل (Git أو Subversion) له ، حيث سيتم إنشاء الوحدات النمطية مع التعديلات اللازمة. يعرّف هذا المستودع الوحدة النمطية المسماة أعلى. عند بدء تشغيل الخادم ، سيتم توصيل هذه الوحدات فقط ، والتي يعتمد عليها بشكل مباشر أو مؤقت من خلال وحدات أخرى. يسمح هذا للعميل باستخدام ليس كل وظائف المنتج ، ولكن فقط الجزء الذي يحتاجه.
تقوم Jenkins بإنشاء مهمة تجمع بين وحدات المنتج والوحدة العميلة في ملف جرة واحد ، يتم تثبيته بعد ذلك على خادم إنتاج أو اختبار.
النظر في العديد من الحالات الرئيسية للتحسينات التي تنشأ في الممارسة العملية:
افترض أن لدينا وحدة
ترتيب في المنتج ، والتي تصف منطق الطلب القياسي:
يريد العميل
X إضافة نسبة خصم وسعر خصم لخط الطلب.
أولاً ، يتم إنشاء وحدة
OrderX جديدة في مستودع العملاء. في رأسها ، يتم وضع تبعية على وحدة
الطلب الأصلية:
في هذه الوحدة ، نعلن عن خصائص جديدة سيتم بموجبها إنشاء حقول إضافية في الجداول ، وإضافتها إلى النموذج:
نجعل السعر المخفض غير متاح للتسجيل. سيتم احتسابها كحدث منفصل عندما يتغير السعر الأولي أو نسبة الخصم:
أنت الآن بحاجة إلى تغيير حساب المبلغ في سطر الطلب (يجب أن يأخذ في الاعتبار سعر الخصم الذي تم إنشاؤه حديثًا). للقيام بذلك ، نقوم عادةً بإنشاء "نقاط دخول" معينة حيث يمكن للوحدات النمطية الأخرى إدراج سلوكها. بدلاً من الإعلان الأولي عن خاصية المبلغ في وحدة الطلبات ، نستخدم ما يلي:
في هذه الحالة ، سيتم جمع قيمة خاصية
المبلغ في حالة واحدة ، حيث يمكن أن تنتشر عبر وحدات مختلفة. من المضمون أنه إذا كانت الوحدة (أ) تعتمد على الوحدة (ب) ، فسوف تعمل جميع وحدات الوحدة "ب" في وقت لاحق (WHEN) من الوحدة (أ). ولحساب
المبلغ المخصوم بشكل صحيح ، يضاف الإعلان التالي إلى وحدة
OrderX :
نتيجة لذلك ، إذا تم تعيين خصم ، فسيخضع المبلغ له ، وإلا التعبير الأصلي.
لنفترض أن العميل يريد إضافة قيود على ألا يتجاوز مبلغ الطلب مبلغًا محددًا معينًا. في نفس الوحدة النمطية
OrderX ، نعلن عن خاصية يتم فيها تخزين قيمة القيد ، وإضافتها إلى نموذج
الخيارات القياسية (يمكنك إنشاء نموذج منفصل مع الإعدادات إذا كنت ترغب في ذلك):
بعد ذلك ، في نفس الوحدة النمطية ، نعلن عن مقدار الطلب ، ونعرضه في النموذج ونضيف حدًا لزيادة الفائض:
وأخيرًا ، طلب العميل تغيير تصميم نموذج تحرير الطلب قليلاً: لجعل رأس الطلب على يسار الخطوط بفاصل ، وكذلك دائمًا عرض الأسعار بدقة من حرفين. للقيام بذلك ، تتم إضافة التعليمات البرمجية التالية إلى الوحدة النمطية الخاصة به ، والذي يغير التصميم القياسي الذي تم إنشاؤه لنموذج الطلب:
نتيجة لذلك ، حصلنا على وحدتي
طلب (في المنتج) ، يتم فيها تنفيذ منطق الطلب الأساسي ، و
OrderX (لدى العميل) ، حيث يتم تنفيذ منطق الخصم الضروري:
تجدر الإشارة إلى أنه يمكن استدعاء وحدة
OrderX OrderDiscount ونقلها مباشرة إلى المنتج. ثم ، إذا لزم الأمر ، سيكون من الممكن لكل عميل توصيل الوظيفة بسهولة مع خصومات.
هذا أبعد ما يكون عن كل الاحتمالات التي يوفرها النظام الأساسي لتوسيع الوظيفة في الوحدات الفردية. على سبيل المثال ، باستخدام الوراثة ، يمكنك تطبيق منطق
السجل بطريقة معيارية.
إذا كانت هناك أي تغييرات في الكود المصدر للمنتج تتعارض مع الكود في الوحدة التابعة ، فسيتم إنشاء خطأ عند بدء تشغيل الخادم. على سبيل المثال ، إذا تم
حذف نموذج
الطلب في وحدة
الطلبات ،
فسيحدث خطأ عند بدء تشغيل نموذج
الطلب في وحدة
OrderX . أيضا ، سيتم تسليط الضوء على الخطأ في
IDE . بالإضافة إلى ذلك ، فإن IDE لديه وظيفة للبحث عن جميع الأخطاء في المشروع ، مما يسمح لك بتحديد جميع المشاكل التي حدثت بسبب تحديث إصدار المنتج.
في الممارسة العملية ، لدينا جميع المستودعات (للمنتج وجميع العملاء) متصلة بالمشروع نفسه ، لذلك نقوم بإعادة تشكيل المنتج بهدوء ، مع تغيير المنطق في وحدات العميل حيث يتم استخدامه.
استنتاج
توفر هذه البنية المجهرية الفوائد التالية:
- كل عميل متصل فقط بالوظائف التي يحتاجها . يحتوي هيكل قاعدة البيانات الخاصة به على تلك الحقول التي يستخدمها فقط. لا تحتوي واجهة الحل النهائي على عناصر غير ضرورية. لا يقوم الخادم والعميل بإجراء أحداث وشيكات غير ضرورية.
- المرونة في التغييرات في الوظائف الأساسية . مباشرة في مشروع العميل ، يمكنك إجراء تغييرات على أي شكل من أشكال المنتج تمامًا ، وإضافة أحداث ، وكائنات وخصائص جديدة ، وإجراءات ، وتغيير التصميم وغير ذلك الكثير.
- تسريع عملية تقديم التحسينات الجديدة المطلوبة من قبل العميل . مع كل طلب تغيير ، لن تحتاج إلى التفكير في كيفية تأثيره على العملاء الآخرين. نتيجة لهذا ، يمكن إجراء العديد من التحسينات وتشغيلها في أسرع وقت ممكن (غالبًا في غضون ساعات قليلة).
- مخطط أكثر ملاءمة لتوسيع وظائف المنتج . أولاً ، يمكن تضمين أي وظيفة لعميل معين يكون جاهزًا لتجربتها ، وبعد ذلك ، في حالة التنفيذ الناجح ، يتم نقل الوحدات بالكامل إلى مستودع المنتج.
- قانون قاعدة الاستقلال . نظرًا لأن العديد من التحسينات يتم توفيرها بموجب عقود خدمة العملاء ، من الناحية الرسمية ، فإن الكود بأكمله الذي تم تطويره بموجب هذه العقود يخص العميل. مع هذا المخطط ، يتم ضمان الفصل الكامل لرمز المنتج الذي ينتمي إلى البائع عن الرمز الذي يملكه العميل. بناءً على الطلب ، نقوم بنقل المستودع إلى خادم العميل ، حيث يمكنه تعديل الوظيفة التي يحتاجها مع مطوريه. بالإضافة إلى ذلك ، إذا كان المورد يرخص لوحدات المنتج الفردية ، فلن يكون لدى العميل الكود المصدري للوحدات النمطية التي لا يوجد ترخيص لها. وبالتالي ، ليس لديه القدرة التقنية على توصيلهم بشكل مستقل في انتهاك لشروط الترخيص.
غالبًا ما يطلق على نظام الوحدات الموضحة أعلاه بمساعدة الملحقات في البرمجة
mix in . على سبيل المثال ، قدمت Microsoft Dynamics مؤخرًا مفهوم الامتداد ، والذي يسمح لك أيضًا بتوسيع الوحدات الأساسية. ومع ذلك ، هناك حاجة إلى الكثير من البرمجة ذات المستوى الأدنى ، والتي بدورها تتطلب مؤهلات أعلى للمطورين. بالإضافة إلى ذلك ، على عكس lsFusion ، يتطلب توسيع الأحداث والقيود "نقاط الدخول" الأولية للمنتج من أجل الاستفادة من هذا.
في الوقت الحالي ، وفقًا للمخطط الموضح أعلاه ، ندعم
وننفذ نظام ERP لتجارة التجزئة مع أكثر من 30 عميلًا كبيرًا نسبيًا ، والذي يتكون من أكثر من 1000 وحدة. بين العملاء هناك شبكات سلع استهلاكية ، بالإضافة إلى الصيدليات ومحلات الملابس ومتاجر سلاسل دروجي وتجار الجملة وغيرها. في المنتج ، على التوالي ، هناك فئات منفصلة من الوحدات النمطية المرتبطة بالاعتماد على الصناعة والعمليات التجارية المستخدمة.