Помогите реструктурировать мой 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.)
Всего несколько центов.