Моя кодовая база на Python. Допустим, у меня есть довольно общий класс под названием Report. Требуется большое количество параметров
class Report(object):
def __init__(self, title, data_source, columns, format, ...many more...)
И есть много много экземпляров Отчета. Эти реализации не совсем не связаны. Многие отчеты имеют одинаковый набор параметров, различаются лишь незначительными изменениями, например, имеют одинаковый источник данных и столбцы, но с другим заголовком.
Вместо дублирования параметров применяется некоторая программная конструкция, чтобы упростить выражение этой структуры. И я пытаюсь найти какую-то помощь, чтобы разобраться в моей голове, чтобы определить какую-то идиому или шаблон дизайна для этого.
Если подкатегория отчета нуждается в дополнительном коде обработки, подкласс является хорошим выбором. Скажем, у нас есть подкатегория ExpenseReport.
class ExpenseReport(Report):
def __init__(self, title, ... a small number of parameters ...)
# some parameters are fixed, while others are specific to this instance
super(ExpenseReport,self).__init__(
title,
EXPENSE_DATA_SOURCE,
EXPENSE_COLUMNS,
EXPENSE_FORMAT,
... a small number of parameters...)
def processing(self):
... extra processing specific to ExpenseReport ...
Но во многих случаях подкатегория просто фиксирует некоторые параметры без какой-либо дополнительной обработки. Это легко сделать с помощью частичной функции.
ExpenseReport = functools.partial(Report,
data_source = EXPENSE_DATA_SOURCE,
columns = EXPENSE_COLUMNS,
format = EXPENSE_FORMAT,
)
А в некоторых случаях даже нет никакой разницы. Нам просто нужно 2 копии одного и того же объекта для использования в разных средах, например, для встраивания в разные страницы.
expense_report = Report("Total Expense", EXPENSE_DATA_SOURCE, ...)
page1.add(expense_report)
...
page2.add(clone(expense_report))
И в моей кодовой базе используется уродливая техника. Поскольку нам нужно 2 отдельных экземпляра для каждой страницы и поскольку мы не хотим дублировать код с длинным списком параметров, создающих отчет, мы просто клонируем (глубокая копия в Python) отчет для страницы 2. Не только необходимость клонирование не очевидно, пренебрежение клонированием объекта и совместное использование одного экземпляра создает множество скрытых проблем и тонких ошибок в нашей системе.
Есть ли какие-либо указания в этой ситуации? Подкласс, частичная функция или другая идиома? Я хочу, чтобы эта конструкция была легкой и прозрачной. Я немного опасаюсь подклассов, потому что это может привести к джунглям подклассов. И это побуждает программиста добавлять специальный код обработки, подобный тому, что у меня есть в ExpenseReport. Если есть необходимость, я лучше проанализирую код, чтобы выяснить, можно ли его обобщить, и перенести на уровень отчета. Так что отчет становится более выразительным, не требуя специальной обработки на нижних уровнях.
Дополнительная информация
Мы используем параметр ключевого слова. Проблема скорее в том, как управлять и организовывать реализацию. У нас есть большое количество экземпляров с общими шаблонами:
expense_report = Report("Expense", data_source=EXPENSE, ..other common pattern..)
expense_report_usd = Report("USD Expense", data_source=EXPENSE, format=USD, ..other common pattern..)
expense_report_euro = Report("Euro Expense", data_source=EXPENSE, format=EURO, ..other common pattern..)
...
lot more reports
...
page1.add(expense_report_usd)
page2.add(expense_report_usd) # oops, page1 and page2 shared the same instance?!
...
lots of pages
...