Я програміст паскаль Delphi, використовую останню версію Embarcadero delphi XE, і я хотів би скористатися такими моделями дизайну, як контролер перегляду моделі та модель подання виду.
Однак, в Інтернеті, здається, не так багато про кращі практики для цього в мові Pascal. Більшість прикладів, які я можу знайти, є на C #, а деякі мовні функції відсутні у мові pascal, а значить, можливо, мені доведеться знайти способи реалізації цих функцій.
Я намагаюся адаптувати код з цієї статті тут
Я перелічу проблеми, з якими я стикаюся
- Зменшувані типи
Паскаль не має змінних типів, як це робить C #, тому я створив свій власний.
TNullable<T> = record
strict private
fHasValue : boolean;
fValue : T;
function GetValue:T;
procedure SetValue(newValue : T);
public
property HasValue : boolean read fHasValue;
property Value : T read GetValue write SetValue;
procedure SetToNull;
end;
у розділі впровадження
function TNullable<T>.GetValue:T;
begin
if fHasValue then
begin
Result := fValue;
end
else raise Exception.Create('Value Not Set');
end;
procedure TNullable<T>.SetValue(newValue : T);
begin
fValue := newValue;
fHasValue := true;
end;
procedure TNullable<T>.SetToNull;
begin
fHasValue := false;
end;
- Отримати / встановити властивості
Тепер, коли я маю мінливий тип, я можу створювати мінливі властивості, проте він має деякі запахи коду
наприклад, якщо я створюю
TFoo = class
private
function GetBar:TNullable<Integer>;
procedure SetBar(x:TNullable<Integer>);
public
property Bar : TNullable<Integer> read GetBar write SetBar;
у розділі впровадження
function TFoo.GetBar:TNullable<Integer>;
begin
if **valueExists** then
begin
Result.Value := **the value**
end else
begin
Result.SetToNull;
end;
end;
procedure TFoo.SetBar(x:TNullable<Integer>);
begin
if X.hasValue then
begin
//Store/show value here
end else
begin
//handle null assignment here
end;
end;
Це добре, але коли справа стосується використання цих властивостей, я не можу просто використовувати
myFoo.Bar.Value: = 1;
Я маю користуватися
var
myBar : TNullable<Integer>;
begin
myBar.Value := 1;
myFoo.Bar := myBar;
end;
Що трохи мідніше. Я гадаю, що з цим я нічого не можу зробити.
- Кругові довідники
Мені подобається розділяти класи на різні одиниці.
тобто:
зберігаючи інтерфейс користувача окремо від логіки управління та логічного рівня моделі та даних.
У мене може виникнути ситуація, коли 2 класи можуть посилатися один на одного. Хоча це ситуація, якої я б хотів уникнути, здебільшого, є випадки, коли це потрібно.
наприклад
unit u_A;
interface
uses
u_B
;
type
TA = class
public
Foo : TB;
end;
implementation
end;
та інший підрозділ
unit u_B;
interface
uses
u_A
;
type
TB = class
public
Foo : TA;
end;
implementation
end;
Цей код порушений, оскільки два класи включають один одного, і це не можна зробити на мові Pascal. Це не така проблема в C #. Рішення, про які я можу придумати: 1. включайте обидва класи в один і той же підрозділ, хоча це проблема, якщо я не думаю, що це відповідає дизайну. 2. Створіть інший батьківський інтерфейс для B і успадкуйте B від цього, тоді це обходить. Хоча це безладно для такого простого завдання.
- Статичні класи
Немає статичних класів у Delphi, вони корисні для класів управління.
- Кращі класи для контейнерів, які можна використовувати в Delphi
В даний час я використовую TList і TObjectList в Generics.Collections Вони були представлені в Delphi XE, я сподіваюся, що це найкраще використовувати, оскільки delphi 7, схоже, не має жодних хороших варіантів.
Я все ще думаю про обробників подій та будь-які проблеми, які можуть виникнути там. Можливо, є якісь інші питання, про які я ще не замислювався.
Дякую за будь-яку пораду.