Если код вложенного в средства управления GUI


Я пишу GUI управления и есть много мест, где есть много вложенных еслис проверкой какой-то результат.

function TMyObject.GetCursor: TCursor;
begin
  if CanDragX then
  begin
    if CanDragY then
      Result := crSizeAll
    else
      Result := crSizeWE;
  end
  else if CanDragY then
    Result := crSizeNS
  else
  if CanClick then
    Result := crHandPoint
  else
    Result := crArrow;
end;

Как бы вы формат/переписать этот код?



955
5
задан 8 августа 2011 в 05:08 Источник Поделиться
Комментарии
5 ответов

Я хотел бы сделать это:

function TMyObject.GetCursor: TCursor;
begin
if CanDragX and CanDragY then
Result := crSizeAll
else if CanDragX then
Result := crSizeWE
else if CanDragY then
Result := crSizeNS
else
if CanClick then
Result := crHandPoint
else
Result := crArrow;
end;

Но на самом деле это вопрос стиля и того, что наиболее удобочитаемыми (и человек, который будет поддерживать его).

5
ответ дан 8 августа 2011 в 07:08 Источник Поделиться

Я не уверен, что ваш язык. Вместо того, чтобы назначить к результату, я предпочитаю середину-функция возвращает в таком случае; тогда мне не нужно другого.

function TMyObject.GetCursor: TCursor;
begin
if CanDragX && CanDragY then return crSizeAll;
if CanDragX then return crSizeWE;
if CanDragY then return crSizeNS;
if CanClick then return crHandPoint;
return crArrow;
end;

Если в вашем языка (VB?), Я думаю, что это намного чище.

4
ответ дан 8 августа 2011 в 03:08 Источник Поделиться

Поскольку существует всего 8 возможных результатов, вы можете положить их в картирование массива. Тогда сама функция будет один-только вкладыш.

const
CursorMap: array [boolean, boolean, boolean] // CanClick, CanDragX, CanDragY
of TCursor = // see CanClick, CanDragX indexes values below:
(((crArrow, crSizeNS), // false, false
(crSizeWE, crSizeAll)), // false, true
((crHandPoint, crSizeNS), // true, false
(crSizeWE, crSizeAll))); // true, true

function TMyObject.GetCursor: TCursor;
begin
Result:= CursorMap[CanClick, CanDragX, CanDragY];
end;

2
ответ дан 10 октября 2011 в 06:10 Источник Поделиться

В методе, как это мне нравится, чтобы было понятно, что результат по умолчанию crArrow и остальные процедуры просто рассматривает ситуации, в которых по умолчанию будет недостаточно.

function TMyObject.GetCursor: TCursor;
begin
Result := crArrow;

if CanDragX and CanDragY then Result := crSizeAll
else if CanDragX then Result := crSizeWE
else if CanDragY then Result := crSizeNS
else if CanClick then Result := crHandPoint;
end;

Это несколько похоже на Карла ответ, но компенсируя тот факт, что Delphi не поддерживает одну операцию на оба набора результатов и возвращения.

Ключевым различием здесь является то, что это очень важно учитывать воздействие еще если против простых если. Например, если вы изменить порядок проверок, то необходимо реализовать следующим образом:

if CanClick then Result := crHandPoint;
if CanDragY then Result := crSizeNS;
if CanDragX then Result := crSizeWE;
if CanDragX and CanDragY then Result := crSizeAll;

Более прямой перевод ответа Карл может оказаться немного меньше ошибок, хотя и более многословно:

if CanDragX and CanDragY then
begin
Result := crSizeAll;
Exit;
end;
if CanDragX then
begin
Result := crSizeWE;
Exit;
end;
...

Даже тогда я подозреваю, что ошибки можно было бы легко сделать.
Хотя мне не нравится как солнечный и Сережи ответы, потому что они нуждаются в комментариях для выяснения, есть много, чтобы быть сказанным для явного сопоставления каждой перестановки. Рассмотрим следующие псевдо-код:

case [DragX, DragY, Click] of
[CanDragX, CanDragY, CanClick] : Result := crSizeAll;
[CanDragX, CanDragY, NotClick] : Result := crSizeAll;
[CanDragX, NotDragY, CanClick] : Result := crSizeWE;
[CanDragX, NotDragY, NotClick] : Result := crSizeWE;
[NotDragX, CanDragY, CanClick] : Result := crSizeNS;
[NotDragX, CanDragY, NotClick] : Result := crSizeNS;
[NotDragX, NotDragY, CanClick] : Result := crHandPoint;
[NotDragX, NotDragY, NotClick] : Result := crArrow;
end;

Было бы замечательно, если бы в Delphi перечислений и множеств поддерживает такой синтаксис, но подобное может быть достигнуто с помощью самодокументируемыми вариации Санни ответ:

const
cCannotDo = 0;
cCanDragX = 1;
cCanDragY = 2;
cCanClick = 4;
var
LMouseOptions: Integer;
begin
LMouseOptions := Ord(CanDragX)*cCanDragX +
Ord(CanDragY)*cCanDragY +
Ord(CanClick)*cCanClick;
case LMouseOptions of
cCanDragX + cCanDragY + cCanClick : Result := crSizeAll;
cCanDragX + cCanDragY + cCannotDo : Result := crSizeAll;
cCanDragX + cCannotDo + cCanClick : Result := crSizeWE;
cCanDragX + cCannotDo + cCannotDo : Result := crSizeWE;
cCannotDo + cCanDragY + cCanClick : Result := crSizeNS;
cCannotDo + cCanDragY + cCannotDo : Result := crSizeNS;
cCannotDo + cCannotDo + cCanClick : Result := crHandPoint;
cCannotDo + cCannotDo + cCannotDo : Result := crArrow;
else
//Either raise error or return crArrow as default
end;
end;

Однако, перестановки могут стать громоздкими, как больше флагов и даже многозначное добавляются опции. Поэтому лично я бы пошла на мой первый вариант, и реализовать модульные тесты по всем делам, представляющим интерес.

1
ответ дан 23 июня 2012 в 12:06 Источник Поделиться

Используя побитовое или, и предполагая, что это какая-то форма Паскаль, но то же самое относится к любому languiage:

VAR:
res : integer

res := (ord(CanClick) * 4) OR (ord(CanDragY) * 2) OR ord(CanDragX);
case res of
0: Result := crArrow; // 0 0 0
1, 5: Result := crSizeWE; // 0 0 1 or 1 0 1
2, 6: Result := crSizeNS; // 0 1 0 or 1 1 0
3, 7: Result := crSizeAll; // 0 1 1 or 1 1 1
4: Result := crHandPoint; // 1 0 0
end;

0
ответ дан 8 августа 2011 в 06:08 Источник Поделиться