الموضوع 70 من 91· هندسة البرمجيات والتسليم الرقمي

التخصيص الدقيق للتكاليف إلى السنت

تقسيم مبلغ إجمالي — دعم مشترك، فاتورة بنية تحتية، رقم أثر ميزانية — بين عدة مستلمين بحساب النِّسَب الساذج كثيرًا ما يعطي حصصًا لا يعود مجموعها إلى المبلغ الأصلي. التخصيص الدقيق إلى السنت هو العلاج: طريقة بالأعداد الصحيحة/العشرية تعمل بأصغر وحدة للعملة (السنت) وتضمن أن تجمع الحصص تمامًا إلى الإجمالي، مهما كان القسمة غير منتظمة. وكل مهندس برمجيات يحتاج إلى أن يتطابق إجمالي مقسَّم إلى آخر سنت — كشوف الرواتب، وصرف الدعم، وتحميل الخدمات المشتركة — يحتاج هذا النمط، لا النِّسَب المئوية بالفاصلة العائمة.

لماذا يهم هذا

هذا نمط أساسي مسمّى في هندسة برمجيات المؤسسات: كتاب Martin Fowler ‏Patterns of Enterprise Application Architecture (2002) يوثّق Money وAllocate تحديدًا لأن «قسمة 100$ على ثلاثة» مشكلة يخطئ فيها الكود الساذج دائمًا، ويخطئ بصمت — يظهر الخطأ حين يطابق أحدهم الدفاتر فيجد الحصص تنقص (أو تزيد) عن الإجمالي بسنت. وفي عمل اقتصاد الصحة ومالية NHS ليس هذا أكاديميًا: رقم أثر الميزانية يُقسَّم حسب الموقع أو السنة أو الجهة؛ وتكاليف البنية التحتية والتراخيص المشتركة تُوزَّع على الأقسام بحسب عدد الموظفين أو نسبة النشاط. ويجب أن يتطابق كل تقسيم من هذه تمامًا، لأن مدير مالية يتلقى حصصًا لا يساوي مجموعها الإجمالي سيفقد الثقة بالنموذج كله.

الحساب

الطريقة الساذجة (خاطئة):
  الحصة_i = قرِّب(الإجمالي × النسبة_i / Σ النسب)     — تقريب كل حصة على حدة

الطريقة الدقيقة (أكبر باقٍ / "largest remainder allocation"):
  1. الأساس_i = أرضية(الإجمالي_بأصغر_وحدة × النسبة_i / Σ النسب)   — أصغر وحدات كاملة فقط (سنتات)
  2. الباقي = الإجمالي_بأصغر_وحدة − Σ الأساس_i                      — السنتات المتبقية، دائمًا < عدد المستلمين
  3. وزِّع وحدة صغرى إضافية واحدة على `الباقي` من المستلمين ذوي أكبر
     جزء كسري من الخطوة 1 حتى ينفد الباقي

النتيجة: Σ الحصة_i == الإجمالي دائمًا، بحكم البنية

لا تقرِّب الطريقة الدقيقة أي حصة منفردة أبدًا — بل تقرِّب التخصيص كله في عملية واحدة، وهذا ما يجعل ثبات المجموع صحيحًا.

مثال محلول

قسمة 100.00$ إلى ثلاث حصص متساوية (النسب = [1, 1, 1]).

الطريقة الساذجة: 100.00$ ÷ 3 = 33.333…$، يُقرَّب كل ناتج على حدة إلى أقرب سنت فيصير 33.33$ لكل مستلم. المجموع: 33.33$ × 3 = 99.99$ — سنت واحد مفقود، ولا بند منفرد «خاطئ» بما يكفي لملاحظته بالفحص.

الطريقة الدقيقة: الأساس = 33.33$ للثلاثة (إجمالي 9,999 وحدة صغرى من أرضية(10,000 / 3) = 3,333 سنتًا لكل مستلم). يتبقى سنت واحد (10,000 − 9,999). ويذهب ذلك السنت الوحيد إلى المستلم ذي أكبر جزء كسري في القسمة — أي مستلم بالتحديد تفصيلة داخلية في حسم التعادل، لا يجوز للمستدعي الاعتماد عليها. يحصل مستلمان على 33.33$ وواحد على 33.34$، ويجمع الثلاثة 100.00$ بالضبط.

هذا هو الحساب الذي يحتاجه تحليل أثر الميزانية كلما وجب تقسيم رقم أثر ميزانية إجمالي حسب الموقع أو الفئة السكانية أو السنة المالية ومطابقته مع الإجمالي المنشور — انظر تجميع التكاليف الآمن للعملات للمسألة المقابلة وهي جمع كثير من البنود دون انحراف.

الصلة بهندسة البرمجيات

هذا هو «نمط Money» في عمارة برمجيات المؤسسات بالضبط — النمط الأساسي المسمّى لهذا النوع من الأخطاء تحديدًا، لا حيلة عابرة. وقد وصلت إلى الإنتاج بالفعل إخفاقات مطابقة مالية حقيقية بسبب هذا الخطأ نفسه: تقسيم نسبي محسوب بـ f64، يُقرَّب لكل مستلم، ولا يُفحص أبدًا مقابل الإجمالي الأصلي. ويرتبط مباشرةً بوحدة التكلفة الإجمالية للملكية في هذا المستودع، التي تجمع حاليًا تكاليف بالفاصلة العائمة العادية عبر السنوات والخيارات — والانضباط الدقيق نفسه ينطبق حين يجب تخصيص إجمالي TCO أو أثر الميزانية، لا مجرد جمعه.

المزالق

  • النسبة المئوية ثم التقريب بدل أكبر باقٍ: التخصيص بنسب مئوية بالفاصلة العائمة مع تقريب كل مستلم على حدة، وهذا يراكم أخطاء التقريب ونادرًا ما يعود مجموعه إلى الإجمالي، خاصةً مع كثرة المستلمين.
  • تجاهل أُسّ أصغر وحدة للعملة: افتراض أن لكل العملات منزلتين عشريتين — الين الياباني صفر، وبعض العملات ثلاث — والتقسيم النسبي المكتوب يدويًا كثيرًا ما يضمّن 2 ثابتة ويتعطل بصمت مع عملة أخرى. أما روتين التخصيص الدقيق فيقرأ الأُسّ من العملة نفسها (ISO 4217).
  • إعادة تخصيص الباقي المخصَّص: تشغيل روتين التخصيص ثانية على ما تبقى من تخصيص سابق دون فحص لخاصية الخمول (idempotency)، وقد يقيِّد السنت نفسه مرتين للمستلم نفسه.

المصادر

  • Fowler M. "Patterns of Enterprise Application Architecture." Addison-Wesley, 2002 — نمطا Money وAllocate.
  • ISO 4217 — معيار رموز العملات والصناديق، الذي يحدد أُسّ أصغر وحدة لكل عملة.