Add information to interface

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();
    }

}

I got like 100 functions which look like main(). The problem is I don't want to change the code of these 100 functions and only change 1 line getNormalConnection to getTransactionalConnection . I don't have access and don't know names of classes implementing Connect interface . I want only to add commit to closeConnection() whether I created a transactional connection or not .

Jon Skeet
people
quotationmark

One simple answer is to have your own implementation of Connect which either exposes an isTransactional property, or which automatically commits when it's transactional, delegating everything else to an underlying connection:

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();
    }
}

Then change your connection-returning methods to use it:

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

people

See more on this question at Stackoverflow