2013-12-24 2 views
1

Connect.javaДобавить информацию интерфейс

public interface Connect { 
void commit(); 
void close(); 
void setTransactional(); 
void executeCommand(); 
} 

MainApp.java

public class MainApp { 
    public static void main(String[] args) { 
     Connect conn=MainApp.getTransactionalConnection(); 
     conn.executeCommand(); 
     conn.executeCommand(); 
     conn.executeCommand(); 
     conn.executeCommand(); 
     closeConnection(conn);  
    } 
    public static Connect getNormalConnection(){ 
     return DriverManager.getConnection(); //returns class i have no access to , dont even know its name 
    } 
    public static Connect getTransactionalConnection(){ 
     Connect conn = getNormalConnection(); 
     conn.setTransactional(); 
     return conn; 
    } 
    private static void closeConnection(Connect conn) { 
     //something like if connection is transactional then conn.commit(); 

     conn.close(); 
    } 

} 

я получил как 100 функций, которые выглядят как основной(). Проблема в том, что я не хочу менять код этих 100 функций и изменять только 1 строку getNormalConnection для getTransactionalConnection. У меня нет доступа и не знаю имен классов, реализующих интерфейс Connect. Я хочу только добавить commit для closeConnection(), создал ли я транзакционное соединение или нет.

ответ

0

Один простой ответ должен иметь свою собственную реализацию Connect, которые либо выставляет isTransactional свойство, или который автоматически совершает, когда это транзакционный, делегируя все остальное нижележащего связи:

public class AutoCommitConnect implements Connect { 
    private final Connect connect; 
    private boolean transactional = false; 
    private boolean committed = false; 

    public AutoCommitConnect(Connect delegate) { 
     this.delegate = delegate; 
    } 

    public void commit() { 
     delegate.commit(); 
     committed = true; 
    } 

    public void setTransactional() { 
     transactional = true; 
     delegate.setTransactional(); 
    } 

    public void close() { 
     if (transactional && !committed) { 
      commit(); 
     } 
     delegate.close(); 
    } 

    public void executeCommand() { 
     delegate.executeCommand(); 
    } 
} 

Затем изменить свой Соединения- возвращающие методы для его использования:

public static Connect getNormalConnection() { 
    // getTransactionalConnection will call setTransactional on the wrapper, 
    // which will remember that it needs to commit 
    return new AutoCommitConnect(DriverManager.getConnection()); 
} 
+0

Но что, когда Connect содержит 60 методов? Каждый из них мы должны «обернуть». Другим возможным решением было бы сделать внешнюю карту и сохранить ссылки с булевым isTransactional. Это очень легко реализовать, но для этого просто ситуация не рекомендуется? – MistyK

+0

@Zbigniew: В этот момент это другой вопрос - и я был бы глубоко подозрите к такому интерфейсу в целом. Обтекание довольно легко, хотя достойные IDE могут генерировать для вас весь этот код, а затем вам просто нужно решить, какие методы вы хотите обрабатывать по-разному. –

+0

http://pastebin.com/MfMvMAmT Что вы думаете об этом в C++? Я знаю, что это турбо-уродливое;] Он работает, но я думаю, что fancyPointer иногда может быть случайным числом, может быть, даже «5», поэтому он будет терпеть неудачу. – repo

0

Похоже, что вы хотите, чтобы классы реализации вашего интерфейса имели реализацию определенных методов по умолчанию?
Вы не можете сделать это с помощью интерфейса, это цель абстрактного класса. Это, конечно, означало бы, что вам понадобится extend абстрактный класс, а не implement интерфейс в каждом классе.

+1

Просто надстройка: перед изменением интерфейса к абстрактному классу вы также должны иметь в виду, что изменение интерфейса для абстрактного класса является двоичным несовместимым приемлемое изменение. Весь клиентский код необходимо перекомпилировать. –

Смежные вопросы