2

У нас был семинар, на котором я представил принцип единой ответственности перед моей командой, чтобы мы использовали его в наших проектах. Я использовал следующий популярный пример:Должен ли я добавлять новые методы в класс вместо использования принципа единой ответственности

class Employee: 
    save() 
    calculate_salary() 
    generate_report() 

И я попросил команду, чтобы сказать все ли в порядке с этим классом. Все сказали мне, что все в порядке. Но я вижу три нарушения принципа SRP здесь. Я прав, если скажу, что все методы должны быть извлечены из класса? Мои рассуждения:

save() метод является причиной изменения, если изменить нашу базу данных.

метод calculate_salary() является причиной изменения, поскольку политика зарплаты может измениться.

метод generate_report() является причиной изменения, если мы хотим изменить представление отчета (т. Е. Csv вместо html).

Давайте рассмотрим последний метод. Я придумал следующий класс HtmlReportGenerator.

class HTMLReportGenerator: 
    def __init__(self, reportable): 
     self.reportable = reportable 

    def generate_csv_report() 

class CSVReportGenerator: 
    def __init__(self, reportable): 
     self.reportable = reportable 

    def generate_html_report() 

Теперь, даже если бизнес-логика этого генератора изменяется, он не касается класса Employee, и это было моим основным моментом. Более того, теперь мы можем повторно использовать эти классы для объектов, отличных от объектов класса Employee.

Но команда придумала другой класс:

class Employee: 
    save() 
    calculate_salary() 
    generate_html_report() 
    generate_csv_report() 

Они понимают, что они нарушают SRP, но это хорошо для них.

И это, где у меня не было никаких других идей, чтобы бороться за))

Любые идеи о ситуации?

+2

«Они понимают, что они нарушают SRP». Я не могу поверить, что они это понимают. СРП означает конец. Эта цель - ремонтопригодность. Часто бывает трудно увидеть преимущества разделения классов, рассматривая такой маленький пример в изоляции. – Steven

+0

Да. Понятно, что проблемы возникают, когда система растет.Но они считают, что слишком сложно создать новый класс для каждого типа отчетов. Так же проще добавлять новый метод каждый раз. У меня просто нет идей, как понять, что система должна быть масштабируемой с самого начала) –

+0

Этот вопрос, вероятно, принадлежит программистам, а не SO. – plalx

ответ

1

Я согласен с вами, добавив дополнительные функции, которые они нарушили как SRP, так и принцип открытия/закрытия, и каждый раз, когда будет новый тип отчета, они будут нарушать его снова.

Я бы сохранил функцию generate_report(), но добавил параметр из интерфейса. Тип «ReportType», который имеет функцию generate().

Это означает, что, например, вы можете позвонить (простите мой Java):

employee.generate_report(new CSVReport()) 

employee.generate_report(new HTMLReport()) 

И завтра, если вы хотите добавить отчет XML вы просто реализовать XMLReport из интерфейса отчетов и вызова:

employee.generate_report(new XMLReport()) 

Это дает вам большую гибкость, не требует изменения сотрудника для новых типов отчетов и гораздо проще тестировать (например, если у generate_report была сложная логика, вы могли бы просто создать класс TestReport, который реализует интерфейс Report и просто печатает на выходной поток для отладки и вызова generate_report (новый TestReport())

Смежные вопросы