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
 
 
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
ResponderEliminarAo 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!