البرمجة الهيكلية لجاكسون

البرمجة الهيكلية لجاكسون ( JSP ) هي منهجية للبرمجة الهيكلية طورها مستشار البرمجيات البريطاني مايكل أ. جاكسون. وقد وُصفت في كتابه "مبادئ تصميم البرامج" الصادر عام 1975. [ 1 ] تعتمد تقنية JSP على تحليل هياكل البيانات للملفات التي يجب على البرنامج قراءتها كمدخلات وإنتاجها كمخرجات، ثم تصميم البرنامج بناءً على تلك الهياكل، بحيث يتعامل هيكل التحكم في البرنامج مع هذه الهياكل بطريقة طبيعية وبديهية.
يصف JSP هياكل البيانات والبرامج باستخدام ثلاثة هياكل أساسية: التسلسل، والتكرار، والاختيار (أو البدائل). ويتم تمثيل هذه الهياكل بيانياً كتمثيل مرئي للتعبير النمطي .
مقدمة
قام مايكل أ. جاكسون بتطوير JSP في الأصل خلال سبعينيات القرن الماضي. وقد وثّق النظام في كتابه " مبادئ تصميم البرامج " الصادر عام 1975. [ 1 ] وفي محاضرة ألقاها في مؤتمر عام 2001، [ 2 ] قدّم تحليلًا استعاديًا للدوافع الأصلية وراء هذه الطريقة، وربطها بتطورات هندسة البرمجيات اللاحقة . كان هدف جاكسون هو تسهيل تعديل وصيانة برامج معالجة ملفات الدفعات في لغة كوبول ، ولكن يمكن استخدام هذه الطريقة لتصميم برامج لأي لغة برمجة تحتوي على بنى تحكم هيكلية - التسلسل، والتكرار، والاختيار ("إذا/ثم/وإلا").
كانت برمجة جاكسون الهيكلية مشابهة لبرمجة وارنير/أور الهيكلية [ 3 ] [ 4 ] على الرغم من أن JSP أخذت في الاعتبار كلًا من هياكل بيانات الإدخال والإخراج بينما ركزت طريقة وارنير/أور بشكل حصري تقريبًا على بنية تدفق الإخراج.
الدافع وراء هذه الطريقة
عند تطوير JSP، كانت معظم البرامج عبارة عن برامج COBOL تعمل على دفعات، وتعالج ملفات متسلسلة مخزنة على شريط. كان البرنامج النموذجي يقرأ ملف الإدخال كسلسلة من السجلات، مما جعل جميع البرامج تتشابه في بنيتها - حلقة رئيسية واحدة تعالج جميع السجلات في الملف، سجلًا تلو الآخر. أكد جاكسون أن هذه البنية البرمجية خاطئة في أغلب الأحيان، وشجع المبرمجين على البحث عن هياكل بيانات أكثر تعقيدًا. في الفصل الثالث من كتاب "مبادئ تصميم البرامج " [ 1 ]، يعرض جاكسون نسختين من برنامج، إحداهما مصممة باستخدام JSP، والأخرى باستخدام بنية الحلقة المفردة التقليدية. إليكم مثاله، مترجمًا من COBOL إلى Java. يهدف هذان البرنامجان إلى التعرف على مجموعات السجلات (الأسطر) المتكررة في ملف مُرتب، وإنتاج ملف إخراج يسرد كل سجل وعدد مرات ظهوره في الملف.
إليكم النسخة التقليدية ذات الحلقة الواحدة من البرنامج.
سلسلة نصية line = null ؛ عدد صحيح count = 0 ؛ سلسلة نصية firstLineOfGroup = null ؛// بداية حلقة التكرار الرئيسية المفردة while (( line = in . readLine ()) != null ) { if ( firstLineOfGroup == null || ! line . equals ( firstLineOfGroup )) { if ( firstLineOfGroup != null ) { System . out . printf ( "%s %d%n" , firstLineOfGroup , count ); } count = 0 ; firstLineOfGroup = line ; } count ++ ; } if ( firstLineOfGroup != null ) { System . out . printf ( "%s %d%n" , firstLineOfGroup , count ); }إليك نسخة من البرنامج نفسه مكتوبة بلغة JSP. لاحظ أنها (على عكس البرنامج التقليدي) تحتوي على حلقتين، إحداهما متداخلة داخل الأخرى. تعالج الحلقة الخارجية مجموعات من السجلات المتكررة، بينما تعالج الحلقة الداخلية السجلات الفردية في المجموعة.
int numberOfLinesInGroup = 0 ;String line = in.readLine ( ); // بداية الحلقة الخارجية: معالجة مجموعة واحدة while ( line ! = null ) { numberOfLinesInGroup = 0 ; String firstLineOfGroup = line ;// بداية الحلقة الداخلية: معالجة سجل واحد في المجموعة while ( line != null && line . equals ( firstLineOfGroup )) { numberOfLinesInGroup ++ ; line = in . readLine (); } System . out . printf ( "%s %d%n" , firstLineOfGroup , numberOfLinesInGroup ); }ينتقد جاكسون النسخة التقليدية ذات الحلقة الواحدة لعجزها عن معالجة بنية ملف الإدخال (سلسلة من المجموعات التي تحتوي على سجلات متكررة) بطريقة طبيعية. ومن دلائل تصميمها غير الطبيعي أنها، لكي تعمل بشكل صحيح، مضطرة إلى تضمين شيفرة خاصة لمعالجة السجل الأول والأخير من الملف.
الطريقة الأساسية
تستخدم JSP خطوات شبه رسمية لالتقاط البنية الحالية لمدخلات ومخرجات البرنامج في بنية البرنامج نفسه.
الهدف هو إنشاء برامج يسهل تعديلها طوال فترة استخدامها. تمثلت الفكرة الرئيسية لجاكسون في أن تغييرات المتطلبات عادةً ما تكون تعديلات طفيفة على الهياكل القائمة. بالنسبة لبرنامج مُنشأ باستخدام JSP، تتطابق المدخلات والمخرجات والهياكل الداخلية للبرنامج، لذا فإن التغييرات الطفيفة في المدخلات والمخرجات ستؤدي إلى تغييرات طفيفة في البرنامج نفسه.
تُصنّف JSP البرامج من حيث أربعة أنواع من المكونات:
- العمليات الأساسية
- التسلسلات
- التكرارات
- مختارات
تبدأ هذه الطريقة بوصف مدخلات البرنامج من حيث أنواع المكونات الأساسية الأربعة. ثم تنتقل إلى وصف مخرجات البرنامج بنفس الطريقة. يُنمذج كل مدخل ومخرج على شكل مخطط هيكل بيانات منفصل . ولجعل JSP مناسبًا للتطبيقات كثيفة الحساب، مثل معالجة الإشارات الرقمية ، من الضروري أيضًا رسم مخططات هيكل الخوارزمية، التي تركز على هياكل البيانات الداخلية بدلًا من هياكل المدخلات والمخرجات.
بعد ذلك، يتم توحيد أو دمج بنيتي الإدخال والإخراج في بنية برنامج نهائية، تُعرف باسم مخطط بنية البرنامج (PSD). قد تتضمن هذه الخطوة إضافة قدر ضئيل من بنية التحكم عالية المستوى لربط المدخلات والمخرجات. تعالج بعض البرامج جميع المدخلات قبل إخراج أي مخرجات، بينما تقرأ برامج أخرى سجلاً واحداً، وتكتب سجلاً واحداً، ثم تُكرر العملية. يجب توثيق هذه الأساليب في مخطط بنية البرنامج (PSD).
يتم بعد ذلك تنفيذ بنية PSD، المحايدة لغوياً، بلغة برمجة. تُركز JSP على البرمجة على مستوى هياكل التحكم، لذا تستخدم التصاميم المُنفذة عمليات أساسية فقط، مثل التسلسلات والتكرارات والاختيارات. لا تُستخدم JSP لهيكلة البرامج على مستوى الفئات والكائنات، مع أنها تُفيد في هيكلة تدفق التحكم داخل أساليب الفئة.
تستخدم لغة JSP تدوينًا تخطيطيًا لوصف بنية المدخلات والمخرجات والبرامج، مع عناصر تخطيطية لكل نوع من أنواع المكونات الأساسية.
يتم رسم عملية بسيطة على شكل مربع.
عمليةيتم تمثيل سلسلة العمليات بمربعات متصلة بخطوط. في المثال أدناه، A هي سلسلة تتكون من العمليات B و C و D.
تسلسلتُمثَّل التكرارات مرة أخرى بمربعات متصلة. بالإضافة إلى ذلك، تحتوي العملية المُكرَّرة على نجمة في الزاوية العلوية اليمنى من مربعها. في المثال أدناه، يُمثِّل A تكرارًا لصفر أو أكثر من استدعاءات العملية B.
تكراريُشبه الاختيار التسلسل، ولكن مع رسم دائرة في الزاوية العلوية اليمنى لكل عملية اختيارية. في المثال، يُمثل A اختيار عملية واحدة فقط من بين العمليات B أو C أو D.
مجموعة مختارةلاحظ أنه في المخططات أعلاه، العنصر A هو الذي يمثل التسلسل أو التكرار، وليس العناصر B أو C أو D (التي تُعتبر جميعها عناصر أولية في المخططات أعلاه). يُقدّم جاكسون "قاعدة النظر لأسفل" لتحديد ماهية العنصر، أي النظر إلى العناصر الموجودة أسفل عنصر ما لمعرفة ماهيته.
مثال عملي
كمثال، إليك كيفية تصميم مبرمج JSP وبرمجته لبرنامج ترميز طول التشغيل . برنامج ترميز طول التشغيل هو برنامج يستقبل سلسلة من البايتات، والتي يمكن اعتبارها على شكل سلاسل ، حيث تتكون السلسلة من بايت واحد أو أكثر من نفس القيمة. يُخرج البرنامج سلسلة من أزواج البايتات، حيث يمثل كل زوج وصفًا مضغوطًا لسلسلة. في كل زوج، يمثل البايت الأول قيمة البايت المتكرر في السلسلة، بينما يمثل البايت الثاني عدد مرات تكرار تلك القيمة في السلسلة. على سبيل المثال، سلسلة من ثماني مرات ظهور للحرف "A" في سلسلة الإدخال ("AAAAAAAA") ستنتج "A8" كزوج بايتات في سلسلة الإخراج. تُستخدم برامج ترميز طول التشغيل غالبًا لضغط الصور النقطية بشكل تقريبي.
في لغة JSP، تتمثل الخطوة الأولى في وصف بنية (بنى) بيانات تدفق (تدفقات) الإدخال للبرنامج. يحتوي البرنامج على تدفق إدخال واحد فقط، يتكون من صفر أو أكثر من تكرارات نفس قيمة البايت. إليك مخطط بنية بيانات JSP لتدفق الإدخال.

الخطوة الثانية هي وصف بنية بيانات الإخراج، والتي تتكون في هذه الحالة من صفر أو أكثر من تكرارات أزواج البايت.

تتمثل الخطوة التالية في وصف أوجه التشابه بين مكونات هياكل الإدخال والإخراج.

تتمثل الخطوة التالية في استخدام أوجه التشابه بين بنيتي البيانات لإنشاء بنية برنامج قادرة على معالجة بنية بيانات الإدخال وإنتاج بنية بيانات الإخراج. (قد لا يكون ذلك ممكنًا في بعض الأحيان. انظر مناقشة تعارضات البنية أدناه).

بمجرد الانتهاء من هيكل البرنامج، يقوم المبرمج بإنشاء قائمة بالعمليات الحسابية التي يجب أن يقوم بها البرنامج، ويتم توضيح مخطط هيكل البرنامج من خلال ربط تلك العمليات بالمكونات الهيكلية المناسبة.
- قراءة بايت
- تذكر البايت
- اضبط العداد على الصفر
- عداد الزيادة
- بايت الإخراج المحفوظ
- عداد الإخراج
أيضًا، في هذه المرحلة يتم سرد الشروط المتعلقة بالتكرارات (الحلقات) والاختيارات (عبارات if-then-else أو case) وإضافتها إلى مخطط بنية البرنامج.
- بينما يوجد المزيد من البايتات
- بينما يوجد المزيد من البايتات، وهذا البايت هو نفسه البايت الأول من التشغيل، فإن العدد سيظل مناسبًا في بايت واحد.
بمجرد الانتهاء من رسم المخطط، يمكن ترجمته إلى أي لغة برمجة مستخدمة. إليك ترجمة إلى لغة C.
#include <stdio.h> #include <stdlib.h>int main ( int argc , char * argv []) { char first_byte ; int count = 0 ;char c = getchar (); // الحصول على البايت الأول while ( c != EOF ) { // معالجة البايت الأول first_byte = c ; count = 1 ; c = getchar ( ); // الحصول على البايت التالي// معالجة البايتات المتتالية في الحلقة while ( c != EOF && c == first_byte && count < 255 ) { // معالجة بايت واحد من نفس القيمة count ++ ; c = getchar (); // الحصول على البايت التالي }putchar ( first_byte ); putchar ( count ); } return EXIT_SUCCESS ; }تقنيات التعامل مع مشاكل التصميم الصعبة
في كتاب "مبادئ تصميم البرامج"، أقر جاكسون بالحالات التي تطرح أنواعًا محددة من مشاكل التصميم، وقدم تقنيات للتعامل معها.
إحدى هذه الحالات هي عندما يعالج البرنامج ملفي إدخال بدلاً من ملف واحد. في عام ١٩٧٥، كانت إحدى المشكلات المعقدة الشائعة هي كيفية تصميم برنامج لمعالجة المعاملات. في مثل هذا البرنامج، يُشغَّل ملف تسلسلي لسجلات التحديث مقابل ملف رئيسي تسلسلي، لينتج عنه ملف رئيسي مُحدَّث كناتج. (على سبيل المثال، في الليل، كان أحد البنوك يُشغِّل برنامجًا دفعيًا لتحديث أرصدة حسابات عملائه بناءً على سجلات الإيداعات والسحوبات التي أجروها في ذلك اليوم). وقد قدّم كتاب "مبادئ تصميم البرامج " حلاً قياسيًا لهذه المشكلة، إلى جانب شرح للمنطق الكامن وراء التصميم.
ثمة نوع آخر من المشاكل يتمثل فيما أسماه جاكسون "صعوبات التعرف"، وهو ما نسميه اليوم مشاكل التحليل النحوي . وقد تم استكمال تقنية تصميم JSP الأساسية بعمليتي POSIT وQUIT للسماح بتصميم ما نسميه الآن محلل التراجع .
أقرّت لغة JSP أيضًا بثلاث حالات تُعرف باسم "تعارضات البنية" - تعارض الحدود، وتعارض الترتيب، وتعارض التداخل - وقدّمت تقنيات للتعامل معها. في حالات تعارض البنية، تكون هياكل بيانات الإدخال والإخراج غير متوافقة لدرجة أنه يستحيل إنتاج ملف الإخراج من ملف الإدخال. لذا، من الضروري كتابة برنامجين : الأول يُعالج دفق الإدخال، ويُقسّمه إلى أجزاء أصغر، ويكتب هذه الأجزاء في ملف وسيط. أما البرنامج الثاني فيقرأ الملف الوسيط ويُنتج المخرجات المطلوبة.
JSP والتصميم الموجه للكائنات
طُوِّرت لغة JSP قبل وقت طويل من ظهور تقنيات البرمجة الكائنية. وهي، وكذلك منهجها اللاحق JSD، لا تتعامل مع ما يُسمى اليوم "الكائنات" على أنها مجموعات من الدوال المستقلة إلى حد ما. بدلاً من ذلك، واستنادًا إلى أعمال كار هوار ، تصف JSP وJSD كائنات البرمجيات على أنها دوال مشتركة . [ 5 ] [ 6 ]
انظر أيضاً
مراجع
- 1 2 3 جاكسون، ماساتشوستس (1975)، مبادئ تصميم البرامج ، أكاديميك.
- ↑ جاكسون، ماساتشوستس (2001)، JSP في منظور (ملف PDF) ، مؤتمر رواد sd&m، بون، يونيو 2001، مؤرشف (ملف PDF) من الأصل في 16 مايو 2017 ، تم استرجاعه في 26 يناير 2017
{{citation}}: CS1 maint: location ( link ) CS1 maint: location missing publisher ( link ) - ↑ وارنير، جيه دي (1974)، البناء المنطقي للبرامج ، نيويورك: فان نوستراند رينهولد
- ↑ أور، ك. ت. (1980)، "البرمجة الهيكلية في ثمانينيات القرن العشرين"، وقائع المؤتمر السنوي لجمعية آلات الحوسبة لعام 1980 ، نيويورك، نيويورك: مطبعة جمعية آلات الحوسبة، ص 323-326 ، doi : 10.1145/800176.809987 ، ISBN 978-0897910286، S2CID 26834496
- ↑ ويرينغا، ر. (ديسمبر 1998)، "دراسة استقصائية لأساليب وتقنيات تحديد مواصفات البرمجيات المهيكلة والموجهة للكائنات"، مجلة ACM Computing Surveys ، 30 (4): 459-527 ، CiteSeerX 10.1.1.107.5410 ، doi : 10.1145/299917.299919 ، S2CID 14967319 .
- ↑ هندرسون-سيلرز، برايان ؛ إدواردز، جيه إم (سبتمبر 1990)، "دورة حياة الأنظمة الموجهة للكائنات"، اتصالات رابطة مكائن الحوسبة ، 33 (9): 142-159 ، doi : 10.1145/83880.84529 ، S2CID 14680399 .
روابط خارجية
- نماذج البرمجة
- الرسوم البيانية
