0

I'm learning about SRP and had to reduce the responsibility of a customer object, which contained too much info. So I turned that into just a Pojo and pulled out the database logic. I'm trying to find the best design for this setup and am split between making the DatabaseManager class be a parent class, or a singleton that can return the single connection object. This system will be used to insert and delete customers from the database. I don't want my domain objects/DAOs to worry about the connection details. Is the design I currently have a strong follower of OOP design principles?

public class DatabaseManager {

    private Connection conn;

    private static DatabaseManager managerInstance = new DatabaseManager();

    private DatabaseManager() {

    }

    public static DatabaseManager getInstance() {
        return managerInstance;
    }

    /**
     * contains connection details
     * 
     * @throws SQLException
     */
    public void connect() throws SQLException {
        System.out.println("Established Database Connection...");
        conn = DriverManager.getConnection("Some/Database/URL");
    }

    public Connection getConnectionObject() {
        return conn;
    }

    public void disconnect() throws SQLException {
        conn.close();
        System.out.println("Disconnected from Database...");
    }
}

Here is the Customer Object:

public class Customer {

       private int id;
       private String name;
       private boolean active;


       public Customer(int id, String name, String department, boolean working) {
              super();
              this.id = id;
              this.name = name;
              this.department = department;
              this.working = working;
       }

       @Override
       public String toString() {
              return "Customer [id=" + id + ", name=" + name + ", department="
                           + department + ", working=" + working + "]";
       }
}

The customer DAO:

public class CustomerDAO {

    public CustomerDAO() {
    }

    public void addCustomer(Customer Customer) throws SQLException {
        DatabaseManager.getInstance().getConnectionObject().prepareStatement("some sql... ");
    }

    public void removeCustomer(Customer Customer) throws SQLException {
        DatabaseManager.getInstance().getConnectionObject().prepareStatement("some sql... ");
        // implementation details avoided
    }

}
Horse Voice
  • 8,138
  • 15
  • 69
  • 120
  • 1
    I would not choose to implement a new `DatabaseManager` in 2014. There are lots of good Connection Pool implementations, I would use one of them. – Elliott Frisch Aug 22 '14 at 03:39
  • Save yourself some time and use Spring Data JPA – Neil McGuigan Aug 22 '14 at 03:43
  • Singleton...personally...that kind of resource management really needs to be done in a single place - personally. – MadProgrammer Aug 22 '14 at 03:46
  • @MadProgrammer thank you. Could you elaborate why that would be better? What can happen if there are multiple instances of the connection object? What if multiple DAOs for example, productDAO, employeeDAO all issue database commands using the singleton? wouldnt that cause problem for database? could you please enlighten me? thank you! – Horse Voice Aug 22 '14 at 03:58
  • Again this is for learning OOP design not picking the latest technology. – Horse Voice Aug 22 '14 at 03:59
  • Assuming that the manager is centralised and is dealing with connection pooling and controlling access to those resources, it should make no difference. You could actually setup mechanism that allow the manager to provide functionality to insert/update/delete DAO, further confining the responsibility. It also means that changing how the manager is managing this content (writing to XML, web, DB, what ever) shouldn't affect the other aspects of the API - but that's just me – MadProgrammer Aug 22 '14 at 04:02
  • not quite sure what you mean by " It also means that changing how the manager is managing this content (writing to XML, web, DB, what ever) shouldn't affect the other aspects of the API" – Horse Voice Aug 22 '14 at 04:09

1 Answers1

3

IMHO neither inheriting nor singleton is best design.

Inheritance is for modeling "is-a". CustomerDAO is not a DatabaseManager, and you don't want to expose the functionality of DatabaseManager to client of CustomerDAO, so you should not use inheritance. There is a good explanation in answers of this question.

Singleton pattern is okay to be used here. However it makes CustomerDAO couples tightly with DatabaseManager.

It's better to define interface of DatabaseManager:

public interface DatabaseManager {
    public Connection getConnectionObject();
}

public class DatabaseManagerImpl implements DatabaseManager {
    // ...
}

Then the DatabaseManager implementation can be injected into DAO by setter method or constructor.

public class CustomerDAO {

    private DatabaseManager databaseManager;

    public void setDatabaseManager(DatabaseManager databaseManager) {
        this.databaseManager = databaseManager;
    }

    public void addCustomer(Customer Customer) throws SQLException {
        databaseManager.getConnectionObject().prepareStatement("some sql... ");
    }

}
Community
  • 1
  • 1
aleung
  • 9,848
  • 3
  • 55
  • 69