OOZOU
تواصلوا معنا
العودة إلى المدونة

إعادة هيكلة الكود باستخدام التعميم بالمعاملات (Parameterization)

تقليل التعقيد عبر إعادة هيكلة الكود بأسلوب التعميم بالمعاملات (parameterization).

10 يوليو 2017
4 دقائق للقراءة
إعادة هيكلة الكود باستخدام التعميم بالمعاملات (Parameterization)

تحديث (13 يوليو 2017): أصلحت منطق حساب المتوسط المرجّح الخاطئ في الكود، وأضفت مثالًا عمليًا يمكنكم تشغيله على أجهزتكم. :awesome:

صادفت في مناسبات عديدة أجزاء من الكود "شبه متطابقة" منتشرة في أنحاء قاعدة الكود. والمشكلة في هذا النوع من الكود الرديء (code smell) أنكم حين تريدون تغيير تفصيل صغير في دالة بعينها، تضطرون إلى البحث عن كل المواضع التي كتبتموها فيها وتعديلها جميعًا، وهذه ليست فكرة جيدة.

الكود المكرر سبب رئيسي في صعوبة صيانة السكربتات. fancy-quote

_Brian Marick في كتاب Everyday Scripting with Ruby _ الأسلوب الذي أستخدمه كثيرًا وأجده سهلًا للغاية هو التعميم بالمعاملات (parameterization). سأشرح اليوم كيف يعمل من خلال مثال صغير ولطيف.

حساب المتوسط المرجّح

لدي تقارير أحتاج فيها إلى حساب المتوسط المرجّح لحقل إجمالي الربح، على أن يكون الترجيح بحسب إيرادات المبيعات. وهذا ما توصلت إليه (بلغة Ruby).

def weight_avg_gross_profit(reports)
  # find total weight, sum of sale_revenue
  total_weight = reports.reduce(0) { |sum, r| sum + r.sale_revenue }

  # find sum products
  sum_prod = reports.reduce do |sum, r|
    sum + (r.percent_gross_profit * r.sale_revenue)
  end

  # simple weight average formula, (w1*x1 + w2*x2) / (w1 + w2)
  sum_prod / total_weight
end
lang-ruby

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

def weight_avg_gross_profit(reports)
  # find total weight, sum of sale_revenue
  total_weight = reports.reduce(0) { |sum, r| sum + r.sale_revenue }

  # find sum products
  sum_prod = reports.reduce(0) do |sum, r|
    sum + (r.percent_gross_profit * r.sale_revenue)
  end

  # simple weight average formula, (w1*x1 + w2*x2) / (w1 + w2)
  sum_prod / total_weight
end

def weight_avg_gross_profit(reports)
  # find total weight, sum of sale_revenue
  total_weight = reports.reduce(0) { |sum, r| sum + r.sale_revenue }

  # find sum products
  sum_prod = reports.reduce(0) do |sum, r|
    sum + (r.cogs * r.sale_revenue)
  end

  # simple weight average formula, (w1*x1 + w2*x2) / (w1 + w2)
  sum_prod / total_weight
end
lang-ruby

اجعله يعمل أولًا، ثم اجعله صحيحًا ❤ fancy-quote

حصلنا على ما نريد، أليس كذلك؟ رائع، لكن ماذا لو احتجنا إلى المتوسط المرجّح لحقول أخرى؟ وماذا لو احتجنا إلى تغيير الترجيح من sale_revenue إلى شيء آخر؟ إنشاء دالة جديدة تتشارك هذا المنطق سيعيدنا إلى المشكلة التي تحدثت عنها سابقًا، أي مشكلة التكرار.

التعميم بالمعاملات عمليًا

ماذا نلاحظ الآن؟ هاتان الدالتان متطابقتان تقريبًا، أليس كذلك؟ الفرق الوحيد هو الـ block الذي مررته إلى دالة map.

لنستخرج الكود المتشابه ونضعه في دالة جديدة سأسميها w_avg، ثم نحوّل الاختلافات إلى معاملات.

ملاحظة: تستطيع Ruby استدعاء دالة ديناميكيًا عبر تمرير string أو symbol إلى الدالة send

حذفت الدالة المكررة، وأصبح برنامجنا يبدو هكذا.

def weight_avg_gross_profit(reports)
  weight_avg(reports, 'gross_profit')
end

def weight_avg_cogs(reports)
  weight_avg(reports, 'cogs')
end

def weight_avg(reports, value)
  total_weight =   reports.reduce(0) { |sum, r| sum + r.sale_revenue }
  sum_prod = reports.reduce(0) do |sum, res|
    sum + (res.send(value) * res.sale_revenue)
  end

  sum_prod / total_weight
end
lang-ruby

أصبح منطق الدالتين الآن في مكان واحد. ويمكنني بسهولة توسيعه لحساب weight_avg لأي قيمة من التقرير بدالة من سطر واحد.

إليكم رابطًا لنسخة عاملة من برنامج Ruby هذا

_ نزّلوه وشغّلوه _

ruby parameterized_working_example.rb
lang-bash

خطوة أبعد

التعميم بالمعاملات حيلة صغيرة لطيفة، لكنه ليس حلًا سحريًا. ففي بعض الأحيان يكون من الحكمة الإبقاء على قدر بسيط من التكرار بدلًا من دالة مفرطة في التجريد لا يمكن توسيعها أو تعديلها. وكما قالت Sandi Metz في RailsConference 2014

التكرار أقل تكلفة بكثير من التجريد الخاطئ. fancy-quote

ملاحظة أخيرة

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

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

تصميم البرمجيات عملية ممتعة لكنها معقدة، تتطلب الإبداع والتفكير المنطقي ومهارات حل المشكلات.

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد