Моя база кода находится в 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))
И в моей базе кода используется уродливая техника. Поскольку нам нужны два отдельных экземпляра для каждой страницы, и потому что мы не хотим дублировать код с длинным списком параметров, который создает отчет, мы просто клонируем (deepcopy in 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
...
О клоне и его проблемах. Может быть, вы можете использовать копию аргументов ключевого слова? 'report_args = dict (title = 'Some tile', data_source = ..., columns = ..., format = ...)' then' cost_report1 = Report (** report_args), cost_report2 = Report (** report_args) ' – reclosedev
И мне непонятно, какие типы аргументов вы используете, но если у вас есть метод, который принимает большое количество параметров, я думаю, что в этой ситуации использовать аргументы ключевого слова. Несколько хороших примеров в [SO question] (http://stackoverflow.com/q/1098549/1052325) – reclosedev