- Ask a coworker
- Search the codebase
- Google it
- Trial and error
- Step-by-step debugging
- "Debug sniping" - pause the program at the 'right' time and hope you’ve stopped at a useful place
public enum BreakPointLocator {
ToJson {
@Override
public void locate() {
• doNothing();
}
@Override
public <T> T locate(T input) {
• return input;
}
},
SqlQuery {
@Override
public void locate() {
doNothing();
}
@Override
public <T> T locate(T input) {
// Example: inspect or log SQL query before execution
if (input instanceof String) {
String sql = (String) input;
if (sql.contains("UserTable")){
• System.out.println("Executing SQL: " + sql);
}
}
return input;
}
},
SqlResult {
@Override
public void locate() {
doNothing();
}
@Override
public <T> T locate(T input) {
return input;
}
},
ValidationError {
@Override
public void locate() {
doNothing();
}
@Override
public <T> T locate(T input) {
return input;
}
},
Exception {
@Override
public void locate() {
doNothing();
}
@Override
public <T> T locate(T input) {
return input;
}
},
;
public abstract void locate();
public abstract <T> T locate(T input);
// Optional method for computation-heavy debugging
// Don't include it by default.
// supplier.get() should never be called by default
public <T> java.util.function.Supplier<T> locate(java.util.function.Supplier<T> supplier);
public static void doNothing() { /* intentionally empty */ }
}
Binding:
public String buildJson(Object data) {
BreakPointLocator.ToJson.locate(data);
String json = toJson(data); // your existing JSON conversion
return json;
}
public <T> T executeSqlQuery(String sql, Class<T> resultType) {
BreakPointLocator.SqlQuery.locate(sql);
T result = runQuery(sql, resultType);
return result;
}
- Each time that we identify a useful debug point, or logic location that is time consuming, we can add new element to BreakPointLocator or use existing one.
- When we have multiple project, we can extend naming convention to BreakPointLocator4${ProjectName}.
- Debug logic is for us to change, including runtime.
The value of this solution is directly proportional to project complexity, the amount of conventions and frameworks in the company, as well as the specialization of developers.
- New blood can became fluent in legacy systems much faster.
- We have a much higher chance of changing service code without breaking program state while debugging (most changes would be are localized to the enum).
- We are able to connect breakpoints & code & runtime in one coherent mechanism.
- Greatly reducting hot swapping fail rate.
- All control goes through breakpoints, so there is no need to introduce an additional control layer(like switches that needs controll).
- Debug logic can be shared and reused if needed.
- This separate layer protects us from accidentally re‑run business logic and corrupting the data.
- We don’t need to copy‑paste code into multiple breakpoints.
- The risk of mixing debug and business logic is greatly reduced.
0 comments / komentarz(y):
Post a Comment