quinta-feira, 26 de janeiro de 2012

Exemplo de Aplicação Java Swing com BD Oracle – 3

Hoje, vamos desenvolver uma biblioteca de classes que mapeia os conceitos do domínio do problema, e faz a ponte entre a interface com o utilizador, cujo desenvolvimento trataremos no próximo artigo, e a camada de persistência de dados, tratada no primeiro artigo desta série.

Esta camada com conceitos e operações do domínio do problema é comummente chamada de camada intermédia ou camada de lógica do negócio.

Podemos considerar que o nosso pequeno sistema aplicacional terá, então, uma arquitectura de software em 3-camadas (abordaremos o tema da arquitectura de software num artigo futuro).

Há várias maneiras de desenvolver esta camada intermédia, a qual pode ela própria conter uma ou mais camadas. Nós iremos desenvolver uma classe para cada conceito do domínio, o que corresponde, mais ou menos, neste pequeno exemplo, a desenvolver uma classe para cada tabela da base de dados.

Há várias maneiras de fazer isso. Em particular, vamos ver duas possíveis maneiras, cada uma com o seu grupo de defensores, e com as suas próprias vantagens e desvantagens.

1 – Há autores que defendem o desenvolvimento de uma camada de classes apenas com atributos, getters e setters (ex.: classe Book abaixo), separadamente de uma camada de classes com operações com significado para o negócio (ex.: classe BookBLL abaixo).

1.1 classe Book:
public class Book {
    private int idBook;
    private String title;
    private String editor;
    private java.sql.Date date;
    private String ISBN;
    private String edition;
    //
    private List<Author> authors = new ArrayList<Author>();

   
    public Book() {    }

    public int getID() {  return this.idBook;    }

    public void setTitle(String title) {  this.title = title;    }

    public String getTitle() {  return title;    }

    public void setEditor(String editor) { this.editor = editor;    }

    public String getEditor() {  return editor;    }

    public void setDate(java.sql.Date date) {  this.date = date;    }

    public java.sql.Date getDate() {  return date;    }

    public void setISBN(String ISBN) {  this.ISBN = ISBN;    }

    public String getISBN() {  return ISBN;    }

    public void setEdition(String edition) {  this.edition = edition;    }

    public String getEdition() {  return edition;    }

    public List<Author> getAuthors() {  return this.authors;    }
}

1.2 classe BookBLL:

public class BookBLL {
    private DBAccessObj dbo;

    public BookBLL() {
        this.dbo = new DBAccessObj();
        this.dbo.openConnection();
    }

    public BookBLL(DBAccessObj dbo) {
        this.dbo = dbo;
        this.dbo.openConnection();
    }

     public void create(Book b) throws SQLException{

            String sqlCommand =
                         "INSERT INTO Book (ISBN, Title, Edition, Editor) VALUES('" +
                                                                b.getISBN() + "', '" + b.getTitle() + "', '" +
                                                                b. getEdition() + "', '" + b.getEditor() + "')";

            this.dbo.executeSQL(sqlCommand);
     }


// restantes operações

}

Esta primeira abordagem não explora o encapsulamento de dados e operações sobre os dados (conceito fundamental do paradigma de programação orientado a objetos).




2 – Outra maneira, é desenvolver:
•    uma camada de classes com atributos, getters e setters, mais as operações CRUD (Create, Retrieve, Update, Delete) (ex.: class BookDAL abaixo); separadamente de,
•    uma camada de classes com operações com significado para o negócio, e que não dependem directamente da base de dados e podem ser obtidas por composição das operações CRUD primitivas (ex.: class BookBLL abaixo).


2.1 classe BookDAL:

public class BookDAL {
    private int idBook;
    private String title;
    private String editor;
    private java.sql.Date date;
    private String ISBN;
    private String edition;
    //
    private List<Author> authors = new ArrayList<Author>();
   
    private DBAccessObj dbo;

    public BookDAL() {
        this.dbo = new DBAccessObj();
        this.dbo.openConnection();
    }

    public BookDAL(DBAccessObj dbo) {
        this.dbo = dbo;
        this.dbo.openConnection();
    }

    public int getID() {  return this.idBook;    }

    public void setTitle(String title) {  this.title = title;    }

    public String getTitle() {  return title;    }

    public void setEditor(String editor) { this.editor = editor;    }

    public String getEditor() {  return editor;    }

    public void setDate(java.sql.Date date) {  this.date = date;    }

    public java.sql.Date getDate() {  return date;    }

    public void setISBN(String ISBN) {  this.ISBN = ISBN;    }

    public String getISBN() {  return ISBN;    }

    public void setEdition(String edition) {  this.edition = edition;    }

    public String getEdition() {  return edition;    }

    public List<Author> getAuthors() {  return this.authors;    }

    public void create() throws SQLException{
              String sqlCommand =
                         "INSERT INTO Book (ISBN, Title, Edition, Editor) VALUES('" +
                         this.ISBN + "', '" + this.title + "', '" + this.edition + "', '" + this.editor + "')";
              this.dbo.executeSQL(sqlCommand);
    }

    public void retrieve(int id) throws SQLException{
         String sqlCommand =
            "SELECT ISBN, Title, DateEdition, Edition, Editor FROM Book WHERE ID = '" + id + "'";

         ResultSet book;

         book = this.dbo.executeQuery(sqlCommand);
       
         if (book.next()){
                    this.idBook = id;
                    this.ISBN = book.getString("ISBN");
                    this.title = book.getString("Title");
                    this.date = book.getDate("DateEdition");
                    this.edition = book.getString("Edition");
                    this.editor = book.getString("Editor");
         }
    }

    public void retrieveByISBN(String isbn) throws SQLException{
        String sqlCommand =
         "SELECT ID, Title, DateEdition, Edition, Editor FROM Book WHERE ISBN = '" + isbn + "'";

        ResultSet book;

        book = this.dbo.executeQuery(sqlCommand);
        
        if (book.next()){
             this.idBook = book.getInt("ID");
             this.title = book.getString("Title");
             this.date = book.getDate("DateEdition");
             this.edition = book.getString("Edition");
             this.editor = book.getString("Editor");
             this.ISBN = isbn;
        }
    }

    public void update() {
        String sqlCommand =
             "UPDATE Book SET ISBN = '" + this.ISBN + "', Title = '" + this.title + "', Edition = '" +
                   this.edition + "', Editor = '" + this.editor + "' WHERE ID = '" + this.idBook + "'";

        this.dbo.executeSQL(sqlCommand);
    }

    public void delete() {
        String sqlCommand = "DELETE FROM Book WHERE ID = '" + this.idBook + "'";
        this.dbo.executeSQL(sqlCommand);
    }


    public ResultSet retrieveThisBookAuthors(DBAccessObj dbo) throws SQLException{
        String sqlCommand =
              "SELECT B.ID, B.ISBN, B.Title, A.ID, A.Name, A.Surname FROM BookAuthor BA, Author A, Book B WHERE BA.BookID = B.ID AND BA.AuthorID = A.ID AND B.ID = " + this.getID() + " ORDER BY 3, 2";

        ResultSet books;

        dbo.openConnection();
        books = dbo.executeQuery(sqlCommand);
        return books;
    }

    public void fillThisBookAuthors() throws SQLException{
        String sqlCommand = "SELECT A.ID, A.Name, A.Surname FROM BookAuthor BA, Author A, Book B WHERE BA.BookID = B.ID AND BA.AuthorID = A.ID AND B.ID = " + this.getID() + " ORDER BY 3, 2";
        ResultSet booksA;

        this.dbo.openConnection();
        booksA = this.dbo.executeQuery(sqlCommand);

        while (booksA.next()){
            Author au = new Author();
            au.setName(booksA.getString("Name"));
            au.setSurname(booksA.getString("Surname"));
            this.authors.add(au);
        }

    }

    public static ResultSet retrieveAllBooks(DBAccessObj dbo) throws SQLException{
        String sqlCommand = "SELECT ISBN, Title, DateEdition, Edition, Editor FROM Book";
        ResultSet books;

        dbo.openConnection();
        books = dbo.executeQuery(sqlCommand);
        return books;
    }

    public static ResultSet retrieveAllBooksAuthors(DBAccessObj dbo) throws SQLException{

        String sqlCommand = "SELECT B.ID, B.ISBN, B.Title, A.ID, A.Name, A.Surname FROM BookAuthor BA, Author A, Book B WHERE BA.BookID = B.ID AND BA.AuthorID = A.ID ORDER BY 1, 6, 5";
        ResultSet books;

        dbo.openConnection();
        books = dbo.executeQuery(sqlCommand);
        return books;
    }


2.2 classe ManageBooksBLL:

public class ManageBooksBLL {
    public ManageBooksBLL () {    }

    public int requisitarBook (Book book, Borrower leitor)  throws  ManageBookException {
          …
    }

    public int requisitarBook (int bookID, int leitorID)  throws  ManageBookException {
          …
    }

    public int devolverBook (Book book)  throws  ManageBookException{
          …
    }

    public int devolverBook (int bookID)  throws  ManageBookException {
          …
    }
}



Nesta abordagem, o encapsulamento de dados e operações aparece, orientado às entidades do domínio do problema (classes Entidade ou persistentes), na camada DAL.

A camada BLL (Business Logic Layer) contém operações orientadas aos casos de uso a implementar na aplicação, podendo portanto ser vista como uma camada de fornecimento de serviços para a camada acima, de Interface com o utilizador (UI, User Interface).





Em termos práticos, dependendo da quantidade de operações complexas num programa (diferentes de CRUD), podemos ainda misturar a DAL e BLL da 2ª abordagem, passando isso por acrescentar nas classes DAL os poucos métodos BLL que tivéssemos, eliminando as classes BLL.

De notar, em ambas as abordagens, a utilização da classe DBAccessObj, cujo desenvolvimento foi tratado no artigo anterior, para acesso à base de dados.

O zip com o resultado final pode, como de costume, ser solicitado nos comentários a este artigo.

Outros artigos relacionados:
     - Exemplo de Aplicação Java Swing com BD Oracle - 1
     - Exemplo de Aplicação Java Swing com BD Oracle - 2
     - Exemplo de Aplicacao Java Swing com BD Oracle - 4

1 comentário:

  1. Olá! O zip com o projeto da camada de lógica de negócio desenvolvida neste artigo está em https://docs.google.com/open?id=0B0zl-Rzbx3qgQnQ1ZDRKeU5Valk

    Ao descompactar, os ficheiros Java devem ficar numa pasta ...\libraryProjectBLL\src\libraryBLL

    Importar no Netbeans, criando um projeto "with existing sources".
    Nas libraries do projeto acrescentar a referencia ao projeto HelperDB.

    Bom trabalho!

    ResponderEliminar