Clean Code (Part 2)
+++ +++
Comments
Don’t comment bad code—rewrite it.
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
or
if (employee.isEligibleForFullBenefits())
Classes
public class Sql {
public Sql(String table, Column[] columns)
public String create()
public String insert(Object[] fields)
public String selectAll()
public String findByKey(String keyColumn, String keyValue)
public String select(Column column, String pattern)
public String select(Criteria criteria)
public String preparedInsert()
private String columnList(Column[] columns)
private String valuesList(Object[] fields, final Column[] columns)
private String selectWithCriteria(String criteria)
private String placeholderList(Column[] columns)
}
-
Reason to change -
Sql
will change when adding new type. - Modifyselect
to support subqueries Violate SRP -
Solution:
abstract public class Sql {
public Sql(String table, Column[] columns)
abstract public String generate();
}
public class CreateSql extends Sql {
public CreateSql(String table, Column[] columns)
@Override public String generate()
}
public class SelectSql extends Sql {
public SelectSql(String table, Column[] columns)
@Override public String generate()
}
public class InsertSql extends Sql {
public InsertSql(String table, Column[] columns, Object[] fields)
@Override public String generate()
private String valuesList(Object[] fields, final Column[] columns)
}
public class SelectWithCriteriaSql extends Sql {
public SelectWithCriteriaSql(
String table, Column[] columns, Criteria criteria)
@Override public String generate()
}
public class SelectWithMatchSql extends Sql {
public SelectWithMatchSql(
String table, Column[] columns, Column column, String pattern)
@Override public String generate()
}
public class FindByKeySql extends Sql {
public FindByKeySql(
String table, Column[] columns, String keyColumn, String keyValue)
@Override public String generate()
}
public class PreparedInsertSql extends Sql {
public PreparedInsertSql(String table, Column[] columns)
@Override public String generate() {
private String placeholderList(Column[] columns)
}
public class Where {
public Where(String criteria)
public String generate()
}
public class ColumnList {
public ColumnList(Column[] columns)
public String generate()
}
}
Seperate of main
// Seperate of main: the main only care the config (how to setting config to run)
function main() {
function build() {
return new Builder();
}
function run() {
const configObj = build().create();
const app = new Application(configObj);
app.run();
}
return run;
}
class Builder {
create() {
return new ConfigObject("A", "B");
}
}
class ConfigObject {
constructor(setting1, setting2) {
this.setting1 = setting1;
this.setting2 = setting2;
}
}
// Seperate of concern: the application only care the ConfigObject
class Application {
constructor(configObj) {
this.configObj = configObj;
}
run() {
console.log("App running with config: ", this.configObj);
}
}
main()();
main()();