Logo

ماركو كانتو:
أساسي باسكال

الفصل 11
برنامج و وحدات

تقوم تطبيقات دلفي باستخدام مكثّف للوحدات units، أو بنيات modules البرنامج. الوحدات، في الواقع، كانت الأساس لمفهوم البنيات في اللغة قبل ان يتم ادخال الطبقات classes. في تطبيق دلفي، كل نموذج form له وحدة unit توافقه من خلفه. عندما تضيف نموذج جديد للمشروع project (من خلال الزر الخاص في شريط الأدوات أو الأمر File ثم New ثم Form) تقوم دلفي فعليا باضافة وحدة جديدة، فيها تعريف لطبقة النموذج الجديد.

الوحدات

بالرغم أن كلّ نموذج يكون معرّفا في وحدة، فإن العكس ليس صحيحا. الوحدات لا تحتاج لأن تقوم بتعريف النماذج؛ هي ببساطة تستطيع أن تقوم بتعريف مجموعة من الإجرائيات و جعلها متوفرة. من خلال اختيار الأمر File ثم New ثم أيقونة Unit في صفحة New لمستودع الكائنات Object Repository، تقوم باضافة وحدة جديدة فارغة للمشروع الحالي. هذه الوحدة الفارغة تحتوي على التوليف التالي، الذي يحدد أقسام الوحدة بتجزئتها إلى:

unit Unit1;

interface

implementation

end.

مفهوم الوحدة بسيط. الوحدة لديها اسما مميزا متوافقا مع اسم الملف. قسم الواجهة interface يعرّف فيه كل ماهو مرئي للوحدات الأخرى، و قسم التنفيذ implementation فيه التوليف الفعلي كذلك التعريفات المخفية الأخرى. أخيرا، يمكن للوحدة أن يكون لها قسم اختياري للتمهيد initialization مع بعض التوليف الخاص بالاستهلال startup، و الذي سينفذ حالما يُشحن البرنامج في الذاكرة؛ يمكن للوحدة أيضا أن يكون لها قسما اختياري للإنهاء finalization، والذي سينفذ عند وقف البرنامج.

البنيان العام للوحدة، مع كل أقسامها المحتملة، هي كالتالي:

unit unitName;

interface

// other units we need to refer to
// وحدات أخرى نحتاج إلى الإشاة إليها
uses A, B, C; // exported type definition
// تعريفات نوع مصدّرة
type newType = TypeDefinition; // exported constants
// ثوابت مصدّرة
const Zero = 0; // global variables
// متغيرات عامة
var Total: Integer; // list of exported functions and procedures
// سرد بالوظائف والإجراءات المصدّرة
procedure MyProc; implementation uses D, E; // hidden global variable
// متغيرات عامة مخفية
var PartialTotal: Integer; // all the exported functions must be coded
// كل الوظائف المصدرة يجب أن يتم توليفها
procedure MyProc; begin // ... code of procedure MyProc
// توليف الإجراء end; initialization // optional initialization part
// جزء تمهيد اختياري
finalization // optional clean-up code
// توليف اختياري للتنظيف بعد الإستعمال
end.

فقرة الاستخدام uses في بداية قسم الواجهة interface تشير إلى أي من الوحدات الأخرى التي نحتاج للوصول إليها في جزء الواجهة من الوحدة. هذا يتضمن الوحدات التي تقوم بتعريف أنواع البيانات التي نشير إليها عند تعريف أنواع بيانات أخرى، مثل المكونات components المستخدمة داخل النموذج الذي نقوم بتحديده.

فقرة uses الثانية، في بداية قسم التنفيذ implementation، تشير إلى وحدات أخرى نحتاج إلى الوصول إليها فقط في التوليف الخاص بالتنفيذ. عندما تحتاج إلى الإشارة إلى وحدة أخرى من داخل توليف لإجرائيات و مسارات، يجب عليك إضافتها في فقرة uses الثانية بدلا من الأولى. كل الوحدات المشار إليها يجب أن تكون موجودة في دليل directory المشروع أو في دليل مشار إليه في مسار البحث (يمكنك تحديد مسار البحث search path الخاص بالمشروع في صفحة Directories/Conditionals من مربع خيارات المشروع Project Options).

مبرمجو لغة س++ يجب أن يلاحظوا أن تعليمة uses لا تشبه توجيه include. تأثير تعليمة uses هي فقط لجلب جزء الواجهة interface المسبق التحويل precompiled من الوحدات المشار إليها. جزء التنفيذ impementation من الوحدة يتم أخذها في الإعتبار فقط عندما يتم تجميع compile تلك الوحدة. الوحدات التي تقوم بالإشارة إليها يمكن أن تكون إما بشكل توليف مصدري (PAS) أو بشكل ممّع (DCU)، بشرط أن يكون التحويل قد تم بنفس الإصدارة من دلفي.

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

الوحدات ونطاقها

في باسكال، تعدّ الوحدات المفتاح لمفاهيم التغليف encapsulation و المشاهدة visibility، و هي تقريبا أكثر أهمية حتى من الكلمات المفتاحية private خاص و public عام في الطبقة. (في الواقع، كما سنرى في الفصل التالي، تأثير الكلمة المفتاحية private له علاقة بنطاق الوحدة التي تحتوي الطبقة.) إن نطاق أو مجال المعرّف identifier (مثل المتغير، الإجراء، الوظيفة، أو نوع البيانات) يشمل جزء التوليف الذي يمكن منه الوصول إلى المعرّف. القاعدة الرئيسية هي أن المعرّف له معنى فقط ضمن نطاقه، فقط ضمن المساحة التي تم فيها تعريفه. فيما يلي بعض الأمثلة.

أية تصريحات declarations في جزء الواجهة من الوحدة يمكن الوصول إليها من أي مكان في البرنامج يقوم بتضمين هذه الوحدة في فقرة الاستعمال uses الخاصة به. متغيرات طبقة النموذج معرّفة بنفس الطريقة، و بذلك يمكنك الإشارة إلى النموذج (و ما هو عام من حقوله، مساراته، سماته، و مكوناته) من توليف أي نموذج آخر. بالطبع، تعدّ من العادات البرمجية السيئة أن يتم تعريف كل شيء على أنه جامع global. علاوة على مشاكل الاستهلاك المفرط للذاكرة. فإن استخدام المتغيرات الجامعة يجعل من البرنامج أقلّ سهولة عند الصيانة و التحديث. باختصار، يجب أن تستخدم أقل ما يمكن من المتغيّرات الجامعة.

الوحدات و قواعد التسمية

تعليمة uses هي التقنية المعتادة للوصول إلى مجال أو طاق وحدة أخرى. و بالتالي الوصول إلى تعريفات هذه الوحدة. لكن قد يحدث أن تشير إلى وحدتين تتضمنان نفس المعرّف؛ يمكن أن يكون لديك طبقتان أو إجرائيتان تحملان نفس الإسم.

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

على كل حال، إذا نظرت داخل ملفات مكتبة VCL و ملف Windows، ستجد أن بعض وظائف دلفي لديها نفس الإسم (و لكن عموما بمحددات مختلفة) الذي لدى بعض وظائف API لويندوز و المتوفرة في دلفي نفسها. مثال على ذلك إجراء Beep البسيط.

إذا أنشأت برنامج دلفي جديد، مع اضافة زرّ، وكتبت التوليف التالي:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Beep;
end;

عندها و حالما تضغط على الزرّ ستسمع صوتا قصيراّ. انتقل إلى تعليمة uses للوحدة و قم بتغيير التوليف من هذا:

uses
  Windows, Messages, SysUtils, Classes, ...

إلى النسخة الشبيهة جدا التالية (ببساطة انقل وحدة SysUtils إلى ما قبل وحدة Windows ):

uses
  SysUtils, Windows, Messages, Classes, ...

إذا حاولت الآن إعادة تحويل recompile التوليف، سيظهر خطأ التحويل: "Not enough actual parameters." أي: "المحددات الفعلية غير كافية". المشكلة هي أن وحدة Windows تقوم بتعريف وظيفة Beep أخرى تحوي محدّدين. بتعبير آخر أعمّ، ما يحدث للتعريفات في الوحدة الأولي المتضمنة في تعليمة uses قد يتم حجبها من قبل تعريفات مشابهة في وحدات لاحقة. الحل الآمن لذلك في الواقع بسيط جدا:

procedure TForm1.Button1Click(Sender: TObject);
begin
  SysUtils.Beep;
end;

هذا التوليف سوف يتم تحويله بغض النظر عن ترتيب الوحدات في تعليمات uses. عموما يوجد عدد قليل من تعارض الأسماء في دلفي، سبب هذه القلّة ببساطة أن توليف دلفي عادة يكون مودعا داخل مسارات الطبقات. إن وجود مسارين بنفس الإسم في طبقتين مختلفتين لا يسبّب أية مشكلة. المشكلة دائما تكمن في الإجرائيات ذات النطاق الجامع global.

الوحدات و البرامج

تحتوي تطبيقات دلفي على نوعين من التوليف المصدري: وحدة واحدة أو أكثر و ملف برنامج واحد. يمكن اعتبار الوحدات كملفات ثانوية، يتم الإشارة إليها من قبل جزء التطبيق الرئيسي، ألا و هو البرنامج. نظريا، يُعدّ هذا صحيحا. عمليا، ملف البرنامج هو عادة ملف يتم توليده آليا مع إعطائه دورا محدودا. ببساطة هو مطلوب لبدء البرنامج و تشغيل النموذج الرئيسي. يمكن لتوليف ملف البرنامج، أو ملف مشرع دلفي (DPR)، أن يتم تعديله يدويا أو باستخدام مدير المشروع Project Manager و ببعض ما هو متعلق بالتطبيق و بالنماذج في خيارات المشروع Project Options.

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

program Project1;

uses
  Forms,
  Unit1 in ‘Unit1.PAS’ {Form1DateForm};

begin
  Application.Initialize;
  Application.CreateForm (TForm1, Form1);
  Application.Run;
end.

كما ترى، يوجد فقط قسم الاستخدام uses ، ثم التوليف الرئيسي للتطبيق، محصور بين الكلمتين المفتاحين begin و end. تعليمة uses في البرنامج تعتبر بصفة خاصة مهمة لأنها تُستخدم لإدارة عمليات التحويل و الربط linking للتطبيق.

ملخّص

على الأقل في هذه اللحظة، يعدّ هذا الفصل حول هيكل تطبيق باسكال المكتوب بدلفي أو بأحد نسخ تربو باسكال الأخيرة، هو آخر موضوع في الكتاب. لأية ملاحظات أو طلبات يرجى عدم التردد و مراسلتي الكترونيا.

بعد هذا التقديم للغة باسكال، إذا أردت التعمّق أكثر في عناصر التوجّه الكائني لأوبجكت باسكال في دلفي، يمكنك مراجعة كتابي المنشور Masterig Delphi 5 (Sybex, 1999) . من اجل معلومات أكثر عن هذا الكتاب و عن كتبي الأخرى (و كذلك لمؤلّفين آخرين) يمكنك مراجعة موقعي بالشبكة، www.marcocantu.com. نفس هذا الموقع يحتوي النسخ المنقّحة من هذا الكتاب، و الأمثلة الواردة به.

عودة لصفحة الغلاف

حقوق النسخ محفوظة لماركو كانتو؛ وينتش ايطاليا © Copyright Marco Cantù, Wintech Italia Srl 1995-2000
حقوق الترجمة: خالد الشقروني ، 2000