Sometimes, the logic stored into a class is shared by several departments (i. e. Sales and Accounting). The issue here is that both departments control that class; so, potentially you are violating the SRP principle too.
You should refactor this class so the logic business of it goes to splitted classes, each one for each department. This way, you don't violate this principle. The shared logic business should go to the Shared folder at your project.
Hello @Abelardo, Great point! You've highlighted a common misconception about SRP that's worth clarifying.
The scenario you describe - where Sales and Accounting both use the same class - doesn't automatically violate SRP. The key is distinguishing between "who uses the class" vs "what the class is responsible for."
SRP is about having one reason to change, not one user.
For example:
A TaxCalculator class used by both Sales and Accounting still has a single responsibility: calculating taxes
An Invoice class used by multiple departments still has one job: representing invoice data and behavior
However, you're absolutely right about the control issue. If both departments want to modify the class for their specific needs, that's when we have a problem. Here's how I'd approach it:
Keep shared business logic centralized when it represents a single responsibility
Use composition/delegation rather than splitting: Have department-specific classes that use the shared logic
Apply the Interface Segregation Principle: Create department-specific interfaces so each only sees what they need
Here is an example:
public class TaxCalculator {
public BigDecimal calculateTax(BigDecimal amount, BigDecimal rate) {
return amount.multiply(rate);
}
public BigDecimal calculateSalesTax(BigDecimal amount) {
return calculateTax(amount, new BigDecimal("0.08"));
}
}
public class SalesTaxService {
private TaxCalculator taxCalculator;
public SalesTaxService(TaxCalculator calculator) {
Sometimes, the logic stored into a class is shared by several departments (i. e. Sales and Accounting). The issue here is that both departments control that class; so, potentially you are violating the SRP principle too.
You should refactor this class so the logic business of it goes to splitted classes, each one for each department. This way, you don't violate this principle. The shared logic business should go to the Shared folder at your project.
Thoughts?
Hello @Abelardo, Great point! You've highlighted a common misconception about SRP that's worth clarifying.
The scenario you describe - where Sales and Accounting both use the same class - doesn't automatically violate SRP. The key is distinguishing between "who uses the class" vs "what the class is responsible for."
SRP is about having one reason to change, not one user.
For example:
A TaxCalculator class used by both Sales and Accounting still has a single responsibility: calculating taxes
An Invoice class used by multiple departments still has one job: representing invoice data and behavior
However, you're absolutely right about the control issue. If both departments want to modify the class for their specific needs, that's when we have a problem. Here's how I'd approach it:
Keep shared business logic centralized when it represents a single responsibility
Use composition/delegation rather than splitting: Have department-specific classes that use the shared logic
Apply the Interface Segregation Principle: Create department-specific interfaces so each only sees what they need
Here is an example:
public class TaxCalculator {
public BigDecimal calculateTax(BigDecimal amount, BigDecimal rate) {
return amount.multiply(rate);
}
public BigDecimal calculateSalesTax(BigDecimal amount) {
return calculateTax(amount, new BigDecimal("0.08"));
}
}
public class SalesTaxService {
private TaxCalculator taxCalculator;
public SalesTaxService(TaxCalculator calculator) {
this.taxCalculator = calculator;
}
public BigDecimal processOrderTax(Order order) {
return taxCalculator.calculateSalesTax(order.getAmount());
}
}
public class AccountingTaxService {
private TaxCalculator taxCalculator;
public AccountingTaxService(TaxCalculator calculator) {
this.taxCalculator = calculator;
}
public TaxReport generateTaxReport(List<Transaction> transactions) {
// Use taxCalculator for accounting-specific tax operations
return new TaxReport();
}
}
This way we can avoid code duplication while maintaining clear ownership boundaries. What's your experience been with this approach?
It's ok, since I am confused about the SRP.
Thank you for clarifying that, Soma!
Warmest regards.