Answer the question
In order to leave comments, you need to log in
How to decorate a composition?
interface Transaction {
begin()
commit()
rollback()
}
interface Connection {
transaction()
query(queryString)
}
interface Connection {
query(queryString)
}
LoggedConnection implements Connection {
LoggedConnection(Connection connection) {...}
query(queryString) {
this.log.append(queryString);
return this.connection.query(queryString);
}
}
LazyConnection implements Connection {
query(queryString) {
if (!connected) {
this.connection.connect();
}
return this.connection.query(queryString);
}
}
Connection loggedConnection = new LoggedConnection(connection);
// здесь логируется
methodToLog(loggedConnection);
// loggedConnection.getLog();
// а здесь уже нет
anotherMethod(connection);
interface Transaction {
begin()
commit()
rollback()
}
interface Connection {
transaction()
query(queryString)
}
PgTransaction implements Transaction {
PgTransaction(connection) {...}
begin(){
this.connection.query("BEGIN");
}
}
PgConnection implements Connection {
PgConnection() {
this.transaction = new PgTransaction(this); // this мы декорировать извне не сможем
}
}
// Плюс: интуитивно понятная реализация
// Минус: лишняя логика в Connection
// Минус: надо отлавливать ошибки, чтобы логгер не остался в подключении
interface ConnectionLoggers {
add(logger)
remove(logger)
log(query)
}
Connection {
// ...
ConnectionLoggers loggers()
// ...
}
logger = new ConnectionLogger();
connection.loggers().add(logger);
try {
someMethod(connection);
// logger.getLog();
} finally {
connection.loggers().remove(logger);
}
// Плюс: можно декорерировать
// Минус: Менее удобен при вызове Transaction
// Минус: в begin() технически можно кинуть другое соединение (другое подключене к БД), что может нарушить логику работы
interface Transaction {
begin(connection)
commit(connection)
rollback(connection)
}
// вызов
connection.transaction.begin(connection);
// Плюс: можно декорерировать
// Плюс: удобно вызывать методы транзакции
interface Transaction {
begin()
commit()
rollback()
// Создаем новый экземпляр Transaction, с тем же состоянием транзакции, но другим соединением.
// Оба экземпляра будут разделять одно и то же состояние (в тразакции или нет, уровень вложенности, уровень изоляции).
// Минус: В clone() технически можно кинуть другое соединение, что может нарушить логику работы.
// Минус: Интуитивно непонятно как должен быть реализован метод clone()
// Минус: clone() виден "пользователям" при работе с транзакциями.
Transaction clone(newConnection);
}
PgTransaction implements Transaction {
private bool inTransaction;
PgTransaction(Connection connection, TransactionState state) {
}
clone(c) {
new PgTransaction(c, this.getState())
}
}
LoggedConnection {
LoggedConnection(Connection connection) {
thix.txn = c.transaction().clone(this);
}
}
// вызов
connection.transaction.begin();
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question