Проблемы с проектированием ввода и вывода для приложения калькулятора - PullRequest
0 голосов
/ 15 апреля 2010

Пишу кнопочный калькулятор. У меня есть код, разделенный на модель, представление и контроллер. Модель ничего не знает о форматировании, она касается только чисел. Все форматирование выполняется в представлении. Модель получает свои данные в виде нажатий клавиш, каждое нажатие клавиши является частью перечисления:

typedef enum {

    kButtonUnknown        =   0,
    kButtonMemoryClear    = 100,
    kButtonMemoryPlus     = 112,
    kButtonMemoryMinus    = 109,
    kButtonMemoryRecall   = 114,
    kButtonClear          =  99,
    …
};

Когда пользователь нажимает кнопку (скажем, 1 ), модель получает код кнопки (kButtonNum1), добавляет соответствующий номер в буфер ввода строки ("1") и обновляет числовой выходное значение (1.0). Затем контроллер передает числовое выходное значение представлению, которое его форматирует (1).

Это все просто, просто и чисто, но на самом деле не работает. Проблема заключается в том, что, когда пользователь вводит часть числа (скажем, 0.00, собираясь ввести 0.001), ввод не сохраняется в процессе просмотра модели, и на дисплее отображается 0 вместо 0.00. Я знаю, почему это происходит ("0.00"::string анализирует 0::double, и это форматируется как 0). Чего я не знаю, так это как разработать калькулятор, чтобы код оставался чистым и простым, а цифры отображались на экране в точности так, как их набирает пользователь.

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

Идеи


Текущее решение отслеживает состояние калькулятора. Если калькулятор строит число, я беру входной буфер калькулятора (строку) и непосредственно устанавливаю содержимое дисплея (также строку). В противном случае я выбираю правильный путь, т.е. возьмите вывод числового калькулятора, передайте его представлению как double, и представление использует свой внутренний форматер для создания строки для отображения. Пример ввода:

input | display | mode
------+---------+------------
0     | 0       | from string
0.    | 0.      | from string
0.0   | 0.0     | from string
0.0+  | 0       | from number

Это безобразно. (1) Калькулятор должен выставить свой входной буфер и состояние. (2) Представление должно отображать свое отображение и позволять устанавливать его содержимое напрямую, используя строку. (3) Мне нужно продублировать часть кода форматирования, чтобы отформатировать строку, полученную из входного буфера калькулятора. Если пользователь вводит 12345.000, мне нужно отобразить 12,345.000, и поэтому у меня должен быть код исправления для строк. Тьфу.

Ответы [ 2 ]

1 голос
/ 15 апреля 2010

На моем калькуляторе (HP48SX) числа на дисплее отформатированы в соответствии с настройками отображения чисел. Прямо сейчас, если я введу 0.00 (или любой другой вариант), он отобразится как 0.0000. Возможно, вы могли бы отделить отображение (т.е. форматирование) от внутреннего представления чисел? С точки зрения MVC я предполагаю, что это будет реализовано как состояние в C.

РЕДАКТИРОВАТЬ в ответ на комментарий ОП. Я не совсем понимаю ограничения того, что вы называете кнопочным калькулятором, так что вы сами там. Что касается разделения, я бы разработал калькулятор так, чтобы:

  • Модель всегда работает с тем, что вы используете для представления чисел: числа с плавающей запятой, двойные числа, десятичные числа, что у вас есть.
  • Представление всегда работает со строками, которые хорошо представляют числа и позволяют пользователям вводить их по своему усмотрению.
  • Контроллер переводит из строки в число, из числа в строку. В моем первоначальном предложении я предполагал, что сам контроллер будет иметь состояние (например, сохраняя current-numeric-format) и быть адресуемым с помощью кнопок. Но вы, кажется, исключили это.

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

0 голосов
/ 16 апреля 2010

Наконец-то я нашел лучшее решение. Я добавил свойство inputHint к объекту форматирования, который заботится о форматировании вывода в представлении. Эта входная подсказка получает значение входного буфера калькулятора и влияет на форматирование. Если во входной подсказке есть десятичная точка, то средство форматирования вынуждено всегда сохранять десятичную точку на выходе, что решает проблему форматирования "0." как "0". И если вход содержит несколько цифр дроби, то средство форматирования вынуждено сохранять на выходе одинаковое количество цифр дроби (решает случай форматирования "0.00" как "0").

Мне по-прежнему необходимо предоставить входной буфер калькулятора и его состояние, но мне не нужно отображать отображение представления как строку, и мне не нужно поддерживать путь для кода дублирующего форматирования для строк.

...