في البداية أردت أن أكتب تعليقًا على مقال " لقد عانيت من هياكل مروعة في C # لمدة عشر سنوات ... " ، لكنني أدركت شيئين:
- هناك الكثير من الأفكار لمشاركتها.
- بالنسبة لمثل هذا المجلد ، فإن تنسيق التعليق غير مناسب سواء للكتابة أو للقراءة.
- لقد كنت أقرأ Habr لفترة طويلة ، وأحيانًا أعلق ، لكنني لم أكتب مقالات مطلقًا.
- أنا لست جيدًا في القوائم المرقمة.
إخلاء المسؤولية: أنا لا أنتقد @ pnovikov أو فكرته بشكل عام. النص ذو جودة عالية (أشعر أنني محرر ذو خبرة) ، أشارك بعض أفكاري. هناك العديد من الأبنية ، لكن هذا جيد (نعم ، يبدو وكأنه عنوان فيلم كوري).
ومع ذلك ، دعنا نذهب بالترتيب. أولاً ، رأيي في ما يؤثر على العمارة ، ثم حول النقاط الخلافية في المقال حول "إصلاح البنى". سأخبرك أيضًا بما يناسبنا جيدًا - ربما يكون مفيدًا لشخص ما.
وبالطبع كل ما يقال هنا هو رأي شخصي مبني على تجربتي والتحيزات المعرفية.
عن رأيي
غالبًا ما أتخذ قرارات معمارية. مرة واحدة - كبيرة ، مرة - صغيرة. من حين لآخر أتوصل إلى الهندسة المعمارية من الصفر. حسنًا ، كما لو كان من الصفر - بالتأكيد تم اختراع كل شيء من قبلنا ، لكننا لا نعرف شيئًا ، لذلك علينا أن نخترع. وليس من باب الحب لبناء الدراجات (دعنا نقول ، ليس فقط بدافع الحب لها) ، ولكن لأنه في بعض المهام لم يكن هناك حل جاهز يناسب جميع المعايير.
لماذا أعتقد أن البنى المختلفة تمامًا لها الحق في الوجود؟ قد يتكهن المرء بأن البرمجة هي فن وليست حرفة ، لكنني لن أفعل ذلك. رأيي: مرة فن ، مرة واحدة حرفة. لاعلاقة بذاك. الشيء الرئيسي هو أن المهام مختلفة. و الناس. للتوضيح ، المهام هي متطلبات العمل.
إذا أصبحت مهماتي في يوم من الأيام كما هي ، فسأكتب أو أطلب من شخص ما أن يكتب شبكة عصبية (أو ربما يكون النص كافياً) التي ستحل محلني. وسأفعل شيئًا أقل كآبة بنفسي. حتى لا تأتي نهاية العالم الخاصة بي ، وآمل ذلك ، دعونا نفكر في كيفية تأثير المهام والظروف الأخرى على مجموعة متنوعة من البنى. TL & DR؛ - متنوع .
الأداء مقابل قابلية التوسع
ربما يكون هذا هو السبب الأكثر صحة لتغيير البنية. ما لم يكن ، بالطبع ، من الأسهل تكييف العمارة القديمة مع المتطلبات الجديدة. ولكن هنا من الصعب أن تخبر بإيجاز عن شيء مفيد.
توقيت
لنفترض أن المصطلحات (لقد تأكدت مرتين من أنني كتبت بحرف "o") ضيقة للغاية. ثم ليس لدينا وقت للاختيار ، ناهيك عن ابتكار الهندسة المعمارية - خذ أدوات مألوفة وحفر. ولكن هناك فارق بسيط - في بعض الأحيان لا يمكن تنفيذ المشاريع المعقدة في الوقت المحدد إلا من خلال تطبيق (وربما اختراع) شيء جديد بشكل أساسي. قد يقول شخص ما أن دعوة العميل إلى الحمام هي تقنية قديمة ، لكنني أتحدث عن الهندسة المعمارية الآن ...
عندما يكون التوقيت مناسبًا - غالبًا ما يتضح أنه موقف متناقض - يبدو أنه يمكنك الخروج بشيء جديد ، ولكن لماذا؟ صحيح أن الكثيرين يستسلمون بنجاح لإغراء القيام بمشروع آخر أكثر احتراقًا وتقليل الوضع إلى السابق.
في عملي ، نادرًا ما يؤدي التوقيت إلى ثورات في الهندسة المعمارية ، لكنه يحدث. وهذا شيء عظيم.
سرعة التطوير والجودة
يحدث ذلك - يلاحظ الفريق (أو شخص من الإدارة) أن سرعة التطوير قد تباطأت ، أو أن الكثير من الأخطاء قد تجاوزت التكرار. غالبًا ما يتم إلقاء اللوم على "الهندسة الخاطئة" في هذا الأمر. في بعض الأحيان - بجدارة. في كثير من الأحيان - تمامًا مثل المتهم الأكثر ملاءمة (خاصةً إذا لم يكن لدى الفريق "والدها").
من حيث المبدأ ، في بعض الحالات يعود الأمر كله إلى عامل الوقت. وفي حالات أخرى - للصيانة ، حولها لاحقًا.
قابلية الصيانة
موضوع غامض. لأن كل شيء ذاتي للغاية ويعتمد كثيرًا على ما. على سبيل المثال - من الفريق ، ولغة البرمجة ، والعمليات في الشركة ، وعدد التعديلات لمختلف العملاء. دعنا نتحدث عن العامل الأخير ، يبدو لي الأكثر إثارة للاهتمام.
الآن قمت بعمل مشروع مخصص. بنجاح ، وفي الوقت المحدد وفي حدود الميزانية ، يشعر العميل بالرضا عن كل شيء. كان لدي هذا أيضا. الآن تنظر إلى ما استخدمته وتفكر فيه - إذن ها هو - منجم ذهب! نحن الآن نستخدم كل هذه التطورات ، وسننشئ بسرعة منتج B2B واحدًا ، و ... في البداية كل شيء على ما يرام. تم تصنيع المنتج وبيعه عدة مرات. استأجرت المزيد من البائعين والمطورين ("المزيد من الذهب مطلوب"). العملاء راضون ، يدفعون مقابل الدعم ، تحدث مبيعات جديدة ...
ثم قال أحد العملاء بصوت بشري - "كنت سأفعل هذا الشيء بطريقة مختلفة تمامًا - ما هي تكلفة ذلك؟" حسنًا ، فكر فقط - ألصق بعض أدوات if'chik برمز مختلف (دعنا نقول ، لم يكن هناك وقت لبرغي DI) ، ما السوء الذي يمكن أن يحدث؟
وفي المرة الأولى ، لن يحدث شيء سيء حقًا. لن أنصح حتى في مثل هذه الحالة بتسييج شيء خاص. يعد تعقيد العمارة قبل الأوان بمثابة تحسين سابق لأوانه. ولكن عندما يحدث ذلك في المرة الثانية والثالثة ، فهذا سبب لتذكر أشياء مثل DI ونمط "الإستراتيجية" و Feature Toggle وغيرها من الأشياء المشابهة لهم. ولفترة من الوقت ، سوف يساعد.
ثم يأتي اليوم الذي تنظر فيه إلى إعدادات المشروع (فقط بضع مئات من الخيارات) لمنصة اختبار محددة ... تذكر كيف تحسب عدد المجموعات وتفكر - كيف ، والدتك ، يمكن اختبار هذا؟ من الواضح أنه في عالم مثالي يكون هذا أمرًا بسيطًا - ففي النهاية ، يتم تصميم كل ميزة وتنفيذها بطريقة لا تؤثر على الأخرى بأي شكل من الأشكال ، وإذا حدث ذلك ، فسيتم توفير كل هذا ، وبشكل عام ، لم يرتكب مطورونا أي أخطاء.
بالطبع ، قمت بتكثيف الألوان - يمكنك إبراز بعض مجموعات الميزات التي يستخدمها عملاء حقيقيون ، وكتابة المزيد من الاختبارات (كيف وأيها موضوع لمحادثة أخرى) وتبسيط المهمة قليلاً. لكن فكر في الأمر - يجب اختبار كل إصدار رئيسي لجميع العملاء. اسمحوا لي أن أذكرك بأن هذه ليست B2C ، حيث يمكنك أن تقول "طرح ميزة لـ 5٪ من المستخدمين وجمع التعليقات" - بالنسبة إلى B2B ، يمكنك البدء في جمع التعليقات من المحاكم ...
الحلول؟ على سبيل المثال ، قسّم المنتج إلى وحدات ذات دورة حياة منفصلة (دون أن تنسى اختبار تفاعلها). سيؤدي ذلك إلى تقليل تعقيد الصيانة ، على الرغم من أنه سيعقد التطوير. والآن أنا لا أتحدث عن الموضوع الخصب لـ holivars "monolith vs. الخدمات المصغرة "- في وحدة متراصة ، يمكنك أيضًا ترتيب مماثل (على الرغم من أنه أكثر تعقيدًا ، في رأيي).
وتذكروا ، من وجهة نظر براغماتية ، في كل مرحلة ، كان لدينا بنية جيدة.
ولماذا كل هذا؟
لا أريد أن أتعبك (وأنا) من خلال سرد الأسباب الأخرى للتغييرات في الهندسة المعمارية. دعنا نتفق الآن على أن البنى تميل إلى التغيير بمرور الوقت ، اعتمادًا على العديد من العوامل. هذا يعني أن التصميم المثالي الذي يحل "حسنًا ، كل المشاكل" غير موجود.
إذا لم أقنعك بذلك حتى الآن ، فابحث عن مجموعة متنوعة من لغات البرمجة وأطر العمل (فقط ليس في الواجهة الأمامية - لا تفتح هذا الموضوع). إذا قال أحدهم أن هذا أمر سيء ، أقترح إجراء تجربة فكرية - تخيل عالماً توجد فيه لغة برمجة واحدة محددة. بشرط واحد مهم - أنت لا تحب ذلك. على سبيل المثال ، لأنك لم تستخدمها مطلقًا ، ولم تكن تنوي ذلك مطلقًا.
وأعترف أن هناك سببًا وجيهًا آخر - الخروج بشيء جديد ، وتحسين بعض المعايير ، واللعب بالتنازلات - إنه أمر ممتع للغاية. الآن وقد اتفقنا جميعًا (أليس كذلك؟) على أن التنوع في الهندسة المعمارية على ما يرام ...
مناقشة المقالة حول "إصلاح البنى"
ماذا عن IoC؟
حول IoC أوافق على أن أقمشة القدم لها مكان في الجيش ، والوحدات النمطية جيدة للجميع. ولكن إليك الباقي ...
إذا استمعت بالطبع إلى بعض المدافعين عن "الشفرة النظيفة" ، فيمكنك حينئذٍ ترميز جبل من الخدمات ، كل منها سيكون لها في المتوسط طريقة ونصف ، وفي الطريقة - سطرين ونصف. لكن لماذا؟ بصراحة ، هل تريد بالتأكيد اتباع المبادئ التي ستساعدك على التعامل مع المشكلات غير المحتملة في المستقبل البعيد ، ولكن تشويه حتى المنطق البسيط عبر عشرات الملفات؟ أم أنه يكفي لك أن تكتب كود عمل لائق الآن؟
بالمناسبة ، أنا الآن أعمل على وحدة سيتم استخدامها بالتأكيد في منتجات مختلفة ، وعلى الأرجح ، سوف "تضبط" بنشاط. لذلك أحاول ألا أكون "ضحلة". لا تؤتي ثمارها. على الرغم من أنني أستخدم التطبيق الوحيد للواجهات أكثر من المعتاد.
لذا ، إذا كانت لدينا وحدات ولسنا "تافهين" ، فمن أين تأتي مشكلات أداء IoC أو "أغطية أقدام تكوينات IoC" غير المدعومة؟ أنا لم أجد.
ومع ذلك ، سأوضح ظروف العمل لدينا:
- وحداتنا ليست هي تلك التي "يتم توفيرها من خلال أي إطار عمل IoC تقريبًا" ، ولكن "الوحدات النمطية المباشرة" - التي تتواصل مع بعضها البعض عن بُعد عبر واجهة برمجة التطبيقات (أحيانًا ، لأسباب تتعلق بالأداء ، يمكنك وضعها في عملية واحدة ، لكن مخطط العمل لن يتغير).
- يتم استخدام IoC بشكل بسيط قدر الإمكان وبسيط قدر الإمكان - يتم تعليق التبعيات في معلمات المُنشئ.
- نعم ، لدينا الآن بنية الخدمات المصغرة ، لكننا هنا نحاول ألا نكون صغيرين جدًا.
نصيحة: يمكن الاحتفاظ بالواجهات في نفس ملف الفصل - فهي مناسبة (إذا كنت تستخدم ، بالطبع ، IDE عاديًا وليس مفكرة). أقوم ببعض الاستثناءات عندما تنمو الواجهات (أو التعليقات عليها). لكن هذا كله ذوق بالطبع.
ما الخطأ في ORM ولماذا الوصول المباشر إلى قاعدة البيانات؟
نعم ، سأقول بنفسي ما هو الخطأ - العديد منهم بعيدون جدًا عن SQL. لكن ليس كل. لذلك ، بدلاً من "التحمل بينما يزيل O / RM 3000 عنصر" أو الخروج بآخر آخر ، ابحث عن الشيء الذي يناسبك.
نصيحة: جرب LINQ to DB . إنه متوازن بشكل جيد ، وهناك طرق تحديث / حذف لأسطر متعددة. فقط بعناية - الادمان. نعم ، لا توجد ميزات EF ومفهوم مختلف قليلاً ، لكنني أحببت EF أكثر من ذلك بكثير.
بالمناسبة ، من الجيد أن هذا تطور لمواطنينا. إيغور تكاتشيف - احترام (لم أجده في حبري).
محدث: RouRلوحظ في التعليقات أن هناك امتدادًا لـ EF Core يسمح بالعمليات الجماعية. لن أتخلى عن LINQ لـ DB على أي حال ، لأنه جيد .
ما الخطأ في اختبارات قاعدة البيانات؟
نعم ، ستكون أبطأ من البيانات الموجودة في الذاكرة. هل هي قاتلة؟ لا بالطبع لأ. كيفية حل هذه المشكلة؟ فيما يلي وصفتان من الأفضل استخدامهما في نفس الوقت.
الوصفة رقم 1. تأخذ مطورًا رائعًا يحب القيام بكل أنواع الأشياء الرائعة وتناقش معه كيفية حل هذه المشكلة بشكل جميل. أنا محظوظ لأنفرضحل المشكلة بشكل أسرع مما ظهرت عليه (لا أتذكر حتى ما إذا كنا ناقشناها أم لا). كيف؟ صنع (في يوم واحد على ما يبدو) مصنع اختبار لـ ORM ، والذي يستبدل المجموعة الفرعية الرئيسية من العمليات بمصفوفات الوصول.
مثالي لاختبارات الوحدة البسيطة. خيار بديل هو استخدام SQLite أو شيء مشابه بدلاً من قواعد البيانات "الكبيرة".
تعليق بواسطة فرض: . -, , ORM, , SQL . -, , , , , .. . .
رقم الوصفة 2. أفضل اختبار سيناريوهات الأعمال على قواعد بيانات حقيقية. وإذا أعلن المشروع عن القدرة على دعم نظم إدارة قواعد بيانات متعددة ، يتم إجراء اختبارات للعديد من نظم إدارة قواعد البيانات. لماذا ا؟ انه سهل. في العبارة "لا أريد اختبار خادم قاعدة البيانات" ، للأسف ، هناك استبدال للمفاهيم. أنا ، كما تعلم ، لا أختبر ما إذا كان الانضمام إلى الأعمال أو الطلب.
أنا أختبر الكود الخاص بي بالعمل مع DB. ومع العلم أنه حتى الإصدارات المختلفة من نفس نظام إدارة قواعد البيانات يمكن أن تنتج نتائج مختلفة عن نفس الاستعلامات ( إثبات ) ، أريد التحقق من السيناريوهات الرئيسية بالضبط في قواعد البيانات التي سيعمل بها هذا الرمز.
عادةً ما تبدو مثل هذه الاختبارات بالنسبة لي كما يلي:
- بالنسبة لمجموعة من الاختبارات (Fixture) ، يتم إنشاؤها من البداية وفقًا لبيانات تعريف قاعدة البيانات. إذا لزم الأمر ، يتم ملء الكتب المرجعية اللازمة.
- يضيف كل برنامج نصي البيانات الضرورية بنفسه أثناء المقطع (يقوم المستخدمون بذلك أيضًا). ليس الأمر كذلك في اختبارات الأداء ، لكن هذه قصة مختلفة تمامًا ...
- بعد كل اختبار ، يتم حذف البيانات الزائدة (باستثناء الكتب المرجعية).
نصيحة: إذا تم إجراء مثل هذه الاختبارات نيابة عنك بموضوعية لفترة طويلة (وليس لأنه حان الوقت لتحسين الاستعلامات في قاعدة البيانات) ، فقم بإنشاء بنية تقوم بتشغيلها كثيرًا (فئات اختبار أو مشروع منفصل للمساعدة). خلاف ذلك ، لن يرغب المطورون في تشغيل الباقي - اختبارات سريعة بأنفسهم.
المعاملات والبريد الإلكتروني
سأضيف فقط إلى القصة "سقطت المعاملة في قاعدة البيانات لسبب ما ، وذهب البريد الإلكتروني". وما هي المتعة عندما تنتظر معاملة ما خادم بريد لا يمكن الوصول إليه ، وتهزم النظام بأكمله بسبب بعض الإشعارات التي يرسلها المستخدم بعد ذلك إلى السلة دون قراءة ...
صحيح ، لقد اعتقدت دائمًا أن يونيو فقط
النتيجة
بشكل عام ، إذا لم يكن لدى @ pnovikov خطط لغزو العالم بمساعدة
أنا بالكاد سأستخدم الإطار المقترح. السبب بسيط - لدينا بالفعل بنية مثالية ...
ملاحظة: إذا كانت لديك رغبة في مناقشة شيء ما في التعليقات ، فسأكون سعيدًا بالمشاركة فيه.