Как добиться разделения проблем без использования каких-либо рамок, кроме Tomcat + Servlets?

У меня есть код, который отлично работает. Важными частями являются следующие:

Мой модельный класс:

package biz.tugay.sakila.model;
/* User: koray@tugay.biz Date: 25/06/15 Time: 12:48 */

public class Actor {

    private long id;
    private String firstName;
    private String lastName;

    // Getters, setters... 
}

Мой дао класс:

package biz.tugay.sakila.dao;
/* User: koray@tugay.biz Date: 25/06/15 Time: 12:12 */

import biz.tugay.sakila.model.Actor;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class ActorDao {

    protected static final Connection connection = DBConnector.getConnection();

    public List<Actor> getAllActors() throws SQLException {

        List<Actor> allActors = new ArrayList<Actor>();

        Statement stmt = connection.createStatement();
        String sql = "SELECT * FROM Actor";

        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
            Actor actor = new Actor();
            actor.setFirstName(rs.getString("first_name"));
            // You get the idea... Setters again..
            allActors.add(actor);
        }

        rs.close();
        stmt.close();

        return allActors;
    }
}

и DBConnector

package biz.tugay.sakila.dao;
/* User: koray@tugay.biz Date: 25/06/15 Time: 12:35 */

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnector {

    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://localhost/sakila";
    static final String USER = "root";
    static final String PASS = "";

    private static Connection connection = null;

    public static final Connection getConnection() {
        if (connection != null) {
            return connection;
        } else {
            try {
                Class.forName(JDBC_DRIVER);
                connection = DriverManager.getConnection(DB_URL, USER, PASS);
                return connection;
            } catch (ClassNotFoundException e) {

            } catch (SQLException e) {

            }
            throw new UnsupportedOperationException();
        }
    }

}

Мой класс сервлетов:

package biz.tugay.sakila.servlet;
/* User: koray@tugay.biz Date: 26/06/15 Time: 14:31 */

import biz.tugay.sakila.dao.ActorDao;
import biz.tugay.sakila.model.Actor;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;

@WebServlet(urlPatterns = "/actors")
public class ActorServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        ActorDao actorDao = new ActorDao();
        List<Actor> allActors = null;

        try {
            allActors = actorDao.getAllActors();
            req.setAttribute("allActors",allActors);
            req.getRequestDispatcher("/actors.jsp").forward(req, resp);
        } catch (SQLException e) {

        }
    }
}

И /actors.jsp покажет пользователю HTML-таблицу.

Я сделал это упражнение самостоятельно с примером базы данных sakila, предоставляемой MySQL.

Мой вопрос: без использования какой-либо инфраструктуры, такой как Spring или Struts, как мне добиться лучшего разделения? Например, в настоящее время ActorServlet зависит от ActorDao конкретно, могу ли я это исправить, если да, то как? Также ActorDao сильно зависит от DBConnector. Например, я хочу иметь возможность создавать коннектор NoSQL и использовать его, но в настоящее время я не могу догадаться?

1 ответ

Решение

Первый шаг - абстрагирование некоторых интерфейсов. Например, сделать ActorDao интерфейс, переместите реализацию в ActorDaoImpl или что угодно. Создать ActorDaoFactory что вручает вам ActorDao который под одеялом ActorDaoImpl, но сервлет не должен знать это.

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

Как только вы это сделаете, отыскать их из JNDI так же просто, как

// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// Look up our DAO
ActorDao ad = (ActorDao)envCtx.lookup("dao/actor");

Удачи!

Другие вопросы по тегам