我正在使用MVC设计模式开发Java swing桌面应用程序,并实现Service
和DAO
层。 DAO层与数据库交互,而Service
层与Controller
通信。这是DAO的实现:
public class ProductDAO implements DAO {
public void insert(Product p) throws SQLException {
//Logic for insertion goes here.. i.e. Getting/pooling connection object and executing PreparedStatement etc.
}
public List<Product> listAll() throws SQLException {
//Logic for retreive
}
.
.
.
}
和Service
层:
public class ProductService implements Service {
private DAO dao;
private Controller con;
public ProductService(Controller con) {
dao = new ProductDAO();
this.con = con;
}
public void insertProduct(Product p) throws SQLException {
dao.insertProduct(p);
con.onSuccess();
}
.
.
.
}
但是DAO可能会花费很长时间(虽然获取所有产品并列出列表),但它应该在后台线程上执行。使用Swing
,运行长时间任务的最佳方法是使用SwingWorker
线程。 (我使用过SwingWorker
及其方法)。 但是我在这里感到震惊的是,哪一层应该实现SwingWorker
想法:
Executer
)::此Executer
层将位于Service
层和DAO
层之间。它将继承SwingWorker
并提供对doInBackground()
和其他方法的实现。 Service
和DAO
对象将从Service
层注入。 Service
层将创建一个新实例并调用execute()
层的Executer
方法,并定义操作模式,例如insert
,update
或{{1} }。该delete
层将调用Executer
的适当方法,例如,如果操作模式为DAO
,则它将调用insert
的{{1}}方法。这是这种想法的实现:执行者层
insertProduct(Product p)
服务层
DAO
所以我的问题是我应该如何使用public class ProductExecuter extends SwingWorker<Void, Void> {
private Service.Mode mode;
private Service service;
private DAO dao;
private Product product;
public ProductExecuter(Service s, DAO d, Product p, Service.Mode mode) {
this.service = s;
this.dao = d;
this.mode = mode;
this.product = p;
}
@Override
public Void doInBackground() {
if(mode.equals(Service.INSERT)) {
dao.insertProduct(product);
service.onSuccess();
} else if(mode.equals(Service.GET_ALL)) {
List<Product> list = dao.listAll();
service.setListData(list);
}
.
.
.
}
}
和public class ProductService implements Service {
private SwingWorker<Void, Void> executer;
private Dao dao;
public ProductService(Controller con) {
this.con = con;
this.dao = new ProductDAO();
}
public void insertProduct(Product p) {
executer = new ProductExecuter(this, dao, p, Mode.INSERT);
executer.execute();
}
public void listAll() {
executer = new ProductExecuter(this, dao, null, Mode.GET_ALL);
executer.execute();
}
public void onSuccess() {
con.onSuccess(); //**This method will interact with VIEW and might change GUI state. So this should be on EDT**
}
public void setListData(List<Product> list) {
con.setListData(list); //**This method will interact with VIEW and might change GUI state. So this should be on EDT**
}
.
.
.
.
public enum Mode {
INSERT, GET_ALL, REMOVE, UPDATE, GET_BY_ID;
}
}
来实现SwingWorker。