Как добиться разделения проблем без использования каких-либо рамок, кроме 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");
Удачи!