|
1 | 1 | --- |
2 | 2 | rule_id: 1580 |
3 | 3 | rule_category: maintainability |
4 | | -title: Write code that is easy to debug |
5 | | -severity: 2 |
| 4 | +title: Consider duplicating simple logic across modules to reduce coupling |
| 5 | +severity: 3 |
6 | 6 | --- |
7 | | -Because debugger breakpoints cannot be set inside expressions, avoid overuse of nested method calls. For example, a line like: |
| 7 | +The DRY principle (Don't Repeat Yourself) is valuable within a bounded context, but applying it blindly across module or service boundaries can introduce coupling that is harder to manage than a small amount of duplication. |
8 | 8 |
|
9 | | - string result = ConvertToXml(ApplyTransforms(ExecuteQuery(GetConfigurationSettings(source)))); |
| 9 | +If sharing a tiny piece of logic between two separate modules would require: |
| 10 | +- Adding a dependency on a shared library that both modules must coordinate upgrades for. |
| 11 | +- Exposing internal types or contracts across a boundary. |
| 12 | +- Introducing a third project or package just to hold a few lines of code. |
10 | 13 |
|
11 | | -requires extra steps to inspect intermediate method return values. On the other hard, were this expression broken into intermediate variables, setting a breakpoint on one of them would be sufficient. |
| 14 | +…then duplicating the logic is often the simpler choice. |
12 | 15 |
|
13 | | -**Note** This does not apply to chaining method calls, which is a common pattern in fluent APIs. |
| 16 | +```csharp |
| 17 | +// In Module A |
| 18 | +private static bool IsValidEmail(string value) |
| 19 | + => value.Contains('@') && value.Contains('.'); |
| 20 | + |
| 21 | +// In Module B — a small duplication is fine here |
| 22 | +private static bool IsValidEmail(string value) |
| 23 | + => value.Contains('@') && value.Contains('.'); |
| 24 | +``` |
| 25 | + |
| 26 | +This applies primarily to: |
| 27 | +- Small utility functions (a few lines of code). |
| 28 | +- Logic that is stable and unlikely to change frequently. |
| 29 | +- Logic that doesn't carry domain meaning that must remain consistent. |
| 30 | + |
| 31 | +For complex or domain-critical logic that must be consistent everywhere, a shared library is still the right choice. |
0 commit comments