8. تمرين تطبيقي – [حساب الضرائب] باستخدام بنية متعددة الطبقات
![]() |
نعيد هنا النظر في التمرين الموصوف في القسم 4.1. نبدأ بنسخة الملف النصي الموصوفة في القسم 4.3. لمعالجة هذا المثال باستخدام الكائنات، سنستخدم بنية ثلاثية المستويات:
![]() |
- تتولى طبقة [DAO] (كائن الوصول إلى البيانات) الوصول إلى البيانات. في ما يلي، ستوجد هذه البيانات أولاً في ملف نصي، ثم في قاعدة بيانات MySQL؛
- تتولى طبقة [الأعمال] معالجة منطق الأعمال، وفي هذه الحالة حساب الضرائب. وهي لا تتعامل مع البيانات. ويمكن أن تأتي هذه البيانات من مصدرين:
- طبقة [DAO] للبيانات الدائمة؛
- طبقة [console] للبيانات التي يقدمها المستخدم.
- تتولى طبقة [console] التعامل مع المستخدم.
فيما يلي، سيتم تنفيذ كل من طبقتي [DAO] و[business] باستخدام فئة. وسيتم تنفيذ طبقة [console] بواسطة البرنامج الرئيسي.
سنفترض أن جميع تطبيقات طبقة [dao] توفر طريقة getData()، التي تُرجع مجموعة من ثلاثة عناصر (limits، coeffR، coeffN) — وهي مصفوفات البيانات الثلاثة المطلوبة لحساب الضريبة. في لغات أخرى، يُطلق على هذا اسم واجهة. تحدد الواجهة الطرق (هنا، getData) التي يجب أن تتوفر في الفئات التي تنفذ هذه الواجهة.
سيتم تنفيذ طبقة [business] بواسطة فئة يأخذ منشئها مرجعًا إلى طبقة [dao] كمعلمة، مما يضمن الاتصال بين الطبقتين.
8.1. طبقة [DAO]
سنجمع الفئات المختلفة المطلوبة للتطبيق في ملف واحد، impots.py. سيتم بعد ذلك استيراد الكائنات الموجودة في هذا الملف إلى البرامج النصية التي تحتاج إليها.
نبدأ بالحالة التي تكون فيها البيانات في ملف نصي، كما في المثال الوارد في القسم 4.3.
![]() |
فيما يلي كود فئة [ ImpotsFile] (impots.py) التي تنفذ طبقة [DAO]:
ملاحظات:
- السطور 7-8: نُعرّف فئة ImpotsError مشتقة من فئة Exception. لا تضيف هذه الفئة أي شيء إلى فئة Exception. نستخدمها فقط للحصول على فئة استثناء مخصصة. يمكن توسيع هذه الفئة لاحقًا؛
- الأسطر 11–18: فئة من طرق المساعدة. هنا، تقوم طريقة cutNewLineChar بإزالة أي أحرف فاصل أسطر من سلسلة؛
- السطر 25: قد يؤدي فتح الملف إلى إلقاء استثناء IOError؛
- الأسطر 32 و39 و46: يتم إلقاء استثناء ImpotsError المخصص؛
- يشبه الكود ذلك الذي تمت دراسته في المثال الوارد في القسم 4.3.
8.2. طبقة [الأعمال]
![]() |
فيما يلي فئة [ ImpotsMetier] (impots.py) التي تنفذ طبقة [الأعمال]:
class ImpotsMetier:
# constructeur
# on récupère un pointeur sur la couche [dao]
def __init__(self, dao):
self.dao=dao
# calcul de l'impôt
# --------------------------------------------------------------------------
def calculer(self,marie,enfants,salaire):
# marié : oui, non
# enfants : nombre d'enfants
# salaire : salaire annuel
# on demande à la couche [dao] les données nécessaires au calcul
(limites, coeffR, coeffN)=self.dao.getData()
# nombre de parts
marie=marie.lower()
if(marie=="oui"):
nbParts=float(enfants)/2+2
else:
nbParts=float(enfants)/2+1
# une 1/2 part de plus si au moins 3 enfants
if enfants>=3:
nbParts+=0.5
# revenu imposable
revenuImposable=0.72*salaire
# quotient familial
quotient=revenuImposable/nbParts
# est mis à la fin du tableau limites pour arrêter la boucle qui suit
limites[len(limites)-1]=quotient
# calcul de l'impôt
i=0
while quotient>limites[i] :
i=i+1
# du fait qu'on a placé quotient à la fin du tableau limites, la boucle précédente
# ne peut déborder du tableau limites
# maintenant on peut calculer l'impôt
return math.floor(revenuImposable*(float)(coeffR[i])-nbParts*(float)(coeffN[i]))
ملاحظات:
- السطران 5-6: يتلقى منشئ الفئة مرجعًا إلى طبقة [dao] كمعلمة؛
- السطر 16: نستخدم طريقة getData الخاصة بطبقة [dao] لاسترداد البيانات اللازمة لحساب الضريبة؛
- باقي الكود مشابه لما تمت دراسته في المثال الوارد في القسم 4.3.
8.3. طبقة [console]
![]() |
البرنامج النصي الذي ينفذ طبقة [console] (impots-03) هو كما يلي:
ملاحظات:
- السطر 4: نقوم باستيراد جميع الكائنات من ملف impots.py، الذي يحتوي على تعريفات الفئات. وبمجرد الانتهاء من ذلك، يمكننا استخدام هذه الكائنات كما لو كانت موجودة في نفس ملف البرنامج النصي؛
- الأسطر 17–21: نقوم بإنشاء مثيل لكل من طبقة [dao] وطبقة [business] مع معالجة الاستثناءات المحتملة؛
- السطر 18: نقوم بإنشاء مثيل لطبقة [dao] ثم طبقة [business]. نقوم بتخزين المرجع إلى طبقة [business]؛
- السطر 19: نتعامل مع الاستثناءين اللذين قد يحدثان؛
- باقي الكود مشابه لما تمت دراسته في المثال الوارد في القسم 4.3.
8.4. النتائج
نفس النتائج التي تم الحصول عليها بالفعل في الإصدارات التي تستخدم المصفوفات والملفات.
ملف البيانات impots.txt:
12620:13190:15640:24740:31810:39970:48360:55790:92970:127860:151250:172040:195000:0
0:0.05:0.1:0.15:0.2:0.25:0.3:0.35:0.4:0.45:0.5:0.55:0.6:0.65
0:631:1290.5:2072.5:3309.5:4900:6898.5:9316.5:12106:16754.5:23147.5:30710:39312:49062
ملف البيانات data.txt:
ملف results.txt الذي يحتوي على النتائج:




