Помогите реструктурировать мой Doc/View более правильно

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

В другом посте я спросил о том, как оставить MFC DocView и перейти к циклу WinProc & Message Loop (как это называется для краткости?). Ну, в настоящее время я думаю, что я должен очистить то, что у меня есть в Doc View, и, возможно, позже преобразовать его в не-MFC, что даже имеет смысл. В моем классе Document сейчас нет ничего полезного.

Я думаю, что начинать нужно с функции InitInstance() (размещена ниже).
В этой части:

POSITION pos=pDocTemplate->GetFirstDocPosition();
CLCWDoc *pDoc=(CLCWDoc *)pDocTemplate->GetNextDoc(pos);
ASSERT_VALID(pDoc);
POSITION vpos=pDoc->GetFirstViewPosition();
CChildView *pCV=(CChildView *)pDoc->GetNextView(vpos);

Это кажется странным для меня. У меня только один документ и один вид. Я чувствую, что я иду об этом в обратном направлении с GetNextDoc() и GetNextView(). Пытаться использовать глупую аналогию; Как будто у меня в руке книга, но я должен посмотреть в ее указателе, чтобы узнать, на какой странице находится заголовок книги. Я устал чувствовать смущение по поводу моего кода. Мне либо нужна коррекция, либо уверенность, либо и то и другое.:)

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

ВСЕ предложения приветствуются!

BOOL CLCWApp::InitInstance()
{
 InitCommonControls();
 if(!AfxOleInit())
  return FALSE;

    // Initialize the Toolbar dll. (Toolbar code by Nikolay Denisov.)
 InitGuiLibDLL(); // NOTE: insert GuiLib.dll into the resource chain

 SetRegistryKey(_T("Real Name Removed"));

 // Register document templates
 CSingleDocTemplate* pDocTemplate;
 pDocTemplate = new CSingleDocTemplate(
  IDR_MAINFRAME,
  RUNTIME_CLASS(CLCWDoc),
  RUNTIME_CLASS(CMainFrame),
  RUNTIME_CLASS(CChildView));
 AddDocTemplate(pDocTemplate);

 // Parse command line for standard shell commands, DDE, file open
 CCmdLineInfo cmdInfo;
 ParseCommandLine(cmdInfo);

 // Dispatch commands specified on the command line
 // The window frame appears on the screen in here.
 if (!ProcessShellCommand(cmdInfo))
 {
  AfxMessageBox("Failure processing Command Line");
  return FALSE;
 }

 POSITION pos=pDocTemplate->GetFirstDocPosition();
 CLCWDoc *pDoc=(CLCWDoc *)pDocTemplate->GetNextDoc(pos);
 ASSERT_VALID(pDoc);
 POSITION vpos=pDoc->GetFirstViewPosition();
 CChildView *pCV=(CChildView *)pDoc->GetNextView(vpos);
 if(!cmdInfo.m_Fn1.IsEmpty() && !cmdInfo.m_Fn2.IsEmpty())
 {
  pCV->OpenF1(cmdInfo.m_Fn1);
  pCV->OpenF2(cmdInfo.m_Fn2);
  pCV->DoCompare(); // Sends a paint message when complete
 }
 // enable file manager drag/drop and DDE Execute open
 m_pMainWnd->DragAcceptFiles(TRUE);

 m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
 m_pMainWnd->UpdateWindow(); // paints the window background

 pCV->bDoSize=true; //Prevent a dozen useless size calculations

 return TRUE;
}

Спасибо

1 ответ

Решение

Трудно дать вам хорошие рекомендации, не зная, что будет делать ваша программа. У меня есть только несколько общих замечаний:

  • Ваш InitInstance не выглядит очень запутанным для меня. Это довольно стандартно с небольшим количеством нестандартного кода.
  • Также, насколько мне известно, стандартная конструкция для извлечения первого представления из класса приложения (цепочка GetDocTemplate -> GetDoc -> GetView) является стандартной. Я на самом деле не знаю другого пути. Вы можете подумать о переносе его в отдельный метод, такой как CChildView* CLCWApp::GetFirstView() но это только косметика, если она нужна только в одном месте.

Что вы делаете и какие данные вы помещаете в свой класс Document и в класс (ы) View - это больше семантический вопрос, если у вас есть только одно представление. (В любом случае у вас есть только один документ, потому что это приложение SDI.) С технической точки зрения часто возможно и то и другое. Но чтобы быть открытыми (возможно) для более поздних расширений более чем одного представления и следовать стандартному шаблону архитектуры документа / представления, есть несколько практических правил:

  • Данные, которые существуют и имеют значение, не зависящее от способа их представления и просмотра (файл документа, дескриптор базы данных и т. Д.), Принадлежат классу документа. Я не знаю, что ты pCV->OpenF1(cmdInfo.m_Fn1) ... and so on делает, но если это что-то вроде файла или имени файла или параметра, который будет использоваться для доступа к данным любым способом OpenF1 может быть лучше метод класса документа.
  • Методы, которые выполняют любые виды обработки или модификации ваших базовых данных, также относятся к классу документов.
  • Данные и методы, которые необходимы только для определенного способа отображения документа, принадлежат к классу представления (например, выбранный шрифт, цвета и т. Д.)
  • С другой стороны: если у вас есть фиксированное количество представлений, которые открываются вместе с документом, возможно, было бы неправильно поместить определенные данные представления в документ, особенно если вы хотите, чтобы эти параметры представления были постоянными. Примером может служить файл с некоторыми статистическими данными - ваш документ - и разделительный фрейм с двумя представлениями: одно отображает данные в виде таблицы сетки, а другое - в виде круговой диаграммы. В таблице есть "данные просмотра", описывающие порядок и ширину столбцов, например, круговая диаграмма содержит данные для настройки цветов круговых частей и расположения легенды. Если вы хотите убедиться, что пользователь получает последнюю конфигурацию вида, отображаемую при открытии файла документа, вы должны где-то сохранить эти параметры вида. По моему мнению, было бы неправильно или плохо проектировать эти параметры в документе, хранить их и извлекать из любого постоянного хранилища, даже если они нужны только в классах представлений.
  • Если ваше приложение позволяет динамически открывать неограниченное количество представлений для документа, и эти представления являются временными, пока приложение выполняется, сохранение всех параметров конфигурации представления непосредственно в классах представлений кажется мне более естественным. В противном случае в документе вам потребуется управлять любой динамической структурой данных и установить связь между представлением и записью в этой структуре данных (индекс в массиве или ключ на карте и т. Д.).
  • Если вы сомневаетесь, размещать ли какие-либо данные в документе или в классе просмотра, я бы предпочел документ, потому что у вас всегда есть легкий GetDocument() метод доступа в классе View для извлечения членов или вызова методов документа. Для извлечения данных из представления в документ требуется выполнить итерацию по списку представлений. (Помните: Doc-View - это отношение 1-n, даже в приложении SDI.)

Всего несколько центов.

Другие вопросы по тегам