TODO: отвалидировать – текст собран автоматически из материалов курса на Google Drive, проверьте формулировки и код.
В контексте GRASP полиморфизм решает конкретную проблему: обработку альтернативных вариантов поведения на основе типа.
Решать её стоит полиморфными операциями, а не проверкой типа и условной логикой. Тогда
систему можно расширять, добавляя новые вариации, а не дописывая ветки в существующий
switch.
// Проверка типа: каждый новый формат – правка этого метода
public string Export(Report report, string format)
{
if (format == "pdf") return ExportPdf(report);
if (format == "csv") return ExportCsv(report);
throw new NotSupportedException(format);
}
// Полиморфизм: новый формат – новый класс, старый код не трогаем
public interface IReportExporter
{
string Export(Report report);
}
public class PdfExporter : IReportExporter { public string Export(Report r) => ""; }
public class CsvExporter : IReportExporter { public string Export(Report r) => ""; }
// Проверка значения: каждый новый формат – правка этой функции
std::string Export(const Report& report, const std::string& format) {
if (format == "pdf") return ExportPdf(report);
if (format == "csv") return ExportCsv(report);
throw std::invalid_argument("формат не поддерживается: " + format);
}
// Полиморфизм: новый формат – новый класс, старый код не трогаем
class IReportExporter {
public:
virtual std::string Export(const Report& report) const = 0;
virtual ~IReportExporter() = default;
};
class PdfExporter : public IReportExporter {
public:
std::string Export(const Report& report) const override { return ""; }
};
class CsvExporter : public IReportExporter {
public:
std::string Export(const Report& report) const override { return ""; }
};
// Проверка значения: каждый новый формат – правка этой функции
func Export(report Report, format string) (string, error) {
switch format {
case "pdf":
return exportPDF(report), nil
case "csv":
return exportCSV(report), nil
}
return "", fmt.Errorf("формат не поддерживается: %s", format)
}
// Полиморфизм через интерфейс: новый формат – новый тип
type ReportExporter interface {
Export(report Report) string
}
type PDFExporter struct{}
func (PDFExporter) Export(r Report) string { return "" }
type CSVExporter struct{}
func (CSVExporter) Export(r Report) string { return "" }
# Проверка типа: каждый новый формат – правка этой функции
def export(report: Report, fmt: str) -> str:
if fmt == "pdf":
return export_pdf(report)
if fmt == "csv":
return export_csv(report)
raise ValueError(f"формат не поддерживается: {fmt}")
# Полиморфизм: новый формат – новый класс
from typing import Protocol
class ReportExporter(Protocol):
def export(self, report: Report) -> str: ...
class PdfExporter:
def export(self, report: Report) -> str:
return ""
class CsvExporter:
def export(self, report: Report) -> str:
return ""
// Проверка типа: каждый новый формат – правка этой функции
function exportReport(report: Report, format: string): string {
if (format === "pdf") return exportPdf(report);
if (format === "csv") return exportCsv(report);
throw new Error(`формат не поддерживается: ${format}`);
}
// Полиморфизм: новый формат – новый класс
interface ReportExporter {
export(report: Report): string;
}
class PdfExporter implements ReportExporter {
export(report: Report): string {
return "";
}
}
class CsvExporter implements ReportExporter {
export(report: Report): string {
return "";
}
}
// Проверка типа: каждый новый формат – правка этого метода
public String export(Report report, String format) {
if (format.equals("pdf")) return exportPdf(report);
if (format.equals("csv")) return exportCsv(report);
throw new UnsupportedOperationException(format);
}
// Полиморфизм: новый формат – новый класс
public interface ReportExporter {
String export(Report report);
}
public class PdfExporter implements ReportExporter {
public String export(Report report) { return ""; }
}
public class CsvExporter implements ReportExporter {
public String export(Report report) { return ""; }
}
// Проверка типа: каждый новый формат – правка этой функции
fun export(report: Report, format: String): String = when (format) {
"pdf" -> exportPdf(report)
"csv" -> exportCsv(report)
else -> throw UnsupportedOperationException(format)
}
// Полиморфизм: новый формат – новая реализация
fun interface ReportExporter {
fun export(report: Report): String
}
class PdfExporter : ReportExporter {
override fun export(report: Report): String = ""
}
class CsvExporter : ReportExporter {
override fun export(report: Report): String = ""
}
Тот же принцип лежит в основе паттернов Strategy и State из последнего модуля курса.