مرحبا،
- DirectPlay تضمن لك وصول كل بايت إلى وجهته بالترتيب المطلوب دون مجهود إضافي من المبرمج.
- هل تغني هذه المكتبة عن استخدام مكونات ال Indy مثلا ؟
فيما يخص الإرسال و الاستقبال فهي تغني عن Indy ، و لكن Indy كما نعلم لديها الكثير
من الخدمات الفرعية و التي قد تجدها مفيدة، و لا يوجد ما يمنع من استخدام التقنيتين معا.
فيما يخص DirectX فأنا أجد أن مكونات DelphiX أو UnDelphix ممتازة وتعزل المبرمج
من صداع التعامل المباشر مع DirectX كما أنها تدعم دلفي 2010.
و عموما باستخدام مفهوم الطبقات و فصل أجزاء البرنامج إلى وحدات منفصلة حسب تخصصها؛
يمكن دعم أو تنفيذ أكثر من تقنية، بحيث تكون تقنية DX موجودة و كذلك Indy وغيرها في نفس الوقت،
و تكون من ضمن خيارات البرنامج (السيرفر).
- بالنسبة للدعم المستقبلي ل DirectPlay فهي نقطة جديرة بالاعتبار.
- المقصود بالطبقات Layers :
تقسيم منطقيات البرنامج إلى طبقات:
نورد الأمثلة التالية بأقل ما يمكن من تعقيد:
في الفورم التي تعرض قائمة الأسماء نحتاج لعرض اسم أحد المشتركين:
كود :
// Form frmChat
procedure TfrmChat.ShowContactDetail(UderId: string);
var
sDisplayName: string;
begin
sDisplayName := uChatManager.GetDisplayName(UsirId);
lblDisplayName.Caption := sDisplayName;
//...
//....
end;
//Unit uChatManager
function GetDisplayName(UderId: string): string;
var
sDisplayName: string;
begin
sDisplayName := uChatDataManager.GetDisplayName(UsirId);
if Trim(sDisplayName) <> '' then
result := sDisplayName
else
result := '<Not Specified>';
end;
//Unit uChatDataManager
function GetDisplayName(UderId: string): string;
var
sDisplayName: string;
sSql: string;
Q: TADOQuery;
begin
sDisplayName := '';
result := '';
sSql := 'SELECT DisplayName FROM chatAccount WHERE Disply_Name = ' +
QuotedStr(UserId);
if ADO_USED then
begin
Q := TADOQuery.Create(nil);
try
Q.Connection := ADoConnection; //
Q.SQL.Text := sSql;
q.Open;
if not q.FieldByName('DisplayName').IsNull then
sDisplayName := q.FieldByName('DisplayName').AsString;
finally
q.Free;
end;
end;
if SQLLITE_USED then
begin
//....
//....
end;
result := sDisplayName;
end;
الفكرة هنا فيما يخص مفهوم الطبقات أن الفورم لا تعلم شيئا عن قاعدة البيانات، و لا عن منطقية البرنامج،
و لكنها تطلب المعلومة وتعرضها فقط. المعلومة تطلبها من الوحدة الخاصة بمنطقيات البرنامج و هي:
uChatManager الذي بدورها لا تعلم شيئا عن قاعدة البيانات ولكن تطلب المعلومة من وحدة uChatDataManager
التي لديها المعلومات الخاصة بقاعدة البيانات و جداولها و حقولها وأيضا تقرر ما نوع تقنية قواعد البيانات
التي يجب استخدامها وكيفية استدعائها (خشية التعقيد، هذه الوحدة أيضا يمكن فصلها).
فيما يخص الشبكة و الاتصال نأخذ المثال التالي:
تقوم الفورم مثلا بنشر Broadcast رسالة للجميع :
كود :
// Form frmChat
procedure TfrmChat.BroadCast(AText: string);
begin
if uChatManager.BroadCast(SenderId, AText) then
ShowMessage('OK');
else
ShowMessage('Not Ok');
end;
//Unit uChatManager
function BroadCast(SenderId: string; AText: string): boolean;
var
sDisplayName: string;
begin
result := false;
if (Trim(AText) <> '') and (SenderId <> '') then
begin
sDisplayName := uChatDataManager.GetDisplayName(SenderId);
AText := sDisplayName + ': ' + AText;
result := uChatNetManager.BroadCast(AText) then
end;
end;
//Unit uChatNetManager
function BroadCast(AText: string): boolean;
begin
if DX_Used then
begin
result := uNetDirectPlay.BroadCast(AText); // unit for handling DirectPlay calls
end;
if INDY_Used then
begin
result := uNetIndy.BroadCast(AText); // unit for handling Indy calls
end;
end;
تقوم الفورم التي لا تعلم شيئا عن تقنيات الاتصال و الشبكة بإرسال طلب نشر رسالة من الوحدة uChatManager ،
فتقوم الوحدة بمراجعة الرسالة و إضافة اسم المرسل لها. ولإنها هي أيضا معزولة عن تقنية الاتصال
المستخدمة فإنها تقوم بالاستعانة بالوحدة uChatNetManager ، التي ستقرر أي نوع من تقنيات الاتصال
سيتم استخدامها، فإذا كان المعتمد هو DirectPlay ستقوم بتمرير الرسالة إلى الوحدة uNetDirectPlay
التي تعلم كيف تتعامل مع هذه التقنية و تمرر الرسالة لها لنشرها. أما إذا كان المعتمد فهو INDY
لإتها تحول الرسالة إلى الوحدة الخاصة بالنعامل مع تقنيات اندي وهي uNetIndy.
طريقة فصل البرنامج إلى طبقات متخصصة تتيح لنا مرونة و سيطرة أكبر، مثل حرية وسهولة تغيير
التقنيات المستخدمة دون المساس بباقي وحدات البرنامج التي ليس لها علاقة مباشرة بهذه التقنيات.
شكرا للجميع.