假设一个初始场景,之后我将成为修改过的有问题的案例。
interface Logger {
log() { }
}
class LogFile extends Logger {
log() { // log to file }
}
class LogDB extends Logger {
log() { // insert log into DB }
}
现在LogDB变成了类似的东西:
class LogDB {
logMySQL() { };
logMongo() { };
}
如何将此更改合并到LogDB中,同时我还希望它适合Logger接口?
答案 0 :(得分:2)
我认为最好制作LogDB
类的两个子类 - 一个用于处理MongoDB,另一个用于MySQL。
class LogMongoDB extends LogDB {
@Override
log() {
//persist the log in MongoDB
}
}
class LogMySQL extends LogDB {
@Override
log() {
//persist the log in MySQL
}
}
答案 1 :(得分:1)
如果LogDB
需要实现Log
,但还必须执行一些自定义日志记录,请根据接口的要求添加执行通用日志记录活动的函数,并从每个自定义版本调用它(反之亦然,视您的需要而定):
public void log() {
//Common logging stuff here
}
public void logDB() {
//Database-specific logging here...
log();
}
public void logMongo() {
//Mongo-specific logging here...
log();
}
但正如@kocko所说,你似乎正在将两种类型的日志记录混合到一个对象中,这就是为什么你首先要问这个问题的原因。按照他的建议拆分它,然后你就不会开始这个问题了。
答案 2 :(得分:1)
我的做法不同,不是继承,但成分。
interface Logger {
log(String message) { }
}
class LogFile extends Logger {
public LogFile(File file) {}
log(String message) { /* log to file */ }
}
class LogDB extends Logger {
private DBLogConf dbConf;
private DBAbstractionLayer dbal;
public LogDB(IDBLogConf dbConf, IDBAbstractionLayer dbal) {
this.dbConf = dbConf;
this.dbal = dbal;
}
log(String message) {
List<String> fields = new ArrayList<String>();
fields.add(dbConf.getLogField());
List<String> values = new ArrayList<String>();
fields.add(message);
dbal.insert(dbConf.getContainer(), fields, values);
}
}
interface IDBLogConf {
public String getContainer(); // table or document
public String getLogField();
}
class DBLogConf implements IDBLogConf { /* ... */ }
interface IDBAbstractionLayer {
public void insert(String container, List<String> fields, List<String> values) {
// ...
}
// other methods
}
class JDBCAbstractionLayer implements IDBAbstractionLayer {
private Connection conn;
public JDBCAbstractionLayer(Connection conn) {
this.conn = conn;
}
public function insert(...) { /* ... */}
}
abstract class NoSQLAbstractionLayer implements IDBAbstractionLayer {
// ...
}
class MongoAbstractionLayer extends NoSQLAbstractionLayer {
// ...
}
把这一切都放在一起:
IDBConf dbConf = new DBConf('log_table', 'details');
IDBAbstractionLayer dbal = new JDBCAbstractionLayer(/* some JDBC connection, */);
Logger dbLogger = new LogDb(dbConf, dbal);
dbLogger.log("Something");
Logger fileLlogger = new LogFile(new File('/var/log/my_log'));
fileLogger.log("Something");
然而,这似乎比上述示例更复杂,此实现不违反SRP并避免代码重复。