Мне нужно распечатать обычный отчет и пакетный отчет. Я использую библиотеку podofo. Я планирую использовать отдельные классы для каждого отчета, но каждый класс будет нуждаться в некоторых общих функциях ниже (прямо сейчас в одном классе в другом проекте).
int CPdfBatchReport::CalculateMaxRowsInEmptyPage(void)
{
int rows = MaxPageHeight / PDF_TABLE_STANDARD_ROW_HEIGHT;
// because the first will always be the column header in every page, we substrct 1 to account for that
rows = rows - 1;
return rows;
}
// Calculates the max rows in current page. The current page is determined
// by the current x, y position
int CPdfBatchReport::CalculateMaxRowsInCurrentPage(void)
{
float AvailablePageHeight = pPage->GetPageSize().GetHeight() - PDF_BOTTOM_MARGIN - y;
int rows = AvailablePageHeight / PDF_TABLE_STANDARD_ROW_HEIGHT;
// because the first will always be the column header in every page, we substrct 1 to account for that
rows = rows - 1;
return rows;
}void CPdfBatchReport::StartPage(void)
{
x = PDF_LEFT_RIGHT_MARGIN;
y = PDF_TOP_MARGIN;
}
Имеет ли смысл создавать базовый класс с этим общим кодом и выполнять фактическую печать в производном классе? Это хорошая практика?
Так что в основном у меня будет базовый класс сказать PrintBase
с вышеуказанными функциями в нем и двумя производными классами из него PrintBatchReport
а также PrintItemReport
который на самом деле будет использовать эти функции.
Да, абсолютно хорошая идея поместить общий код в базовый класс. «Не повторяй себя» — сухой — это хороший стиль программирования. Избегайте копирования-вставки программирования.
Единственный раз, когда вам не нужен контент в базовом классе, это когда это интерфейсный класс. Но это не похоже на случай в этой ситуации.
Да, абсолютно хорошая идея поместить общий код в базовый класс.
Я хотел бы расширить ответ @Mats. Это действительно хорошая идея, поскольку весь код, который вы извлекаете в базовый класс, следует принципу единой ответственности. Избегайте слепого использования наследования для обычного извлечения кода. Объектно-ориентированное программирование — это нечто большее.
Подумай об обязанностях. Во многих случаях вы должны отдавать предпочтение композиции, а не наследованию. Вам действительно нужен родительский класс для вашей задачи? Может быть, существующая функциональность охватывает несколько обязанностей и может быть разделена на несколько классов, которые ваши PrintBase
может быть передан или создан внутри.
Это кажется вполне разумным решением. В этом случае вы наследуете общую реализацию, поэтому я настоятельно рекомендую использовать частное наследование, а не общедоступное. Затем вы просто создаете правильный дочерний класс для выполнения работы. Это, безусловно, лучший подход, чем дублирование кода в нескольких классах.
Другой вариант заключается в том, чтобы инкапсулировать общие параметры / функциональные возможности в третий класс, и чтобы каждый из конкретных отчетов имел один из этих классов по значению, делегируя различные обязанности вспомогательному классу.