реализация SwingWorker с DAO и Сервисом - PullRequest
0 голосов
/ 18 февраля 2019

Я разрабатываю настольное приложение на Java Swing с использованием шаблона проектирования MVC и реализую слои 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

Мысли:

  • Реализация SwingWorker на другом слое (скажем Executer): Этот слой Executer будет находиться между Service layer и DAO layer.Он унаследует SwingWorker и обеспечит реализацию doInBackground() и другим методам.Объекты Service и DAO будут внедрены из слоя Service.Слой Service создаст новый экземпляр и вызовет метод execute() слоя Executer, а также определит режим работы, такой как insert, update или delete.Этот слой Executer вызовет соответствующий метод DAO, например, если режим работы insert, то он вызовет 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 с Service и DAO.

  • Должен ли я перейти к рассмотренной выше мысли?или SwingWorker должен быть реализован на уровне Service или что-то еще, чего я не знаю
...