SlideShare una empresa de Scribd logo
1 de 149
Descargar para leer sin conexión
Paulo Sousa
pag@isep.ipp.pt
Instituto Superior de Engenharia do Porto
Introduction
Enterprise Applications
Sample problem
Business entities
Business logic and data access
Some improvements
Sample application
Patterns for distributed applications
Synopsis
Conclusions
Part 1
“Each pattern describes a problem that
   occurs over and over again in our
  environment and then describes the
core of the solution to that problem in
    such a way that you can use this
 solution a million times over without
  ever doing it the same way twice.”
                        Christopher Alexander
                                    (architect)
“A Software Design Pattern names,
abstracts, and identifies the key aspects
   of a common design structure that
 make it useful for creating a reusable
         object-oriented design.”
       Design Patterns-Elements of Reusable Object-oriented
                       Software, Gamma et al. (Gang of Four)
a set of best practices

a typified solution to a problem in a given
context

a way to facilitate communication

found not invented
“Patterns are half-baked”
                   Martin Fowler
No direct code reuse

Pattern overload

Experience-based validation

Hard work integrating patterns in the
development process

                                        8
name             Contributes to the pattern
                 vocabulary
synopsis         Short description of the problem the
                 pattern will solve.
forces           Requirements, considerations, or
                 necessary conditions
solution         The essence of the solution
counter forces Reasons for not using the pattern.
related patterns Possible alternatives in the design.
                                                        9
GoF Gang of Four
POSA Pattern-Oriented Software Architecture

PoEAA Patterns of Enterprise Application
        Architecture

   CJP Core J2EE Patterns

  ESP Enterprise Solution Patterns using
        Microsoft .NET                        10
Part 2
Critical functionality
Large quantity of concurrently accessed data
Large number of screens
Integration
Conceptual dissonance
Complex (ilogic) business rules
“[Software Architecture is] the
fundamental organization of a system,
  embodied in its components, their
  relationships to each other and the
   environment, and the principles
 governing its design and evolution.“
       ANSI/IEEE Std 1471-2000, Recommended Practice for
     Architectural Description of Software-Intensive Systems
fonte: Application Architecture for .NET:
   designing applications and Services
Layers




         fonte: Core J2EE Patterns
fonte: Application Architecture for .NET: designing applications and Services
How to represent the business entities?

How to persist its state?

How to code the Business logic?

how to guarantee data coherence?

How to handle application distribution?
Part 3
Revenue recognition
 Three different products
   Word processors, databases, spreadsheets


 Different payment rules
   WP – all at once (t)
   DB – 3 payments: t, t+30, t+60
   SS – 3 payments: t, t+60, t+90

                       (From Martin Fowler’s PoEAA book)
Customer               Contract                        Product
           1                       *
+ name             + revenue                         + name
                 * + dateSigned                  1

                           1

                                       WordProcessor              SpreadSheet
                       *

                RevenueRecognition
               + dateRecognition                       DataBase
               + amount
«table»
                                TRevenueRecognitions

                            + «Column» ID : int
                            + «Column» contractID : int
                            + «Column» dateRecognition : date
                            + «Column» amount : currency




                                       «table»
                                                                        «table»
                                     TContracts
                                                                       TProducts
        «table»
                            + «Column» ID : int
      TCustomers
                                                                + «Column» ID : int
                            + «Column» productID : int
                                                                + «Column» type : varchar
+ «Column» ID : int         + «Column» customerID : int
                                                                + «Column» name : varchar
+ «Column» name : varchar   + «Column» revenue : currency
                            + «Column» dateSigned : date
public interface IRevenueRecognition
{
  void CalculateRevenueRecognitions(int contractID);

    Money RecognizedRevenue(int contractID, DateTime asOf);

    object GetContracts();

    object GetCustomers();

    object GetProducts();
}
Part 4
How to represent:
 One entity, e.g. Customer?
 Collections, e.g., List of customers?
 Networked/complex objects, e.g., production plan?

Structure and behaviour
 Structure + behaviour?
 Structure with behaviour?
 Behaviour (and attributes)?

Persistence structure ≠ conceptual structure?
Custom classes

XML

DataSet (.net) / ResultSet (JDBC)
Custom classes

IList / List

XML

DataSet (.net) / ResultSet (JDBC)
User defined code with members for the
entity’s attributes

                 Product
              + Type : int
              + Name : string
              + ID : int
Product                Contract
                                                         Customer
+ Type : int       + Revenue : decimal
+ Name : string    + DateSigned : DateTime             + Name : string
+ ID : int         + CustomerID : int                  + ID : int
                   + ProductID : int
                   + ID : int




                             * + RevenueRecognitions

                     RevenueRecognition
                  + DateRecognition : DateTime
                  + Amount : decimal
                  + ContractID : int
                  + ID : int
An XML document (or string) representing an
entity’s structure

 <product>
  <id>123</id>
  <name>SuperWriter 7.3</name>
  <type>Word Processor</type>
 </product>
A DataSet (or derived class) to hold tabular
data (eventually directly from a data source)
A class implementing the ResultSet interface to
hold tabular data (eventually directly from a data
source)
A library collection class (e.g. LinkedList)
        LinkedList
Part 5
Table oriented        BLL
 Table Module
                             DAL
 Table Data Gateway

Object oriented
                        BLL
 Domain Model
 Active Record
                            DAL
                            BLL
 Data Mapper
Part 5.1
UI



                            Uses the
                           platform’s
                          ResultSet for
                       sharing entity data
   «table module»
                        beteween layers
         BLL




«table data gateway»
         DAL
Pattern




A single instance that handles the business
logic for all rows in a database table or view




       fonte: Patterns of Enterprise Application Architecture
Contract

+ Contract ( )
+ RecognizedRevenue ( [in] contractID : int , [in] asOf : DateTime ) : Money
+ CalculateRevenueRecognitions ( [in] contractID : int )
+ GetContracts ( ) : DataSet
+ GetContractsByProduct ( [in] productID : int ) : DataSet
+ GetContractsByCustomer ( [in] customerID : int ) : DataSet



                             Customer

                  + Customer ( )
                  + GetCustomers ( ) : DataTable



                              Product

                   + Product ( )
                   + GetProducts ( ) : DataTable
Pattern




An object that acts as a Gateway to a
database table. One instance handles all the
rows in the table



            Business
             entity




       fonte: Patterns of Enterprise Application Architecture
CustomerGateway

                       + CustomerGateway ( )
                       + GetCustomers ( ) : DataTable


                                                                                     ContractGateway

     ProductGateway                      + ContractGateway ( )
                                         + InsertRecognition ( [in] contractID : int , [in] recognitionDate : DateTime , [in] amount : decimal ) : int
+ ProductGateway ( )                     + GetContracts ( ) : DataSet
+ GetProducts ( ) : DataTable            + GetContractByID ( [in] contractID : int ) : DataSet
                                         + GetContractsByProduct ( [in] productID : int ) : DataSet
                                         + GetContractsByCustomer ( [in] customerID : int ) : DataSet




                                       BaseGateway
      # «property» CurrentTransaction : OleDbTransaction
      - CONNSTR : string = @quot;Provider=...quot;
      + BaseGateway ( )
      # GetConnection ( [in] open : bool ) : OleDbConnection
      # ExecuteQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : DataSet
      # ExecuteNonQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : int
      # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] sql : string ) : int
      # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int
      + BeginTransaction ( )
                                                                                                                                               42
      + CommitTransaction ( )
                                                                                                                                           ISEP/IP
      + RoolbackTransaction ( )
      # «get» CurrentTransaction ( ) : OleDbTransaction                                                                                          P
/ User : Actor1            / GUI              / ClassifierRole1 : Contract        / ClassifierRole2 : Contract
                                                                                            Gateway

         1 : Form_Load
                               2 : GetContracts ( )
                                                               3 : GetContracts ( )

                                                                                                   4 : GetConnection ( open )




                                                                                                   5 : ExecuteQuery ( cnx , sql )
/ User : Actor1            / GUI                   / ClassifierRole1 : Contract


      1 : btnCalcRevenues_Click
                             2 : CalculateRevenueRecognitions (
                                         contractID )
                                                                    3 : new                  / ClassifierRole2 : Contract
                                                                                                         Gateway

                                                                  4 : GetContractByID ( contractID )



                                                                    5 : BeginTransaction ( )



                                                                                                                              foreach calculated
                                                                  6 : InsertRecognition ( contractID ,
                                                                                                                              recognition
                                                                      recognitionDate , amount )



                                                                    7 : CommitTransaction ( )
Returns a join of
public void CalculateRevenueRecognitions(int contractID)
{
                                                                TContracts and
   DAL.ContractGateway dal = new DAL.ContractGateway();
   DataSet ds = dal.GetContractByID(contractID);
                                                                  TProducts
    string prodType = (string)ds.Tables[0].Rows[0][quot;typequot;];
    decimal totalRevenue = (decimal)ds.Tables[0].Rows[0][quot;revenuequot;];
    DateTime recDate = (DateTime)ds.Tables[0].Rows[0][quot;dateSignedquot;];
    dal.BeginTransaction();
    switch (prodType) {
    case quot;PTquot;:
         dal.InsertRecognition(contractID, recognitionDate, totalRevenue);
         break;
    case quot;FCquot;:
         decimal[] allocs = Money.Allocate(totalRevenue, 3);
         dal.InsertRecognition(contractID, recDate, allocs[0]);
         dal.InsertRecognition(contractID, recDate.AddDays(60), allocs[1]);
         dal.InsertRecognition(contractID, recDate.AddDays(90), allocs[2]);
         break;
    case quot;BDquot;:
         decimal[] allocs = Money.Allocate(totalRevenue, 3);
         dal.InsertRecognition(contractID, recDate, allocs[0]);
         dal.InsertRecognition(contractID, recDate.AddDays(30), allocs[1]);
         dal.InsertRecognition(contractID, recDate.AddDays(60), allocs[2]);
         break;
                                    Explicit transaction control
    }
    dal.CommitTransaction();
                                               ☺/
}
public int InsertRecognition(int contractID,
                         DateTime recognitionDate,
                         decimal amount)
{
   OleDbCommand sqlcmd = new OleDbCommand(
                quot;INSERT INTO TRevenueRecognitions
                (contractID, dateRecognition, amount)
                VALUES (?, ?, ?)quot;,
                CurrentTransation.Connection,
                CurrentTransation
                );
    sqlcmd.Parameters.Add(quot;@cidquot;, contractID);
    sqlcmd.Parameters.Add(quot;@dtquot;, recognitionDate);
    sqlcmd.Parameters.Add(quot;@amtquot;, amount);
    return ExecuteNonQuery(CurrentTransation, sqlcmd);
}
Part 5.2
UI




                                  These classes only
                                    have attributes
                                  (no business logic-
 «table module»        Entities
                                  related behaviour)
       BLL




«table data gateway»
         DAL
Product                Contract
                                                         Customer
+ Type : int       + Revenue : decimal
+ Name : string    + DateSigned : DateTime             + Name : string
+ ID : int         + CustomerID : int                  + ID : int
                   + ProductID : int
                   + ID : int




                             * + RevenueRecognitions

                     RevenueRecognition
                  + DateRecognition : DateTime
                  + Amount : decimal
                  + ContractID : int
                  + ID : int
Contract

+ Contract ( )
+ RecognizedRevenue ( [in] contractID : int , [in] asOf : DateTime ) : Money
+ CalculateRevenueRecognitions ( [in] contractID : int )
+ GetContracts ( ) : IList
+ GetContractsByProduct ( [in] productID : int ) : IList
+ GetContractsByCustomer ( [in] customerID : int ) : IList



                          Customer

                  + Customer ( )
                  + GetCustomers ( ) : IList



                           Product

                   + Product ( )
                   + GetProducts ( ) : IList
CustomerGateway

                                                                                                       ContractGateway
 + CustomerGateway ( )
 + GetCustomers ( ) : IList
                                                           + ContractGateway ( )
 - CreateCustomerObject ( [in] r : DataRow ) : Customer
                                                           + InsertRecognition ( [in] contractID : int , [in] recognitionDate : DateTime , [in] amount : decimal ) : int
                                                           + GetContracts ( ) : IList
                                                           + GetContractByID ( [in] contractID : int ) : Contract
                ProductGateway                             + GetContractsByProduct ( [in] productID : int ) : IList
                                                           + GetContractsByCustomer ( [in] customerID : int ) : IList
+ ProductGateway ( )                                       - CreateContractObject ( [in] r : DataRow ) : Contract
+ GetProducts ( ) : IList                                  - CreateRevenueRecognitionObject ( [in] r : DataRow ) : RevenueRecognition
- CreateProductObject ( [in] r : DataRow ) : Product




                                                            BaseGateway
                            # «property» CurrentTransaction : OleDbTransaction
                            - CONNSTR : string = @quot;Provider=...quot;
                            + BaseGateway ( )
                            # GetConnection ( [in] open : bool ) : OleDbConnection
                            # ExecuteQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : DataSet
                            # ExecuteNonQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : int
                            # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] sql : string ) : int
                            # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int
                            + BeginTransaction ( )
                            + CommitTransaction ( )
                                                                                                                                                             51
                            + RoolbackTransaction ( )
                                                                                                                                                         ISEP/IP
                            # «get» CurrentTransaction ( ) : OleDbTransaction
                                                                                                                                                               P
/ User : Actor1           / GUI        / ClassifierRole1 : Contract


        1 : Form_Load
                             2 : GetContracts ( )
                                                                               / ClassifierRole2 : Contract
                                                       3 : new
                                                                                         Gateway

                                                        4 : GetContracts ( )
                                                                                                5 : GetConnection ( open )




                                                                                                6 : ExecuteQuery ( cnx , sql )




                                                                                              7 : new           / IList

                                                                                                 8 : new
                                                                                                                                 / ClassifierRole3 : Contract


                                                                                                                                     foreach row returned
                                                                                                9 : Add


                                                                                                                                                    52
                                                                                                                                                ISEP/IP
                                                                                                                                                      P
/ GUI              / bll : Contract


                                                                                                                    Sequence
1 : btnCalcRevenues_click
                    2 : CalculateRevenueRecognitions (
                                                                                                                CalculateRevenues
                                contractID )

                                                 3 : new             / dalC : ContractGateway



                                               4 : GetContractByID ( contractID )
                                                                                       5 : CreateContractObject ( r )


                                                                                      6 : new
                                                                                                           / c : Contract



                                                              7 : new
                                                                                                                               / dalP : ProductGateway


                                                             8 : GetProductByID ( productID )
                                                                                                                                             9 : CreateProductObject ( r )


                                                                                                                                           10 : new
                                                                                                                                                             / p : Product



                                                11 : BeginTransaction ( )

                                                                                                  foreach calculated revenue
                                              12 : InsertRecognition ( contractID ,
                                                   recognitionDate , amount )
                                                                                       13 : ExecuteNonQuery ( tx , cmd )




                                                14 : CommitTransaction ( )
public void CalculateRevenueRecognitions(int contractID)
{
   DAL.ContractGateway dalC = new DAL.ContractGateway();
   Entities.Contract c = dalC.GetContractByID(contractID);
    DAL.ProductGateway dalP = new DAL.ProductGateway();
    TM.Entities.Product p = dalP.GetProductByID(c.ProductID);
    dalC.BeginTransaction();
    switch (p.Type) {
    case quot;PTquot;:
         dalC.InsertRecognition(contractID, c.DateSigned, c.Revenue);
         break;
    case quot;FCquot;:
         decimal[] alcs = Money.Allocate(c.Revenue, 3);
         dalC.InsertRecognition(contractID, c.DateSigned, allocs[0]);
         dalC.InsertRecognition(contractID, c.DateSigned.AddDays(60),   alcs[1]);
         dalC.InsertRecognition(contractID, c.DateSigned.AddDays(90),   alcs[2]);
         break;
    case quot;BDquot;:
         decimal[] alcs = Money.Allocate(c.Revenue, 3);
         dalC.InsertRecognition(contractID, c.DateSigned, allocs[0]);
         dalC.InsertRecognition(contractID, c.DateSigned.AddDays(30),   alcs[1]);
         dalC.InsertRecognition(contractID, c.DateSigned.AddDays(60),   alcs[2]);
         break;
    }
    dalC.CommitTransaction();
}
Part 5.3
GUI




«domain model + active record»
         BLL + DAL
Pattern




An object model of the domain that
incorporates both behavior and data




      fonte: Patterns of Enterprise Application Architecture
Pattern




An object that wraps a row in a database
table or view, encapsulates the database
access, and adds domain logic on that data




       fonte: Patterns of Enterprise Application Architecture
                                                                          58
Can be divided:
                                                                                                                                                   Classes
                                                                                             (a) ActiveRecord
                                                                                                                                                  BLL/DAL
                                                                                             (b) DBHelper
                                  ActiveRecord
# myID : int
# «property» CurrentTransaction : OleDbTransaction
                                                                                                                         Product
- CONNSTR : string = @quot;Provider=...quot;
+ «property» ID : int
                                                                                                       + «property» Type : string
                                                                                                       - _name : string
+ Save ( )
                                                                                                       - _type : string
+ ActiveRecord ( )                                                                                                                                   0..1
# GetConnection ( [in] open : bool ) : OleDbConnection
                                                                                                       + Product ( )                                 - _Product
# ExecuteQuery ( [in] sql : string ) : DataSet
                                                                                                       # Product ( [in] row : DataRow )
# ExecuteTransactedQuery ( [in] sql : string ) : DataSet
                                                                                                       + LoadById ( [in] productID : int ) : Product
# ExecuteNonQuery ( [in] sql : string ) : int
                                                                                                       + LoadAll ( ) : IList
# ExecuteTransactedNonQuery ( [in] sql : string ) : int
                                                                                                       + Save ( )
# ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int
                                                                                                       + «get» Type ( ) : string
# BeginTransaction ( )
# CommitTransaction ( )
# RoolbackTransaction ( )
# «get» CurrentTransaction ( ) : OleDbTransaction
+ «get» ID ( ) : int                                                                                                     Customer
# ExecuteTransactedNonQuery ( [in] cmd : OleDbCommand ) : int
                                                                                                       - Name : string

                                                                                                      + Customer ( )
                                                                                         - _Customer
                                                                                                      # Customer ( [in] row : DataRow )
                                  Contract
                                                                                                 0..1 + LoadById ( [in] customerID : int ) : Customer
                                                                                                      + LoadAll ( ) : IList
- CustomerID : int
                                                                                                      + Save ( )
- DateSigned : DateTime
- ProductID : int
- Revenue : decimal
# «property» Product : Product

+ Contract ( )                                                                                                               RevenueRecognition
# Contract ( [in] row : DataRow )
                                                                             - RevenueRecognitions + Amount : decimal
# Contract ( [in] dsContractAndRecognitions : DataSet )
+ RecognizedRevenue ( [in] asOf : DateTime ) : Money                                            * + DateRecognition : DateTime
+ CalculateRevenueRecognitions ( )                                                                 + ID : int
+ LoadById ( [in] contractID : int ) : Contract
                                                                                                   + RevenueRecognition ( [in] id : int , [in] dt : DateTime , [in] amt : decimal )
+ LoadByProduct ( [in] productID : int ) : IList
                                                                                                   + RevenueRecognition ( [in] dt : DateTime , [in] amt : decimal )
+ LoadByCustomer ( [in] customerID : int ) : IList
+ LoadAll ( ) : IList
+ Save ( )                                                                                                    inner private
# AddRecognition ( [in] recognitionDate : DateTime , [in] amount : decimal )                                  class
# «get» Product ( ) : Product
DBHelper
                                                                                                   + «property» CurrentTransaction : OleDbTransaction
                                       ActiveRecord
                                                                                                   - CONNSTR : string = @quot;Provider=...quot;
                                     # myID : int
                                                                                                   + DBHelper ( )
                                     + «property» ID : int
                                                                                                   + GetConnection ( )
                                     + Save ( )                                                    + ExecuteQuery ( )
                                     + ActiveRecord ( )                                            + ExecuteTransactedQuery ( )
                                     + «get» ID ( )                                                + ExecuteNonQuery ( )
                                                                                                   + ExecuteTransactedNonQuery ( )
                                                                                                   + ExecuteNonQuery ( )
                                                                                                   + BeginTransaction ( )
                                                                                                   + CommitTransaction ( )
                                                                                                   + RoolbackTransaction ( )
   Product                                Contract                              Customer
                                                                                                   + «get» CurrentTransaction ( )
- Name : string            -   CustomerID : int                               - Name : string
- Type : int               -   DateSigned : DateTime
                0..1                                                          + Customer ( )
                           -   ProductID : int                  - _Customer
                                                                                                                        inner private class
+ Product ( )                                                                 + LoadById ( )
                           -   Revenue : decimal
+ LoadById ( )                                                           0..1 + LoadAll ( )
+ LoadAll ( ) - _Product   + Contract ( )                                     + Save ( )
+ Save ( )                 + RecognizedRevenue ( )
                           + CalculateRevenueRecognitions ( )
                                                                                                   RevenueRecognition
                           + LoadById ( )
                           + LoadByProduct ( )                          - RevenueRecognitions + Amount : decimal
                           + LoadByCustomer ( )
                                                                                           * + DateRecognition : DateTime
                           + LoadAll ( )                                                      + ID : int
                           + Save ( )
                                                                                                + RevenueRecognition ( )
/ User : Actor1           / GUI                : Contract


        1 : Form_Load
                             2 : LoadAll ( )
                                                      3 : ExecuteQuery ( sql )




                                                        4 : new                  / IList


                                                            5 : Contract ( row )
                                                                                                    / ClassifierRole2 : Contract

                                                            6 : Add

                                                                                             foreach
                                                                                             returned row
Networks of objects
 E.g. Invoice heading relates to invoice details
 Invoice details refers to Products
 Products refers to Suppliers
 …

What to do?
 Load them all into memory?
 How to disallow multiple in-memory copies

                                                   62
Pattern




An object that doesn't contain all of the data
you need but knows how to get it.




       fonte: Patterns of Enterprise Application Architecture
Pattern




Ensures that each object gets loaded only once by
keeping every loaded object in a map. Looks up
objects using the map when referring to them




        fonte: Patterns of Enterprise Application Architecture
                                                                           64
/ User : Actor1              / GUI                  : Contract
                                                                                                       Sequence
      1 : btnCalcRevenues_Click
                                                                                                   CalculateRevenues
                               2 : LoadById ( contractID )
                                                               3 : ExecuteQuery ( sql )




                                                             4 : Contract ( row )    / aContract : Contract



                                     5 : CalculateRevenueRecognitions ( )                          6 : AddRecognition ( recognitionDate ,
                                                                                                                amount )


                                                                                                                  foreach calculated
                                                                                                                  recognition

                                         7 : Save ( )
                                                                                                   8 : BeginTransaction ( )


                                                                                                   9 : ExecuteTransactedNonQuery ( sql
                                                                                                                    )


                                                                                                   10 : ExecuteTransactedNonQuery ( sql
                                                                                                                    )
                                             foreach RevenueRecognition
                                             object in _RevenueRecognitions
                                                                                                   11 : CommitTransaction ( )
public void CalculateRevenueRecognitions()
{
   switch (this.Product.Type) {
      case quot;PTquot;:
        AddRecognition(this.DateSigned, this.Revenue);
        break;
      case quot;FCquot;:
        decimal[] allocsFC = Money.Allocate(Revenue, 3);
        AddRecognition(DateSigned, allocsFC[0]);
        AddRecognition(DateSigned.AddDays(60), allocsFC[1]);
        AddRecognition(DateSigned.AddDays(90), allocsFC[2]);
        break;
      case quot;BDquot;:
        decimal[] allocsBD = Money.Allocate(Revenue, 3);
        AddRecognition(DateSigned, allocsBD[0]);
        AddRecognition(DateSigned.AddDays(30), allocsBD[1]);
        AddRecognition(DateSigned.AddDays(60), allocsBD[2]);
        break;
   }
}
// foreign key
private int ProductID;

// object pointer
private Product _Product;

// relationship property
protected Product Product
{
   get
   {
     // Lazy Load
     if (this._Product == null)
       this._Product = Product.LoadById(this.ProductID);

        return this._Product;
    }
}
// Identity Map
public static IDictionary loaded = new Hashtable();

public static Product LoadById(int productID)
{
   // check registry – Identity Map
   Product p = (Product)loaded[productID];
   if (p != null)
      return p;

    // load
    Product aux = new Product();
    DataSet ds = ExecuteQuery(quot;SELECT * FROM TProducts WHERE productID=quot; +
                                  productID);
    p = new Product(ds.Tables[0].Rows[0]);

    // save in registry
    loaded[productID] = p;
    return p;
}
public void Save() {
   BeginTransaction();
   object[] parms = new object[] {this.ProductID, this.CustomerID,
                                  this.DateSigned, this.Revenue, this.ID};
   if (this.ID != 0) {
        sqlContract = quot;UPDATE TContracts SET productId=?, customerID=?,
                         dateSigned=?, revenue=? WHERE contractID=?quot;;
        ExecuteTransactedNonQuery(sqlContract, parms);
        ExecuteTransactedNonQuery(quot;DELETE FROM TRevenueRecognitions WHERE
                                  contractID=quot; + this.ID);
   } else {
        sqlContract = quot;INSERT INTO TContracts(productId, customerId,
                         dateSigned, revenue) VALUES(?, ?, ?, ?)quot;;
        this.myID = ExecuteTransactedNonQuery(sqlContract, parms);
   }
    foreach (RevenueRecognition r in _RevenueRecognitions) {
        string sqlRecognition = quot;INSERT INTO
                 TRevenueRecognitions(contractID, dateRecognition, amount)
                 VALUES(?, ?, ?)quot;;
        object parms[] = new object[] {this.ID, r.DateRecognition,
                                   r.Amount};
        ExecuteTransactedNonQuery(sqlRecognition, parms);
    }
    CommitTransaction();
}
Part 5.4
UI




«domain model»
                      «data mapper»
     BLL
                           DAL




                          Database
Customer                                                          Contract
                                                 - _ID : int                            + «property» Product : Product
                                                 - _name : string                       - _ID : int
                                                 + «property» ID : int - _Customer
          Business logic                                                                - _CustomerID : int
                                                                                        - _DateSigned : DateTime
                                                 + Customer ( )
          methods only                                                                  - _ProductID : int
                                                 + «get» ID ( ) : int                   - _Revenue : decimal
                                                                                        + «property» Customer : Customer
                                                                                        + «property» RevenueRecognitions : IList
                                                      Product
                                                                                        + «property» DateSigned : DateTime
                                            + «property» Type : string                  + «property» Revenue : decimal
                                            - _ID : int                                 + «property» ID : int
                                            - _name : string
                                                                                        ~ AddRecognition ( [in] recognitionDate : DateTime , [in] amount : decimal )
                                            - _type : string
                                                                                        + Contract ( )
                                            + «property» ID : int
                                                                                        + RecognizedRevenue ( [in] asOf : DateTime ) : Money
                                            + Product ( )                               + CalculateRevenueRecognitions ( )
                                                                          - _Product
                                            + «get» Type ( ) : string                   + «get» Product ( ) : Product
                                            + «get» ID ( ) : int                        ~ SetID ( [in] id : int )
                                                                                        ~ SetProduct ( [in] prodID : int , [in] prodType : string )
                                                                                        - SetStrategy ( [in] prodType : string )
                                   IRevenueRecognitionStrategy
                                                                                        ~ SetProduct ( [in] prodID : int )
                                                                        - theStrategy
                                                                                        + «get» Customer ( ) : Customer
                                                                                        + «get» RevenueRecognitions ( ) : IList
                            RevenueRecognition                                          + «get» DateSigned ( ) : DateTime
                                                                                        + «get» Revenue ( ) : decimal
+ Amount : decimal
                                                                                        + «get» ID ( ) : int
+ DateRecognition : DateTime
                                                                                        ~ SetCustomer ( [in] custID : int )
+ ID : int
                                                                                        + «set» Product ( [in] value : Product )
                                                                                        + «set» DateSigned ( [in] value : DateTime )
+ RevenueRecognition ( [in] id : int , [in] dt : DateTime , [in] amt : decimal )
                                                                                                                                                                72
                                                                                        + «set» Revenue ( [in] value : decimal )
+ RevenueRecognition ( [in] dt : DateTime , [in] amt : decimal )
                                                                                                                                                         ISEP/IP
                                                                *
                                     - _RevenueRecognitions                                                                                                    P
public void CalculateRevenueRecognitions()
{
   switch (this.Product.Type) {
      case quot;PTquot;:
        AddRecognition(this.DateSigned, this.Revenue);
        break;
      case quot;FCquot;:
        decimal[] allocsFC = Money.Allocate(Revenue, 3);
        AddRecognition(DateSigned, allocsFC[0]);
        AddRecognition(DateSigned.AddDays(60), allocsFC[1]);
        AddRecognition(DateSigned.AddDays(90), allocsFC[2]);
        break;
      case quot;BDquot;:
        decimal[] allocsBD = Money.Allocate(Revenue, 3);
        AddRecognition(DateSigned, allocsBD[0]);
        AddRecognition(DateSigned.AddDays(30), allocsBD[1]);
        AddRecognition(DateSigned.AddDays(60), allocsBD[2]);
        break;
   }
}
Pattern GoF




Problem:
 Allow the client the choice of many alternatives,
 but each is complex, and you don't want to
 include code for all.

Solution:
 Make many implementations of the same
 interface, and allow the client to select one and
 give it back to you.
Pattern GoF




Define a family of algorithms, encapsulate each one, and make
them interchangeable. Strategy lets the algorithm vary
independently from clients that use it.




          fonte: Design Patterns: Elements of Reusable Object-Oriented Software
public interface IRevenueRecognitionStrategy
{
   void CalculateRevenueRecognitions();
}
BaseStrategy                                              + theContract
                                                                                                                Contract
+ BaseStrategy ( [in] c : Contract )
+ CreateStrategy ( [in] prodType : string , [in] c : Contract ) : IRevenueRecognitionStrategy




           BDStrategy                                FCStrategy                                  PTStrategy

+ BDStrategy ( [in] c : Contract )       + FCStrategy ( [in] c : Contract )           + PTStrategy ( [in] c : Contract )
+ CalculateRevenueRecognitions ( )       + CalculateRevenueRecognitions ( )           + CalculateRevenueRecognitions ( )




                                                                IRevenueRecognitionStrategy
Pattern




A layer of Mappers that moves data between
objects and a database while keeping them
independent of each other and the mapper
itself




      fonte: Patterns of Enterprise Application Architecture
IDBHelper
              DBHelper




                         ContractMapper                                                 CustomerMapper                                            ProductMapper

+ ContractMapper ( )                                                      + CustomerMapper ( )                                    + ProductMapper ( )
# ApplyMap ( [in] row : DataRow ) : Contract                              # ApplyMap ( [in] row : DataRow ) : Customer            # ApplyMap ( [in] row : DataRow ) : Product
# ApplyMap ( [in] dsContractAndRecognitions : DataSet ) : Contract        + LoadById ( [in] customerID : int ) : Customer         + LoadById ( [in] productID : int ) : Product
+ LoadById ( [in] contractID : int ) : Contract                           + LoadAll ( ) : IList                                   + LoadAll ( ) : IList
+ LoadByProduct ( [in] productID : int ) : IList
+ LoadByCustomer ( [in] customerID : int ) : IList
+ LoadAll ( ) : IList
+ Save ( [in] c : Contract )



                                                                                                                                              IdentityMap
                                                                                                                            # «property» Registry : IDictionary

                                                                                                                            + IdentityMap ( )
                                                                           DBFactory                                        # CheckRegistry ( [in] id : int ) : object
                                                                                                                            # AddToRegistry ( [in] id : int , [in] o : object )
                                                                 + DBFactory ( )                                            # «get» Registry ( ) : IDictionary
                                                                 + CreateDBHelper ( ) : IDBHelper




                                                                                                                                                                            79
DBHelper
            + «property» CurrentTransaction : IDbTransaction
            - CONNSTR : string = @quot;Provider=...quot;
            + DBHelper ( )
            + BeginTransaction ( )
            + CommitTransaction ( )
            + ExecuteNonQuery ( [in] tx : IDbTransaction , [in] cmd : IDbCommand ) : int
            + ExecuteNonQuery ( [in] sql : string ) : int
            + ExecuteQuery ( [in] sql : string ) : DataSet
IDBHelper
            + ExecuteTransactedNonQuery ( [in] sql : string ) : int
            + ExecuteTransactedQuery ( [in] sql : string ) : DataSet
            + GetConnection ( [in] open : bool ) : IDbConnection
            + RoolbackTransaction ( )
            + «get» CurrentTransaction ( ) : IDbTransaction
            + ExecuteTransactedNonQuery ( [in] cmd : IDbCommand ) : int
            + CreateCommand ( ) : IDbCommand
            + CreateCommand ( [in] inTransaction : bool ) : IDbCommand
            + CreateParameter ( [in] name : string , [in] value : object ) : IDataParameter
            + CreateParameter ( [in] name : string , [in] tp : DbType , [in] value : object ) : IDataParameter
            + ExecuteQuery ( [in] cmd : IDbCommand ) : DataSet
: Actor1               / UI             : ContractMapper                 : DBFactory                                                      : BaseStrategy

     1 : Form_Load
                          2 : LoadAll ( )
                                                3 : CreateDBHelper ( )
                                                                               4 : new        : IDBHelper



                                                    5 : ExecuteQuery ( cmd )

                                                  6 : ApplyMap ( dsContractAnd
                                                         Recognitions )
                                                                7 : [currentrow.Id != current
                                                                     Contract.ID] new                       : Contract

                                                           8 : SetID ( id )


                                                      9 : SetProduct ( prodID , prodType )
                                                                                                                     10 : SetStrategy ( prodType )



                                                                                                                 11 : CreateStrategy ( prodType , c )



                                                     12 : AddRecognition ( recognitionDate
                                                                 , amount )
                                                                                       foreach returned
                                                                                       recognition                                              81
                                                                                                                                            ISEP/IP
                                                                                                                                                  P
protected Contract ApplyMap(DataSet dsCNR)
{
   if (dsCNR].Rows.Count < 1)
       return null;
    Contract c = new Contract();
    c.DateSigned = (DateTime)dsCNR.Tables[0].Rows[0][quot;Datesignedquot;];
    c.Revenue = (decimal)dsCNR.Tables[0].Rows[0][quot;Revenuequot;];
    c.SetID( (int)dsCNR.Tables[0].Rows[0][quot;IDquot;] );
    c.SetProduct( (int) dsCNR.Tables[0].Rows[0][quot;ProductIDquot;],
                 (string) dsCNR.Tables[0].Rows[0][quot;ProdTypequot;] );
    c.SetCustomer( (int)dsCNR.Tables[0].Rows[0][quot;CustomerIDquot;] );
    foreach (DataRow r in dsCNR.Tables[0].Rows)
    {
        c.AddRecognition( (DateTime)r[quot;dateRecognitionquot;],
                          (decimal)r[quot;amountquot;]);
    }
    return c;
}
public class Contract
{
   // !!! to be used only by Mapper
   internal void SetProduct(int prodID, string prodType)
   {
       _ProductID = prodID;
       SetStrategy(prodType);
   }

    private void SetStrategy(string prodType)
    {
        theStrategy = BaseStrategy.CreateStrategy(prodType, this);
    }
}




                                                                     83
public abstract class BaseStrategy
{
   protected Contract theContract;
    public BaseStrategy(Contract c) {
        theContract = c;
    }
    public static IRevenueRecognitionStrategy CreateStrategy(
                                           string prodType, Contract c)
    {
        switch (prodType) {
        case quot;PTquot;: return new Strategies.PTStrategy(c);
                 break;
        case quot;FCquot;: return new Strategies.FCStrategy(c);
                 break;
        case quot;BDquot;: return new Strategies.BDStrategy(c);
                 break;
        default:
                 throw new ApplicationException(quot;invalid typequot;);
        }
        return null;
    }
}
: Actor1              / UI         / c : Contract                            : IRevenueRecognitionStrategy      : ContractMapper             : DBFactory

    1 : btnCalc_Click
                      2 : CalculateRevenueRecognitions ( )
                                             3 : CalculateRevenueRecognitions ( )



                                                    4 : AddRecognition ( recognitionDate ,
                                                                 amount )

                                                                                foreach recognized
                                                                                revenue
                                         5 : Save ( c )
                                                                                                                        6 : CreateDBHelper ( )
                                                                                                                                                   7 : new
                                                                                                                                                                 : IDBHelper

                                                                                                                            8 : BeginTransaction ( )

                                                                                                                         9 : ExecuteTransactedNonQuery ( cmd
                                                                                                                                           )

                                                                                                                          10 : ExecuteTransactedNonQuery (
                                                                                   foreach recognized revenue                           cmd )


                                                                                                                            11 : CommitTransaction ( )




                                                                                                                                                                   85
                                                                                                                                                               ISEP/IP
                                                                                                                                                                     P
public void CalculateRevenueRecognitions()
{
   _RevenueRecognitions.Clear();
   theStrategy.CalculateRevenueRecognitions();
}

// !!! to be used by strategies
internal void AddRecognition(DateTime recognitionDate,
                              decimal amount)
{
   _RevenueRecognitions.Add(
       new RevenueRecognition(recognitionDate, amount)
       );
}
public class BDStrategy : BaseStrategy {
   public void CalculateRevenueRecognitions() {
        decimal[] allocs = Money.Allocate(theContract.Revenue, 3);
        theContract.AddRecognition(theContract.DateSigned, allocs[0]);
        theContract.AddRecognition(theContract.DateSigned.AddDays(30),
                                  allocs[1]);
        theContract.AddRecognition(theContract.DateSigned.AddDays(60),
                                  allocs[2]);
   }
}
public class FCStrategy : BaseStrategy {
   public void CalculateRevenueRecognitions() {
        decimal[] allocs = Money.Allocate(theContract.Revenue, 3);
        theContract.AddRecognition(theContract.DateSigned, allocs[0]);
        theContract.AddRecognition(theContract.DateSigned.AddDays(60),
                                  allocs[1]);
        theContract.AddRecognition(theContract.DateSigned.AddDays(90),
                                  allocs[2]);
   }
}
public class PTStrategy : BaseStrategy {
   public void CalculateRevenueRecognitions() {
        theContract.AddRecognition(theContract.DateSigned,
                                  theContract.Revenue);
   }
}
Part 6
Part 6.1
Pattern




Prevents conflicts between concurrent
business transactions by detecting a conflict
and rolling back the transaction




                                                   90
Pattern




fonte: Patterns of Enterprise Application Architecture
Pattern




Prevents conflicts between concurrent
business transactions by allowing only one
business transaction at a time to access data




                                                   92
Pattern




fonte: Patterns of Enterprise Application Architecture
Part 6.2
Pattern GoF




Problem:
 You need a set of related classes but there are
 several sets with different implementations

Solution:
 Create a service interface, create several
 implementations of those services, create a
 factory class for each set of implementations,
 provide the client with the correct
 implementation behind the interface
Pattern GoF




Provides an interface for creating families of
related or dependent objects without
specifying their concrete classes.
Pattern GoF




fonte: Design Patterns: Elements of Reusable Object-Oriented Software
fonte: Microsoft .Net Pet Shop 3.x
Part 6.3
public class PersonDataAccess
{
    public PersonDataAccess() { ... }
    public bool Insert(object r) { ... }
    public bool Delete(object r) { ... }
    public bool Update(object r) { ... }
    public object Load(object id) { ... }
}


                                            Add logging to this
                                              existing class
public class PersonDataAccess
{
    public PersonWithLogDataAccess() { ... }
    public bool Insert(object r)
    {
            ...
           Log.Write(...);
    }
    public bool Delete(object r)
    { ... }
    public bool Update(object r)
                                               What if instead of
    { ... }
                                                 logging you
    public object Load(object id)
                                                needed billing?
    { ... }
}
public class PersonWithLogDataAccess : PersonDataAcess
{
    public PersonWithLogDataAccess() { ... }
    public bool Insert(object r)
    {
           base.Insert(r);
           logFile.Write(...);
    }
    public bool Delete(object r)
    { ... }
    public bool Update(object r)
                                            What if you
    { ... }
                                          needed logging
    public object Load(object id)
                                           and billing?
    { ... }
}
Pattern GoF




Problem:
 Allow functionally to be layered around an
 abstraction, but still dynamically changeable.

Solution:
 Combine inheritance and composition. By making
 an object that both subclasses from anther class
 and holds an instance of the class, can add new
 behavior while referring all other behavior to the
 original class.
Pattern GoF




Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for
extending functionality.




         fonte: Design Patterns: Elements of Reusable Object-Oriented Software
public interface IDataAccess
{
   public bool Insert(object   r);
   public bool Delete(object   r);
   public bool Update(object   r);
   public object Load(object   id);
}
public class PersonDataAccess : IDataAccess
{
    public PersonDataAccess () { ... }
    public bool Insert(object r) { ... }
    public bool Delete(object r) { ... }
    public bool Update(object r) { ... }
    public object Load(object id) { ... }
}
public class LoggingDecorator : IDataAccess
{
    IDataAccess component;
    public LoggingDecorator(IDataAccess component) {
            this.component = component;
    }
    public bool Insert(object r) {
            WriteLog(quot;Insertquot;, r);
            return component.Insert(r);
    }
    public bool Delete(object r) { ... }
    public bool Update(object r) { ... }
    public object Load(object id) { ... }
    private void WriteLog(string op, object parms)
    { ... }
}
public class TesteDecorator
{
    public void Teste()
    {
            IDataAccess da = new PersonIDataAccess ();
            IDataAccess dec = new LoggingDecorator(da);
           ...
           dec.Insert(...);
           ...
    }
}
Since the Decorator class implements the
same interface of the Component, it can be
used anywhere you would use a Component

Inheritance wouldn’t allow scenarios with
only Logging or only billing or both
 But you can chain Decorators!
public class CounterDecorator : IDataAccess
{
    int nAcessos = 0;
    IDataAccess component;
    public CounterDecorator(IDataAccess component) {
            this.component = component;
    }
    public bool Insert(object r) {
            nAcessos++;
            return component.Insert(r);
    }
    public bool Delete(object r) { ... }
    public bool Update(object r) { ... }
    public object Load(object id) { ... }
    public int NumOfAccesses { get { return nAcessos; } }
}
public class BillingDAL
{
    public void Teste()
    {
            IDataAccess da = new PersonDataAccess();
            IDataAccess dec = new LoggingDecorator(da);
            IDataAccess cd = new CounterDecorator(dec);
           ...
           cd.Insert(...);
           ...
           CounterDecorator bil = (CounterDecorator)cd;
           float custo = bil.NumOfAccesses * PRICE_PER_OP;
           ...
    }
}
Part 7
... Pattern ...
... Java/C#... Adapter ...
     Domain model ...




                ???? ...
          ... Java/C#... ???
                 ????
... Pattern ...
... Java/C#... Adapter ...
     Domain model ...




                                ... Pattern ...
                         ... Java/C#... Adapter ...
                              Domain model ...
Architectural
                                                                    style



output

                                                                Business
                                                               operations




  http://w2ks.dei.isep.ipp.pt/psousa/GetFile.aspx?file=PoEAAWorkbench.zip
public interface IRevenueRecognition
{
  Money RecognizedRevenue(int contractID, DateTime asOf);

    void CalculateRevenueRecognitions(int contractID);

    object GetContracts();

    object GetCustomers();

    object GetProducts();
}
common




RevenueGUI   RevenueFacade   Implementations
A combination of a Factory, a
Singleton and a Façade
The desired implementation is loaded
into memory and an instance of the
specific façade is created (reflection)
and returned to the GUI
The UI layer will then interact with the
business layer via the
IRevenueRecognition business
interface ignoring the actual
implementation
Each implementation shows a combination of
patterns that form an architectural style
 Table module + table data gateway
 Domain model / active record           These are the
 Domain model + data mapper          classes the students
                                         must “look”
 …

Define the business classes and data access
classes necessary to support the application
requirements defined by the business interface
Transaction Script using DataSet
  Transaction Script
  Transaction Script + Data Gateway
Transaction Script using Custom Classes
  Transaction Script
  Transaction Script + Row Data Gateway
Table Module
  Table Module + Table Data Gateway (DataSet)
  Table Module + Table Data Gateway (Custom Classes)
Domain Model
  Domain Model + Active Record
  Domain Model + Data Mapper
Part 8
contract
Pattern




An object that encapsulate the code that implements the
consumer portion of a contract. They act as proxies to other
services, encapsulating the details of connecting to the
source and performing any necessary translation.




         fonte: Enterprise Solution Patterns Using .NET
Pattern




Hides the details of accessing the service (ex.,
network protocol)
May be considered a data access component
Native support from most tools (e.g., Visual
Studio, Netbeans, Rational software
Architect) by web service proxies
Pattern




Provides a coarse-grained façade on fine-
grained objects to improve efficiency over a
network




       fonte: Patterns of Enterprise Application Architecture
Pattern




Domain object interfaces are tipically fine grained
Inadequeate for remote operations
Create a surronding layer above domain objects
  Local clients use the local interface
The facade may encapsulate the interface of one or
more business objects
  Domain objects:
    Address.New
    Address.Set
    Person.AddAddress
    Person.Update
  Remote Facade:
    AddressFacade.AddNewAddressToPerson
Pattern




An object that carries data between
processes in order to reduce the number of
method calls.




      fonte: Patterns of Enterprise Application Architecture
Pattern




Since XML is the de facto standard DTO should
support serialization to/from XML
Should be independent of the underlying domain
object
Should be implemented in accordance with the
requiremnts of the remote application
 CompleteCustomerInfoDTO
 BasicCustomerInfoDTO
Should be independent of the underlying platform
(e.g., programming language)
 DataSet/DataTable .net
 ResultSet JDBC
 DateTime .net
Pattern




Defines an application's boundary with a layer of services
that establishes a set of available operations and coordinates
the application's response in each operation




         fonte: Patterns of Enterprise Application Architecture
Pattern




Domain logic pattern in the context of service
orientation
May be implemented as a Remote Facade or
may be called by a Remote Facade
Pattern




Hides the complexity of finding and creating
service gateways




       fonte: Core J2EE Patterns
Part 9
How to represent the business entities?

How to persist its state?

How to code the Business logic?

How to guarantee data coherence?

How to handle application distribution?
Simple to complex logic and good platform
support for Result Sets
  Table Module

Complex logic
  Domain Model




                                            134
Table Module
  Table Data Gateway

Domain Model very similar to DB schema
  Active Record

Complex Domain Model
  Data Mapper
Guarantee that in-memory data is only updated
in one place
  Identity Map

Mantain a relation between in-memory objects
and database records
  Identity field

Avoid loading the entire DB to memory
  Lazy Load

                                                136
Hibernate e nHibernate
  www.hibernate.org
LINQ
  http://msdn.microsoft.com/en-us/netframework/aa904594.aspx
JDO
  http://java.sun.com/products/jdo/
SDO
  http://www.osoa.org/display/Main/Service+Data+Objects+Home
EJB 3
  http://java.sun.com/products/ejb/
Apache Cayenne
  http://cayenne.apache.org/
FastObjects j2
  http://www.versant.net/eu_en/products/fastobjects_j2/
FastObjects.NET
  http://www.versant.net/eu_en/products/fastobjects_net/
Prevayler
  http://www.prevayler.org/wiki.jsp
Only in data access layer
Don’t forget Views
Balance dynamic SQL and stored procedures
 Flexibility
 Security
Easyest implementation for some business
logic (e.g., group operations)


                                            138
Use parameters instead of string concatenation
DELETE is uncommon
INSERT causes no locking problem
Must be careful on UPDATE
 Concurrent access
 Incremental update
   E.g. Update quantity on hand
   UPDATE Products SET QtyOnHand = 10
   UPDATE Products SET QtyOnHand = QtyOnHand + 2
Good scalability and user-centered
availability
  Optimistic Lock

User cannot loose changes
  Pessimistic Lock
How to pass objects in a remote call?
    Data Transfer Object

How to remotely use objects with “fine grained”
interface?
    Remote Façade

How to define a coherent set of operations?
    Service Layer / Service Interface

How to hide the implementation details of the remote
call?
    Service Gateway
                                                       141
Patterns are a good thing

       Patterns can be difficult

                   Driven by example

         Will make it easier
                                   142
Fell free to download the PoEAA Workbench
http://w2ks.dei.isep.ipp.pt/psousa/GetFile.aspx
           ?file=PoEAAWorkbench.zip


        Slides available thru SlideShare
     http://www.slideshare.net/pagsousa

                                                  143
Paulo Sousa
pag@isep.ipp.pt   http://linkedin.com/in/pagsousa
Paulo Sousa
pag@isep.ipp.pt
Instituto Superior de Engenharia do Porto
Fowler, Martin. Patterns of Enterprise Application Architecture. Adisson-Wesley.
Erich Gamma, Richard Helm, Ralph Johnson, John Vissides. Design patterns : elements of
reusable object-oriented software. Adisson-Wesley.
Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal. Pattern-
oriented Software Architecture: System of Patterns.
Buschmann, F.; Henney, K. And Schmidt, D. (2007) Pattern-Oriented Software Architecture: A
Pattern Language for Distributed Computing, Volume 4. Willey.
Deepak Alur, John Crupi and Dan Malks. Core J2EE Patterns: Best Practices and Design
Strategies. Prentice Hall / Sun Microsystems Press.
http://java.sun.com/blueprints/corej2eepatterns/index.html
Enterprise Solution Patterns Using Microsoft .NET. Microsoft Press.
http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-
us/dnpatterns/html/Esp.asp
Designing Data Tier Components and Passing Data Through Tiers. Microsoft Patterns &
Practices. http://msdn.microsoft.com/library/?url=/library/en-
us/dnbda/html/BOAGag.asp?frame=true



                                                                                             147
GoF Design patterns (em C#)
http://www.dofactory.com/Patterns/Patterns.aspx
GoF & POSA Design patterns (em Java)
http://www.vico.org/pages/PatronsDisseny.html
Patterns of Enterprise Application architecture
http://martinfowler.com/eaaCatalog/
Core J2EE Patterns
http://www.corej2eepatterns.com

Enterprise Solution Patterns Using Microsoft .NET.
http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-
us/dnpatterns/html/Esp.asp

Patterns of Enterprise Application Integration
http://www.enterpriseintegrationpatterns.com/

Enterprise Java Patterns @ The Server Side
http://www.theserverside.com/patterns/index.tss

Microsoft Data Patterns
http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en-
us/dnpatterns/html/Dp.asp

Más contenido relacionado

La actualidad más candente

Clean architecture
Clean architectureClean architecture
Clean architectureLieven Doclo
 
Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Araf Karsh Hamid
 
Domain-Driven Design
Domain-Driven DesignDomain-Driven Design
Domain-Driven DesignAndriy Buday
 
Design patterns for microservice architecture
Design patterns for microservice architectureDesign patterns for microservice architecture
Design patterns for microservice architectureThe Software House
 
Slides - Tailwind CSS.pdf
Slides - Tailwind CSS.pdfSlides - Tailwind CSS.pdf
Slides - Tailwind CSS.pdfIgorAugusto76
 
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...Natanael Simões
 
Microservices Architectures: Become a Unicorn like Netflix, Twitter and Hailo
Microservices Architectures: Become a Unicorn like Netflix, Twitter and HailoMicroservices Architectures: Become a Unicorn like Netflix, Twitter and Hailo
Microservices Architectures: Become a Unicorn like Netflix, Twitter and Hailogjuljo
 
Api gateway in microservices
Api gateway in microservicesApi gateway in microservices
Api gateway in microservicesKunal Hire
 
Agile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAgile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAraf Karsh Hamid
 
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...Microservice Architecture | Microservices Tutorial for Beginners | Microservi...
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...Edureka!
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkHùng Nguyễn Huy
 
Domain Driven Design Quickly
Domain Driven Design QuicklyDomain Driven Design Quickly
Domain Driven Design QuicklyMariam Hakobyan
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introductionJonathan Holloway
 
Domain driven design
Domain driven designDomain driven design
Domain driven designtatyaso
 

La actualidad más candente (20)

Clean architecture
Clean architectureClean architecture
Clean architecture
 
Spring GraphQL
Spring GraphQLSpring GraphQL
Spring GraphQL
 
Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018Microservices Architecture - Bangkok 2018
Microservices Architecture - Bangkok 2018
 
Domain-Driven Design
Domain-Driven DesignDomain-Driven Design
Domain-Driven Design
 
Design patterns for microservice architecture
Design patterns for microservice architectureDesign patterns for microservice architecture
Design patterns for microservice architecture
 
Slides - Tailwind CSS.pdf
Slides - Tailwind CSS.pdfSlides - Tailwind CSS.pdf
Slides - Tailwind CSS.pdf
 
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...
Processo de Desenvolvimento de Software - Design de Software, Interface, Arqu...
 
Microservices Architectures: Become a Unicorn like Netflix, Twitter and Hailo
Microservices Architectures: Become a Unicorn like Netflix, Twitter and HailoMicroservices Architectures: Become a Unicorn like Netflix, Twitter and Hailo
Microservices Architectures: Become a Unicorn like Netflix, Twitter and Hailo
 
Api gateway in microservices
Api gateway in microservicesApi gateway in microservices
Api gateway in microservices
 
Agile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven DesignAgile, User Stories, Domain Driven Design
Agile, User Stories, Domain Driven Design
 
Apresentação angular js
Apresentação angular jsApresentação angular js
Apresentação angular js
 
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...Microservice Architecture | Microservices Tutorial for Beginners | Microservi...
Microservice Architecture | Microservices Tutorial for Beginners | Microservi...
 
Introduction to GraphQL
Introduction to GraphQLIntroduction to GraphQL
Introduction to GraphQL
 
Laravel Eloquent ORM
Laravel Eloquent ORMLaravel Eloquent ORM
Laravel Eloquent ORM
 
Integração Contínua
Integração ContínuaIntegração Contínua
Integração Contínua
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Domain Driven Design Quickly
Domain Driven Design QuicklyDomain Driven Design Quickly
Domain Driven Design Quickly
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
 
Domain driven design
Domain driven designDomain driven design
Domain driven design
 

Destacado (15)

REST beyond CRUD
REST beyond CRUDREST beyond CRUD
REST beyond CRUD
 
Enterprise Integration Patterns
Enterprise Integration PatternsEnterprise Integration Patterns
Enterprise Integration Patterns
 
Principles of Service Orientation
Principles of Service OrientationPrinciples of Service Orientation
Principles of Service Orientation
 
Patterns for distributed systems
Patterns for distributed systemsPatterns for distributed systems
Patterns for distributed systems
 
Lição prova professor coordenador
Lição prova professor coordenadorLição prova professor coordenador
Lição prova professor coordenador
 
Design Patterns: From STUPID to SOLID code
Design Patterns: From STUPID to SOLID codeDesign Patterns: From STUPID to SOLID code
Design Patterns: From STUPID to SOLID code
 
Modern web architectural patterns
Modern web architectural patternsModern web architectural patterns
Modern web architectural patterns
 
Rest web services
Rest web servicesRest web services
Rest web services
 
Decoupled Communication
Decoupled CommunicationDecoupled Communication
Decoupled Communication
 
Communication
CommunicationCommunication
Communication
 
RESTful services Design Lab
RESTful services Design LabRESTful services Design Lab
RESTful services Design Lab
 
Software Product Lines
Software Product LinesSoftware Product Lines
Software Product Lines
 
Benefits of Hypermedia API
Benefits of Hypermedia APIBenefits of Hypermedia API
Benefits of Hypermedia API
 
OO design principles and patterns
OO design principles and patternsOO design principles and patterns
OO design principles and patterns
 
Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)Patterns of Enterprise Application Architecture (by example)
Patterns of Enterprise Application Architecture (by example)
 

Similar a PoEAA by Example

Python business intelligence (PyData 2012 talk)
Python business intelligence (PyData 2012 talk)Python business intelligence (PyData 2012 talk)
Python business intelligence (PyData 2012 talk)Stefan Urbanek
 
Dublin Ireland Spark Meetup October 15, 2015
Dublin Ireland Spark Meetup October 15, 2015Dublin Ireland Spark Meetup October 15, 2015
Dublin Ireland Spark Meetup October 15, 2015eddiebaggott
 
Whidbey old
Whidbey old Whidbey old
Whidbey old grenaud
 
CHOReOS Web Services FISL Conference Brazil 2012
CHOReOS Web Services FISL Conference Brazil 2012CHOReOS Web Services FISL Conference Brazil 2012
CHOReOS Web Services FISL Conference Brazil 2012choreos
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxSumant Tambe
 
Data Access Tech Ed India
Data Access   Tech Ed IndiaData Access   Tech Ed India
Data Access Tech Ed Indiarsnarayanan
 
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...Noriaki Tatsumi
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB
 
PDC Video on C# 4.0 Futures
PDC Video on C# 4.0 FuturesPDC Video on C# 4.0 Futures
PDC Video on C# 4.0 Futuresnithinmohantk
 
16 greg hope_com_wics
16 greg hope_com_wics16 greg hope_com_wics
16 greg hope_com_wicsashish61_scs
 
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...AlexACMSC
 
Building DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchBuilding DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchEelco Visser
 
Orm and hibernate
Orm and hibernateOrm and hibernate
Orm and hibernates4al_com
 
Best Practices for Building and Deploying Data Pipelines in Apache Spark
Best Practices for Building and Deploying Data Pipelines in Apache SparkBest Practices for Building and Deploying Data Pipelines in Apache Spark
Best Practices for Building and Deploying Data Pipelines in Apache SparkDatabricks
 
Scalding big ADta
Scalding big ADtaScalding big ADta
Scalding big ADtab0ris_1
 
Benefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsBenefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsMongoDB
 
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...Joseph Alaimo Jr
 

Similar a PoEAA by Example (20)

Super spike
Super spikeSuper spike
Super spike
 
Python business intelligence (PyData 2012 talk)
Python business intelligence (PyData 2012 talk)Python business intelligence (PyData 2012 talk)
Python business intelligence (PyData 2012 talk)
 
Dublin Ireland Spark Meetup October 15, 2015
Dublin Ireland Spark Meetup October 15, 2015Dublin Ireland Spark Meetup October 15, 2015
Dublin Ireland Spark Meetup October 15, 2015
 
Whidbey old
Whidbey old Whidbey old
Whidbey old
 
CHOReOS Web Services FISL Conference Brazil 2012
CHOReOS Web Services FISL Conference Brazil 2012CHOReOS Web Services FISL Conference Brazil 2012
CHOReOS Web Services FISL Conference Brazil 2012
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
 
Data Access Tech Ed India
Data Access   Tech Ed IndiaData Access   Tech Ed India
Data Access Tech Ed India
 
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...
GraphQL Summit 2019 - Configuration Driven Data as a Service Gateway with Gra...
 
MongoDB World 2018: Keynote
MongoDB World 2018: KeynoteMongoDB World 2018: Keynote
MongoDB World 2018: Keynote
 
PDC Video on C# 4.0 Futures
PDC Video on C# 4.0 FuturesPDC Video on C# 4.0 Futures
PDC Video on C# 4.0 Futures
 
16 greg hope_com_wics
16 greg hope_com_wics16 greg hope_com_wics
16 greg hope_com_wics
 
Solving the n + 1 query problem
Solving the n + 1 query problemSolving the n + 1 query problem
Solving the n + 1 query problem
 
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...
Alexandria ACM Student Chapter | Specification & Verification of Data-Centric...
 
Building DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchBuilding DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language Workbench
 
Orm and hibernate
Orm and hibernateOrm and hibernate
Orm and hibernate
 
Best Practices for Building and Deploying Data Pipelines in Apache Spark
Best Practices for Building and Deploying Data Pipelines in Apache SparkBest Practices for Building and Deploying Data Pipelines in Apache Spark
Best Practices for Building and Deploying Data Pipelines in Apache Spark
 
Scalding big ADta
Scalding big ADtaScalding big ADta
Scalding big ADta
 
Benefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSsBenefits of Using MongoDB Over RDBMSs
Benefits of Using MongoDB Over RDBMSs
 
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...
FDMEE Scripting - Cloud and On-Premises - It Ain't Groovy, But It's My Bread ...
 
B_110500002
B_110500002B_110500002
B_110500002
 

Más de Paulo Gandra de Sousa (9)

Introduction to Microservices
Introduction to MicroservicesIntroduction to Microservices
Introduction to Microservices
 
Minds-on DDD
Minds-on DDDMinds-on DDD
Minds-on DDD
 
Introduction to microservices
Introduction to microservicesIntroduction to microservices
Introduction to microservices
 
Design Patterns: Back to Basics
Design Patterns: Back to BasicsDesign Patterns: Back to Basics
Design Patterns: Back to Basics
 
Hypermedia APIs
Hypermedia APIsHypermedia APIs
Hypermedia APIs
 
Revision control with Mercurial
Revision control with MercurialRevision control with Mercurial
Revision control with Mercurial
 
Documenting Software Architectures
Documenting Software ArchitecturesDocumenting Software Architectures
Documenting Software Architectures
 
models of distributed computing
models of distributed computingmodels of distributed computing
models of distributed computing
 
Distributed Systems
Distributed SystemsDistributed Systems
Distributed Systems
 

Último

Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdfChristopherTHyatt
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 

Último (20)

Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 

PoEAA by Example

  • 2. Introduction Enterprise Applications Sample problem Business entities Business logic and data access Some improvements Sample application Patterns for distributed applications Synopsis Conclusions
  • 4. “Each pattern describes a problem that occurs over and over again in our environment and then describes the core of the solution to that problem in such a way that you can use this solution a million times over without ever doing it the same way twice.” Christopher Alexander (architect)
  • 5. “A Software Design Pattern names, abstracts, and identifies the key aspects of a common design structure that make it useful for creating a reusable object-oriented design.” Design Patterns-Elements of Reusable Object-oriented Software, Gamma et al. (Gang of Four)
  • 6.
  • 7. a set of best practices a typified solution to a problem in a given context a way to facilitate communication found not invented
  • 9. No direct code reuse Pattern overload Experience-based validation Hard work integrating patterns in the development process 8
  • 10. name Contributes to the pattern vocabulary synopsis Short description of the problem the pattern will solve. forces Requirements, considerations, or necessary conditions solution The essence of the solution counter forces Reasons for not using the pattern. related patterns Possible alternatives in the design. 9
  • 11. GoF Gang of Four POSA Pattern-Oriented Software Architecture PoEAA Patterns of Enterprise Application Architecture CJP Core J2EE Patterns ESP Enterprise Solution Patterns using Microsoft .NET 10
  • 13. Critical functionality Large quantity of concurrently accessed data Large number of screens Integration Conceptual dissonance Complex (ilogic) business rules
  • 14. “[Software Architecture is] the fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution.“ ANSI/IEEE Std 1471-2000, Recommended Practice for Architectural Description of Software-Intensive Systems
  • 15.
  • 16. fonte: Application Architecture for .NET: designing applications and Services
  • 17. Layers fonte: Core J2EE Patterns
  • 18. fonte: Application Architecture for .NET: designing applications and Services
  • 19. How to represent the business entities? How to persist its state? How to code the Business logic? how to guarantee data coherence? How to handle application distribution?
  • 21. Revenue recognition Three different products Word processors, databases, spreadsheets Different payment rules WP – all at once (t) DB – 3 payments: t, t+30, t+60 SS – 3 payments: t, t+60, t+90 (From Martin Fowler’s PoEAA book)
  • 22. Customer Contract Product 1 * + name + revenue + name * + dateSigned 1 1 WordProcessor SpreadSheet * RevenueRecognition + dateRecognition DataBase + amount
  • 23. «table» TRevenueRecognitions + «Column» ID : int + «Column» contractID : int + «Column» dateRecognition : date + «Column» amount : currency «table» «table» TContracts TProducts «table» + «Column» ID : int TCustomers + «Column» ID : int + «Column» productID : int + «Column» type : varchar + «Column» ID : int + «Column» customerID : int + «Column» name : varchar + «Column» name : varchar + «Column» revenue : currency + «Column» dateSigned : date
  • 24. public interface IRevenueRecognition { void CalculateRevenueRecognitions(int contractID); Money RecognizedRevenue(int contractID, DateTime asOf); object GetContracts(); object GetCustomers(); object GetProducts(); }
  • 25.
  • 27. How to represent: One entity, e.g. Customer? Collections, e.g., List of customers? Networked/complex objects, e.g., production plan? Structure and behaviour Structure + behaviour? Structure with behaviour? Behaviour (and attributes)? Persistence structure ≠ conceptual structure?
  • 29. Custom classes IList / List XML DataSet (.net) / ResultSet (JDBC)
  • 30. User defined code with members for the entity’s attributes Product + Type : int + Name : string + ID : int
  • 31. Product Contract Customer + Type : int + Revenue : decimal + Name : string + DateSigned : DateTime + Name : string + ID : int + CustomerID : int + ID : int + ProductID : int + ID : int * + RevenueRecognitions RevenueRecognition + DateRecognition : DateTime + Amount : decimal + ContractID : int + ID : int
  • 32. An XML document (or string) representing an entity’s structure <product> <id>123</id> <name>SuperWriter 7.3</name> <type>Word Processor</type> </product>
  • 33. A DataSet (or derived class) to hold tabular data (eventually directly from a data source)
  • 34. A class implementing the ResultSet interface to hold tabular data (eventually directly from a data source)
  • 35. A library collection class (e.g. LinkedList) LinkedList
  • 37. Table oriented BLL Table Module DAL Table Data Gateway Object oriented BLL Domain Model Active Record DAL BLL Data Mapper
  • 39. UI Uses the platform’s ResultSet for sharing entity data «table module» beteween layers BLL «table data gateway» DAL
  • 40. Pattern A single instance that handles the business logic for all rows in a database table or view fonte: Patterns of Enterprise Application Architecture
  • 41. Contract + Contract ( ) + RecognizedRevenue ( [in] contractID : int , [in] asOf : DateTime ) : Money + CalculateRevenueRecognitions ( [in] contractID : int ) + GetContracts ( ) : DataSet + GetContractsByProduct ( [in] productID : int ) : DataSet + GetContractsByCustomer ( [in] customerID : int ) : DataSet Customer + Customer ( ) + GetCustomers ( ) : DataTable Product + Product ( ) + GetProducts ( ) : DataTable
  • 42. Pattern An object that acts as a Gateway to a database table. One instance handles all the rows in the table Business entity fonte: Patterns of Enterprise Application Architecture
  • 43. CustomerGateway + CustomerGateway ( ) + GetCustomers ( ) : DataTable ContractGateway ProductGateway + ContractGateway ( ) + InsertRecognition ( [in] contractID : int , [in] recognitionDate : DateTime , [in] amount : decimal ) : int + ProductGateway ( ) + GetContracts ( ) : DataSet + GetProducts ( ) : DataTable + GetContractByID ( [in] contractID : int ) : DataSet + GetContractsByProduct ( [in] productID : int ) : DataSet + GetContractsByCustomer ( [in] customerID : int ) : DataSet BaseGateway # «property» CurrentTransaction : OleDbTransaction - CONNSTR : string = @quot;Provider=...quot; + BaseGateway ( ) # GetConnection ( [in] open : bool ) : OleDbConnection # ExecuteQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : DataSet # ExecuteNonQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : int # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] sql : string ) : int # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int + BeginTransaction ( ) 42 + CommitTransaction ( ) ISEP/IP + RoolbackTransaction ( ) # «get» CurrentTransaction ( ) : OleDbTransaction P
  • 44. / User : Actor1 / GUI / ClassifierRole1 : Contract / ClassifierRole2 : Contract Gateway 1 : Form_Load 2 : GetContracts ( ) 3 : GetContracts ( ) 4 : GetConnection ( open ) 5 : ExecuteQuery ( cnx , sql )
  • 45. / User : Actor1 / GUI / ClassifierRole1 : Contract 1 : btnCalcRevenues_Click 2 : CalculateRevenueRecognitions ( contractID ) 3 : new / ClassifierRole2 : Contract Gateway 4 : GetContractByID ( contractID ) 5 : BeginTransaction ( ) foreach calculated 6 : InsertRecognition ( contractID , recognition recognitionDate , amount ) 7 : CommitTransaction ( )
  • 46. Returns a join of public void CalculateRevenueRecognitions(int contractID) { TContracts and DAL.ContractGateway dal = new DAL.ContractGateway(); DataSet ds = dal.GetContractByID(contractID); TProducts string prodType = (string)ds.Tables[0].Rows[0][quot;typequot;]; decimal totalRevenue = (decimal)ds.Tables[0].Rows[0][quot;revenuequot;]; DateTime recDate = (DateTime)ds.Tables[0].Rows[0][quot;dateSignedquot;]; dal.BeginTransaction(); switch (prodType) { case quot;PTquot;: dal.InsertRecognition(contractID, recognitionDate, totalRevenue); break; case quot;FCquot;: decimal[] allocs = Money.Allocate(totalRevenue, 3); dal.InsertRecognition(contractID, recDate, allocs[0]); dal.InsertRecognition(contractID, recDate.AddDays(60), allocs[1]); dal.InsertRecognition(contractID, recDate.AddDays(90), allocs[2]); break; case quot;BDquot;: decimal[] allocs = Money.Allocate(totalRevenue, 3); dal.InsertRecognition(contractID, recDate, allocs[0]); dal.InsertRecognition(contractID, recDate.AddDays(30), allocs[1]); dal.InsertRecognition(contractID, recDate.AddDays(60), allocs[2]); break; Explicit transaction control } dal.CommitTransaction(); ☺/ }
  • 47. public int InsertRecognition(int contractID, DateTime recognitionDate, decimal amount) { OleDbCommand sqlcmd = new OleDbCommand( quot;INSERT INTO TRevenueRecognitions (contractID, dateRecognition, amount) VALUES (?, ?, ?)quot;, CurrentTransation.Connection, CurrentTransation ); sqlcmd.Parameters.Add(quot;@cidquot;, contractID); sqlcmd.Parameters.Add(quot;@dtquot;, recognitionDate); sqlcmd.Parameters.Add(quot;@amtquot;, amount); return ExecuteNonQuery(CurrentTransation, sqlcmd); }
  • 49. UI These classes only have attributes (no business logic- «table module» Entities related behaviour) BLL «table data gateway» DAL
  • 50. Product Contract Customer + Type : int + Revenue : decimal + Name : string + DateSigned : DateTime + Name : string + ID : int + CustomerID : int + ID : int + ProductID : int + ID : int * + RevenueRecognitions RevenueRecognition + DateRecognition : DateTime + Amount : decimal + ContractID : int + ID : int
  • 51. Contract + Contract ( ) + RecognizedRevenue ( [in] contractID : int , [in] asOf : DateTime ) : Money + CalculateRevenueRecognitions ( [in] contractID : int ) + GetContracts ( ) : IList + GetContractsByProduct ( [in] productID : int ) : IList + GetContractsByCustomer ( [in] customerID : int ) : IList Customer + Customer ( ) + GetCustomers ( ) : IList Product + Product ( ) + GetProducts ( ) : IList
  • 52. CustomerGateway ContractGateway + CustomerGateway ( ) + GetCustomers ( ) : IList + ContractGateway ( ) - CreateCustomerObject ( [in] r : DataRow ) : Customer + InsertRecognition ( [in] contractID : int , [in] recognitionDate : DateTime , [in] amount : decimal ) : int + GetContracts ( ) : IList + GetContractByID ( [in] contractID : int ) : Contract ProductGateway + GetContractsByProduct ( [in] productID : int ) : IList + GetContractsByCustomer ( [in] customerID : int ) : IList + ProductGateway ( ) - CreateContractObject ( [in] r : DataRow ) : Contract + GetProducts ( ) : IList - CreateRevenueRecognitionObject ( [in] r : DataRow ) : RevenueRecognition - CreateProductObject ( [in] r : DataRow ) : Product BaseGateway # «property» CurrentTransaction : OleDbTransaction - CONNSTR : string = @quot;Provider=...quot; + BaseGateway ( ) # GetConnection ( [in] open : bool ) : OleDbConnection # ExecuteQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : DataSet # ExecuteNonQuery ( [in] cnx : OleDbConnection , [in] sql : string ) : int # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] sql : string ) : int # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int + BeginTransaction ( ) + CommitTransaction ( ) 51 + RoolbackTransaction ( ) ISEP/IP # «get» CurrentTransaction ( ) : OleDbTransaction P
  • 53. / User : Actor1 / GUI / ClassifierRole1 : Contract 1 : Form_Load 2 : GetContracts ( ) / ClassifierRole2 : Contract 3 : new Gateway 4 : GetContracts ( ) 5 : GetConnection ( open ) 6 : ExecuteQuery ( cnx , sql ) 7 : new / IList 8 : new / ClassifierRole3 : Contract foreach row returned 9 : Add 52 ISEP/IP P
  • 54. / GUI / bll : Contract Sequence 1 : btnCalcRevenues_click 2 : CalculateRevenueRecognitions ( CalculateRevenues contractID ) 3 : new / dalC : ContractGateway 4 : GetContractByID ( contractID ) 5 : CreateContractObject ( r ) 6 : new / c : Contract 7 : new / dalP : ProductGateway 8 : GetProductByID ( productID ) 9 : CreateProductObject ( r ) 10 : new / p : Product 11 : BeginTransaction ( ) foreach calculated revenue 12 : InsertRecognition ( contractID , recognitionDate , amount ) 13 : ExecuteNonQuery ( tx , cmd ) 14 : CommitTransaction ( )
  • 55. public void CalculateRevenueRecognitions(int contractID) { DAL.ContractGateway dalC = new DAL.ContractGateway(); Entities.Contract c = dalC.GetContractByID(contractID); DAL.ProductGateway dalP = new DAL.ProductGateway(); TM.Entities.Product p = dalP.GetProductByID(c.ProductID); dalC.BeginTransaction(); switch (p.Type) { case quot;PTquot;: dalC.InsertRecognition(contractID, c.DateSigned, c.Revenue); break; case quot;FCquot;: decimal[] alcs = Money.Allocate(c.Revenue, 3); dalC.InsertRecognition(contractID, c.DateSigned, allocs[0]); dalC.InsertRecognition(contractID, c.DateSigned.AddDays(60), alcs[1]); dalC.InsertRecognition(contractID, c.DateSigned.AddDays(90), alcs[2]); break; case quot;BDquot;: decimal[] alcs = Money.Allocate(c.Revenue, 3); dalC.InsertRecognition(contractID, c.DateSigned, allocs[0]); dalC.InsertRecognition(contractID, c.DateSigned.AddDays(30), alcs[1]); dalC.InsertRecognition(contractID, c.DateSigned.AddDays(60), alcs[2]); break; } dalC.CommitTransaction(); }
  • 57. GUI «domain model + active record» BLL + DAL
  • 58. Pattern An object model of the domain that incorporates both behavior and data fonte: Patterns of Enterprise Application Architecture
  • 59. Pattern An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data fonte: Patterns of Enterprise Application Architecture 58
  • 60. Can be divided: Classes (a) ActiveRecord BLL/DAL (b) DBHelper ActiveRecord # myID : int # «property» CurrentTransaction : OleDbTransaction Product - CONNSTR : string = @quot;Provider=...quot; + «property» ID : int + «property» Type : string - _name : string + Save ( ) - _type : string + ActiveRecord ( ) 0..1 # GetConnection ( [in] open : bool ) : OleDbConnection + Product ( ) - _Product # ExecuteQuery ( [in] sql : string ) : DataSet # Product ( [in] row : DataRow ) # ExecuteTransactedQuery ( [in] sql : string ) : DataSet + LoadById ( [in] productID : int ) : Product # ExecuteNonQuery ( [in] sql : string ) : int + LoadAll ( ) : IList # ExecuteTransactedNonQuery ( [in] sql : string ) : int + Save ( ) # ExecuteNonQuery ( [in] tx : OleDbTransaction , [in] cmd : OleDbCommand ) : int + «get» Type ( ) : string # BeginTransaction ( ) # CommitTransaction ( ) # RoolbackTransaction ( ) # «get» CurrentTransaction ( ) : OleDbTransaction + «get» ID ( ) : int Customer # ExecuteTransactedNonQuery ( [in] cmd : OleDbCommand ) : int - Name : string + Customer ( ) - _Customer # Customer ( [in] row : DataRow ) Contract 0..1 + LoadById ( [in] customerID : int ) : Customer + LoadAll ( ) : IList - CustomerID : int + Save ( ) - DateSigned : DateTime - ProductID : int - Revenue : decimal # «property» Product : Product + Contract ( ) RevenueRecognition # Contract ( [in] row : DataRow ) - RevenueRecognitions + Amount : decimal # Contract ( [in] dsContractAndRecognitions : DataSet ) + RecognizedRevenue ( [in] asOf : DateTime ) : Money * + DateRecognition : DateTime + CalculateRevenueRecognitions ( ) + ID : int + LoadById ( [in] contractID : int ) : Contract + RevenueRecognition ( [in] id : int , [in] dt : DateTime , [in] amt : decimal ) + LoadByProduct ( [in] productID : int ) : IList + RevenueRecognition ( [in] dt : DateTime , [in] amt : decimal ) + LoadByCustomer ( [in] customerID : int ) : IList + LoadAll ( ) : IList + Save ( ) inner private # AddRecognition ( [in] recognitionDate : DateTime , [in] amount : decimal ) class # «get» Product ( ) : Product
  • 61. DBHelper + «property» CurrentTransaction : OleDbTransaction ActiveRecord - CONNSTR : string = @quot;Provider=...quot; # myID : int + DBHelper ( ) + «property» ID : int + GetConnection ( ) + Save ( ) + ExecuteQuery ( ) + ActiveRecord ( ) + ExecuteTransactedQuery ( ) + «get» ID ( ) + ExecuteNonQuery ( ) + ExecuteTransactedNonQuery ( ) + ExecuteNonQuery ( ) + BeginTransaction ( ) + CommitTransaction ( ) + RoolbackTransaction ( ) Product Contract Customer + «get» CurrentTransaction ( ) - Name : string - CustomerID : int - Name : string - Type : int - DateSigned : DateTime 0..1 + Customer ( ) - ProductID : int - _Customer inner private class + Product ( ) + LoadById ( ) - Revenue : decimal + LoadById ( ) 0..1 + LoadAll ( ) + LoadAll ( ) - _Product + Contract ( ) + Save ( ) + Save ( ) + RecognizedRevenue ( ) + CalculateRevenueRecognitions ( ) RevenueRecognition + LoadById ( ) + LoadByProduct ( ) - RevenueRecognitions + Amount : decimal + LoadByCustomer ( ) * + DateRecognition : DateTime + LoadAll ( ) + ID : int + Save ( ) + RevenueRecognition ( )
  • 62. / User : Actor1 / GUI : Contract 1 : Form_Load 2 : LoadAll ( ) 3 : ExecuteQuery ( sql ) 4 : new / IList 5 : Contract ( row ) / ClassifierRole2 : Contract 6 : Add foreach returned row
  • 63. Networks of objects E.g. Invoice heading relates to invoice details Invoice details refers to Products Products refers to Suppliers … What to do? Load them all into memory? How to disallow multiple in-memory copies 62
  • 64. Pattern An object that doesn't contain all of the data you need but knows how to get it. fonte: Patterns of Enterprise Application Architecture
  • 65. Pattern Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them fonte: Patterns of Enterprise Application Architecture 64
  • 66. / User : Actor1 / GUI : Contract Sequence 1 : btnCalcRevenues_Click CalculateRevenues 2 : LoadById ( contractID ) 3 : ExecuteQuery ( sql ) 4 : Contract ( row ) / aContract : Contract 5 : CalculateRevenueRecognitions ( ) 6 : AddRecognition ( recognitionDate , amount ) foreach calculated recognition 7 : Save ( ) 8 : BeginTransaction ( ) 9 : ExecuteTransactedNonQuery ( sql ) 10 : ExecuteTransactedNonQuery ( sql ) foreach RevenueRecognition object in _RevenueRecognitions 11 : CommitTransaction ( )
  • 67. public void CalculateRevenueRecognitions() { switch (this.Product.Type) { case quot;PTquot;: AddRecognition(this.DateSigned, this.Revenue); break; case quot;FCquot;: decimal[] allocsFC = Money.Allocate(Revenue, 3); AddRecognition(DateSigned, allocsFC[0]); AddRecognition(DateSigned.AddDays(60), allocsFC[1]); AddRecognition(DateSigned.AddDays(90), allocsFC[2]); break; case quot;BDquot;: decimal[] allocsBD = Money.Allocate(Revenue, 3); AddRecognition(DateSigned, allocsBD[0]); AddRecognition(DateSigned.AddDays(30), allocsBD[1]); AddRecognition(DateSigned.AddDays(60), allocsBD[2]); break; } }
  • 68. // foreign key private int ProductID; // object pointer private Product _Product; // relationship property protected Product Product { get { // Lazy Load if (this._Product == null) this._Product = Product.LoadById(this.ProductID); return this._Product; } }
  • 69. // Identity Map public static IDictionary loaded = new Hashtable(); public static Product LoadById(int productID) { // check registry – Identity Map Product p = (Product)loaded[productID]; if (p != null) return p; // load Product aux = new Product(); DataSet ds = ExecuteQuery(quot;SELECT * FROM TProducts WHERE productID=quot; + productID); p = new Product(ds.Tables[0].Rows[0]); // save in registry loaded[productID] = p; return p; }
  • 70. public void Save() { BeginTransaction(); object[] parms = new object[] {this.ProductID, this.CustomerID, this.DateSigned, this.Revenue, this.ID}; if (this.ID != 0) { sqlContract = quot;UPDATE TContracts SET productId=?, customerID=?, dateSigned=?, revenue=? WHERE contractID=?quot;; ExecuteTransactedNonQuery(sqlContract, parms); ExecuteTransactedNonQuery(quot;DELETE FROM TRevenueRecognitions WHERE contractID=quot; + this.ID); } else { sqlContract = quot;INSERT INTO TContracts(productId, customerId, dateSigned, revenue) VALUES(?, ?, ?, ?)quot;; this.myID = ExecuteTransactedNonQuery(sqlContract, parms); } foreach (RevenueRecognition r in _RevenueRecognitions) { string sqlRecognition = quot;INSERT INTO TRevenueRecognitions(contractID, dateRecognition, amount) VALUES(?, ?, ?)quot;; object parms[] = new object[] {this.ID, r.DateRecognition, r.Amount}; ExecuteTransactedNonQuery(sqlRecognition, parms); } CommitTransaction(); }
  • 72. UI «domain model» «data mapper» BLL DAL Database
  • 73. Customer Contract - _ID : int + «property» Product : Product - _name : string - _ID : int + «property» ID : int - _Customer Business logic - _CustomerID : int - _DateSigned : DateTime + Customer ( ) methods only - _ProductID : int + «get» ID ( ) : int - _Revenue : decimal + «property» Customer : Customer + «property» RevenueRecognitions : IList Product + «property» DateSigned : DateTime + «property» Type : string + «property» Revenue : decimal - _ID : int + «property» ID : int - _name : string ~ AddRecognition ( [in] recognitionDate : DateTime , [in] amount : decimal ) - _type : string + Contract ( ) + «property» ID : int + RecognizedRevenue ( [in] asOf : DateTime ) : Money + Product ( ) + CalculateRevenueRecognitions ( ) - _Product + «get» Type ( ) : string + «get» Product ( ) : Product + «get» ID ( ) : int ~ SetID ( [in] id : int ) ~ SetProduct ( [in] prodID : int , [in] prodType : string ) - SetStrategy ( [in] prodType : string ) IRevenueRecognitionStrategy ~ SetProduct ( [in] prodID : int ) - theStrategy + «get» Customer ( ) : Customer + «get» RevenueRecognitions ( ) : IList RevenueRecognition + «get» DateSigned ( ) : DateTime + «get» Revenue ( ) : decimal + Amount : decimal + «get» ID ( ) : int + DateRecognition : DateTime ~ SetCustomer ( [in] custID : int ) + ID : int + «set» Product ( [in] value : Product ) + «set» DateSigned ( [in] value : DateTime ) + RevenueRecognition ( [in] id : int , [in] dt : DateTime , [in] amt : decimal ) 72 + «set» Revenue ( [in] value : decimal ) + RevenueRecognition ( [in] dt : DateTime , [in] amt : decimal ) ISEP/IP * - _RevenueRecognitions P
  • 74. public void CalculateRevenueRecognitions() { switch (this.Product.Type) { case quot;PTquot;: AddRecognition(this.DateSigned, this.Revenue); break; case quot;FCquot;: decimal[] allocsFC = Money.Allocate(Revenue, 3); AddRecognition(DateSigned, allocsFC[0]); AddRecognition(DateSigned.AddDays(60), allocsFC[1]); AddRecognition(DateSigned.AddDays(90), allocsFC[2]); break; case quot;BDquot;: decimal[] allocsBD = Money.Allocate(Revenue, 3); AddRecognition(DateSigned, allocsBD[0]); AddRecognition(DateSigned.AddDays(30), allocsBD[1]); AddRecognition(DateSigned.AddDays(60), allocsBD[2]); break; } }
  • 75. Pattern GoF Problem: Allow the client the choice of many alternatives, but each is complex, and you don't want to include code for all. Solution: Make many implementations of the same interface, and allow the client to select one and give it back to you.
  • 76. Pattern GoF Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. fonte: Design Patterns: Elements of Reusable Object-Oriented Software
  • 77. public interface IRevenueRecognitionStrategy { void CalculateRevenueRecognitions(); }
  • 78. BaseStrategy + theContract Contract + BaseStrategy ( [in] c : Contract ) + CreateStrategy ( [in] prodType : string , [in] c : Contract ) : IRevenueRecognitionStrategy BDStrategy FCStrategy PTStrategy + BDStrategy ( [in] c : Contract ) + FCStrategy ( [in] c : Contract ) + PTStrategy ( [in] c : Contract ) + CalculateRevenueRecognitions ( ) + CalculateRevenueRecognitions ( ) + CalculateRevenueRecognitions ( ) IRevenueRecognitionStrategy
  • 79. Pattern A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself fonte: Patterns of Enterprise Application Architecture
  • 80. IDBHelper DBHelper ContractMapper CustomerMapper ProductMapper + ContractMapper ( ) + CustomerMapper ( ) + ProductMapper ( ) # ApplyMap ( [in] row : DataRow ) : Contract # ApplyMap ( [in] row : DataRow ) : Customer # ApplyMap ( [in] row : DataRow ) : Product # ApplyMap ( [in] dsContractAndRecognitions : DataSet ) : Contract + LoadById ( [in] customerID : int ) : Customer + LoadById ( [in] productID : int ) : Product + LoadById ( [in] contractID : int ) : Contract + LoadAll ( ) : IList + LoadAll ( ) : IList + LoadByProduct ( [in] productID : int ) : IList + LoadByCustomer ( [in] customerID : int ) : IList + LoadAll ( ) : IList + Save ( [in] c : Contract ) IdentityMap # «property» Registry : IDictionary + IdentityMap ( ) DBFactory # CheckRegistry ( [in] id : int ) : object # AddToRegistry ( [in] id : int , [in] o : object ) + DBFactory ( ) # «get» Registry ( ) : IDictionary + CreateDBHelper ( ) : IDBHelper 79
  • 81. DBHelper + «property» CurrentTransaction : IDbTransaction - CONNSTR : string = @quot;Provider=...quot; + DBHelper ( ) + BeginTransaction ( ) + CommitTransaction ( ) + ExecuteNonQuery ( [in] tx : IDbTransaction , [in] cmd : IDbCommand ) : int + ExecuteNonQuery ( [in] sql : string ) : int + ExecuteQuery ( [in] sql : string ) : DataSet IDBHelper + ExecuteTransactedNonQuery ( [in] sql : string ) : int + ExecuteTransactedQuery ( [in] sql : string ) : DataSet + GetConnection ( [in] open : bool ) : IDbConnection + RoolbackTransaction ( ) + «get» CurrentTransaction ( ) : IDbTransaction + ExecuteTransactedNonQuery ( [in] cmd : IDbCommand ) : int + CreateCommand ( ) : IDbCommand + CreateCommand ( [in] inTransaction : bool ) : IDbCommand + CreateParameter ( [in] name : string , [in] value : object ) : IDataParameter + CreateParameter ( [in] name : string , [in] tp : DbType , [in] value : object ) : IDataParameter + ExecuteQuery ( [in] cmd : IDbCommand ) : DataSet
  • 82. : Actor1 / UI : ContractMapper : DBFactory : BaseStrategy 1 : Form_Load 2 : LoadAll ( ) 3 : CreateDBHelper ( ) 4 : new : IDBHelper 5 : ExecuteQuery ( cmd ) 6 : ApplyMap ( dsContractAnd Recognitions ) 7 : [currentrow.Id != current Contract.ID] new : Contract 8 : SetID ( id ) 9 : SetProduct ( prodID , prodType ) 10 : SetStrategy ( prodType ) 11 : CreateStrategy ( prodType , c ) 12 : AddRecognition ( recognitionDate , amount ) foreach returned recognition 81 ISEP/IP P
  • 83. protected Contract ApplyMap(DataSet dsCNR) { if (dsCNR].Rows.Count < 1) return null; Contract c = new Contract(); c.DateSigned = (DateTime)dsCNR.Tables[0].Rows[0][quot;Datesignedquot;]; c.Revenue = (decimal)dsCNR.Tables[0].Rows[0][quot;Revenuequot;]; c.SetID( (int)dsCNR.Tables[0].Rows[0][quot;IDquot;] ); c.SetProduct( (int) dsCNR.Tables[0].Rows[0][quot;ProductIDquot;], (string) dsCNR.Tables[0].Rows[0][quot;ProdTypequot;] ); c.SetCustomer( (int)dsCNR.Tables[0].Rows[0][quot;CustomerIDquot;] ); foreach (DataRow r in dsCNR.Tables[0].Rows) { c.AddRecognition( (DateTime)r[quot;dateRecognitionquot;], (decimal)r[quot;amountquot;]); } return c; }
  • 84. public class Contract { // !!! to be used only by Mapper internal void SetProduct(int prodID, string prodType) { _ProductID = prodID; SetStrategy(prodType); } private void SetStrategy(string prodType) { theStrategy = BaseStrategy.CreateStrategy(prodType, this); } } 83
  • 85. public abstract class BaseStrategy { protected Contract theContract; public BaseStrategy(Contract c) { theContract = c; } public static IRevenueRecognitionStrategy CreateStrategy( string prodType, Contract c) { switch (prodType) { case quot;PTquot;: return new Strategies.PTStrategy(c); break; case quot;FCquot;: return new Strategies.FCStrategy(c); break; case quot;BDquot;: return new Strategies.BDStrategy(c); break; default: throw new ApplicationException(quot;invalid typequot;); } return null; } }
  • 86. : Actor1 / UI / c : Contract : IRevenueRecognitionStrategy : ContractMapper : DBFactory 1 : btnCalc_Click 2 : CalculateRevenueRecognitions ( ) 3 : CalculateRevenueRecognitions ( ) 4 : AddRecognition ( recognitionDate , amount ) foreach recognized revenue 5 : Save ( c ) 6 : CreateDBHelper ( ) 7 : new : IDBHelper 8 : BeginTransaction ( ) 9 : ExecuteTransactedNonQuery ( cmd ) 10 : ExecuteTransactedNonQuery ( foreach recognized revenue cmd ) 11 : CommitTransaction ( ) 85 ISEP/IP P
  • 87. public void CalculateRevenueRecognitions() { _RevenueRecognitions.Clear(); theStrategy.CalculateRevenueRecognitions(); } // !!! to be used by strategies internal void AddRecognition(DateTime recognitionDate, decimal amount) { _RevenueRecognitions.Add( new RevenueRecognition(recognitionDate, amount) ); }
  • 88. public class BDStrategy : BaseStrategy { public void CalculateRevenueRecognitions() { decimal[] allocs = Money.Allocate(theContract.Revenue, 3); theContract.AddRecognition(theContract.DateSigned, allocs[0]); theContract.AddRecognition(theContract.DateSigned.AddDays(30), allocs[1]); theContract.AddRecognition(theContract.DateSigned.AddDays(60), allocs[2]); } } public class FCStrategy : BaseStrategy { public void CalculateRevenueRecognitions() { decimal[] allocs = Money.Allocate(theContract.Revenue, 3); theContract.AddRecognition(theContract.DateSigned, allocs[0]); theContract.AddRecognition(theContract.DateSigned.AddDays(60), allocs[1]); theContract.AddRecognition(theContract.DateSigned.AddDays(90), allocs[2]); } } public class PTStrategy : BaseStrategy { public void CalculateRevenueRecognitions() { theContract.AddRecognition(theContract.DateSigned, theContract.Revenue); } }
  • 91. Pattern Prevents conflicts between concurrent business transactions by detecting a conflict and rolling back the transaction 90
  • 92. Pattern fonte: Patterns of Enterprise Application Architecture
  • 93. Pattern Prevents conflicts between concurrent business transactions by allowing only one business transaction at a time to access data 92
  • 94. Pattern fonte: Patterns of Enterprise Application Architecture
  • 96. Pattern GoF Problem: You need a set of related classes but there are several sets with different implementations Solution: Create a service interface, create several implementations of those services, create a factory class for each set of implementations, provide the client with the correct implementation behind the interface
  • 97. Pattern GoF Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
  • 98. Pattern GoF fonte: Design Patterns: Elements of Reusable Object-Oriented Software
  • 99. fonte: Microsoft .Net Pet Shop 3.x
  • 101. public class PersonDataAccess { public PersonDataAccess() { ... } public bool Insert(object r) { ... } public bool Delete(object r) { ... } public bool Update(object r) { ... } public object Load(object id) { ... } } Add logging to this existing class
  • 102. public class PersonDataAccess { public PersonWithLogDataAccess() { ... } public bool Insert(object r) { ... Log.Write(...); } public bool Delete(object r) { ... } public bool Update(object r) What if instead of { ... } logging you public object Load(object id) needed billing? { ... } }
  • 103. public class PersonWithLogDataAccess : PersonDataAcess { public PersonWithLogDataAccess() { ... } public bool Insert(object r) { base.Insert(r); logFile.Write(...); } public bool Delete(object r) { ... } public bool Update(object r) What if you { ... } needed logging public object Load(object id) and billing? { ... } }
  • 104. Pattern GoF Problem: Allow functionally to be layered around an abstraction, but still dynamically changeable. Solution: Combine inheritance and composition. By making an object that both subclasses from anther class and holds an instance of the class, can add new behavior while referring all other behavior to the original class.
  • 105. Pattern GoF Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. fonte: Design Patterns: Elements of Reusable Object-Oriented Software
  • 106. public interface IDataAccess { public bool Insert(object r); public bool Delete(object r); public bool Update(object r); public object Load(object id); }
  • 107. public class PersonDataAccess : IDataAccess { public PersonDataAccess () { ... } public bool Insert(object r) { ... } public bool Delete(object r) { ... } public bool Update(object r) { ... } public object Load(object id) { ... } }
  • 108. public class LoggingDecorator : IDataAccess { IDataAccess component; public LoggingDecorator(IDataAccess component) { this.component = component; } public bool Insert(object r) { WriteLog(quot;Insertquot;, r); return component.Insert(r); } public bool Delete(object r) { ... } public bool Update(object r) { ... } public object Load(object id) { ... } private void WriteLog(string op, object parms) { ... } }
  • 109. public class TesteDecorator { public void Teste() { IDataAccess da = new PersonIDataAccess (); IDataAccess dec = new LoggingDecorator(da); ... dec.Insert(...); ... } }
  • 110. Since the Decorator class implements the same interface of the Component, it can be used anywhere you would use a Component Inheritance wouldn’t allow scenarios with only Logging or only billing or both But you can chain Decorators!
  • 111. public class CounterDecorator : IDataAccess { int nAcessos = 0; IDataAccess component; public CounterDecorator(IDataAccess component) { this.component = component; } public bool Insert(object r) { nAcessos++; return component.Insert(r); } public bool Delete(object r) { ... } public bool Update(object r) { ... } public object Load(object id) { ... } public int NumOfAccesses { get { return nAcessos; } } }
  • 112. public class BillingDAL { public void Teste() { IDataAccess da = new PersonDataAccess(); IDataAccess dec = new LoggingDecorator(da); IDataAccess cd = new CounterDecorator(dec); ... cd.Insert(...); ... CounterDecorator bil = (CounterDecorator)cd; float custo = bil.NumOfAccesses * PRICE_PER_OP; ... } }
  • 113. Part 7
  • 114. ... Pattern ... ... Java/C#... Adapter ... Domain model ... ???? ... ... Java/C#... ??? ????
  • 115. ... Pattern ... ... Java/C#... Adapter ... Domain model ... ... Pattern ... ... Java/C#... Adapter ... Domain model ...
  • 116. Architectural style output Business operations http://w2ks.dei.isep.ipp.pt/psousa/GetFile.aspx?file=PoEAAWorkbench.zip
  • 117. public interface IRevenueRecognition { Money RecognizedRevenue(int contractID, DateTime asOf); void CalculateRevenueRecognitions(int contractID); object GetContracts(); object GetCustomers(); object GetProducts(); }
  • 118. common RevenueGUI RevenueFacade Implementations
  • 119. A combination of a Factory, a Singleton and a Façade The desired implementation is loaded into memory and an instance of the specific façade is created (reflection) and returned to the GUI The UI layer will then interact with the business layer via the IRevenueRecognition business interface ignoring the actual implementation
  • 120. Each implementation shows a combination of patterns that form an architectural style Table module + table data gateway Domain model / active record These are the Domain model + data mapper classes the students must “look” … Define the business classes and data access classes necessary to support the application requirements defined by the business interface
  • 121. Transaction Script using DataSet Transaction Script Transaction Script + Data Gateway Transaction Script using Custom Classes Transaction Script Transaction Script + Row Data Gateway Table Module Table Module + Table Data Gateway (DataSet) Table Module + Table Data Gateway (Custom Classes) Domain Model Domain Model + Active Record Domain Model + Data Mapper
  • 122. Part 8
  • 124. Pattern An object that encapsulate the code that implements the consumer portion of a contract. They act as proxies to other services, encapsulating the details of connecting to the source and performing any necessary translation. fonte: Enterprise Solution Patterns Using .NET
  • 125. Pattern Hides the details of accessing the service (ex., network protocol) May be considered a data access component Native support from most tools (e.g., Visual Studio, Netbeans, Rational software Architect) by web service proxies
  • 126. Pattern Provides a coarse-grained façade on fine- grained objects to improve efficiency over a network fonte: Patterns of Enterprise Application Architecture
  • 127. Pattern Domain object interfaces are tipically fine grained Inadequeate for remote operations Create a surronding layer above domain objects Local clients use the local interface The facade may encapsulate the interface of one or more business objects Domain objects: Address.New Address.Set Person.AddAddress Person.Update Remote Facade: AddressFacade.AddNewAddressToPerson
  • 128. Pattern An object that carries data between processes in order to reduce the number of method calls. fonte: Patterns of Enterprise Application Architecture
  • 129. Pattern Since XML is the de facto standard DTO should support serialization to/from XML Should be independent of the underlying domain object Should be implemented in accordance with the requiremnts of the remote application CompleteCustomerInfoDTO BasicCustomerInfoDTO Should be independent of the underlying platform (e.g., programming language) DataSet/DataTable .net ResultSet JDBC DateTime .net
  • 130. Pattern Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation fonte: Patterns of Enterprise Application Architecture
  • 131. Pattern Domain logic pattern in the context of service orientation May be implemented as a Remote Facade or may be called by a Remote Facade
  • 132. Pattern Hides the complexity of finding and creating service gateways fonte: Core J2EE Patterns
  • 133. Part 9
  • 134. How to represent the business entities? How to persist its state? How to code the Business logic? How to guarantee data coherence? How to handle application distribution?
  • 135. Simple to complex logic and good platform support for Result Sets Table Module Complex logic Domain Model 134
  • 136. Table Module Table Data Gateway Domain Model very similar to DB schema Active Record Complex Domain Model Data Mapper
  • 137. Guarantee that in-memory data is only updated in one place Identity Map Mantain a relation between in-memory objects and database records Identity field Avoid loading the entire DB to memory Lazy Load 136
  • 138. Hibernate e nHibernate www.hibernate.org LINQ http://msdn.microsoft.com/en-us/netframework/aa904594.aspx JDO http://java.sun.com/products/jdo/ SDO http://www.osoa.org/display/Main/Service+Data+Objects+Home EJB 3 http://java.sun.com/products/ejb/ Apache Cayenne http://cayenne.apache.org/ FastObjects j2 http://www.versant.net/eu_en/products/fastobjects_j2/ FastObjects.NET http://www.versant.net/eu_en/products/fastobjects_net/ Prevayler http://www.prevayler.org/wiki.jsp
  • 139. Only in data access layer Don’t forget Views Balance dynamic SQL and stored procedures Flexibility Security Easyest implementation for some business logic (e.g., group operations) 138
  • 140. Use parameters instead of string concatenation DELETE is uncommon INSERT causes no locking problem Must be careful on UPDATE Concurrent access Incremental update E.g. Update quantity on hand UPDATE Products SET QtyOnHand = 10 UPDATE Products SET QtyOnHand = QtyOnHand + 2
  • 141. Good scalability and user-centered availability Optimistic Lock User cannot loose changes Pessimistic Lock
  • 142. How to pass objects in a remote call? Data Transfer Object How to remotely use objects with “fine grained” interface? Remote Façade How to define a coherent set of operations? Service Layer / Service Interface How to hide the implementation details of the remote call? Service Gateway 141
  • 143. Patterns are a good thing Patterns can be difficult Driven by example Will make it easier 142
  • 144. Fell free to download the PoEAA Workbench http://w2ks.dei.isep.ipp.pt/psousa/GetFile.aspx ?file=PoEAAWorkbench.zip Slides available thru SlideShare http://www.slideshare.net/pagsousa 143
  • 145. Paulo Sousa pag@isep.ipp.pt http://linkedin.com/in/pagsousa
  • 147.
  • 148. Fowler, Martin. Patterns of Enterprise Application Architecture. Adisson-Wesley. Erich Gamma, Richard Helm, Ralph Johnson, John Vissides. Design patterns : elements of reusable object-oriented software. Adisson-Wesley. Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal. Pattern- oriented Software Architecture: System of Patterns. Buschmann, F.; Henney, K. And Schmidt, D. (2007) Pattern-Oriented Software Architecture: A Pattern Language for Distributed Computing, Volume 4. Willey. Deepak Alur, John Crupi and Dan Malks. Core J2EE Patterns: Best Practices and Design Strategies. Prentice Hall / Sun Microsystems Press. http://java.sun.com/blueprints/corej2eepatterns/index.html Enterprise Solution Patterns Using Microsoft .NET. Microsoft Press. http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en- us/dnpatterns/html/Esp.asp Designing Data Tier Components and Passing Data Through Tiers. Microsoft Patterns & Practices. http://msdn.microsoft.com/library/?url=/library/en- us/dnbda/html/BOAGag.asp?frame=true 147
  • 149. GoF Design patterns (em C#) http://www.dofactory.com/Patterns/Patterns.aspx GoF & POSA Design patterns (em Java) http://www.vico.org/pages/PatronsDisseny.html Patterns of Enterprise Application architecture http://martinfowler.com/eaaCatalog/ Core J2EE Patterns http://www.corej2eepatterns.com Enterprise Solution Patterns Using Microsoft .NET. http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en- us/dnpatterns/html/Esp.asp Patterns of Enterprise Application Integration http://www.enterpriseintegrationpatterns.com/ Enterprise Java Patterns @ The Server Side http://www.theserverside.com/patterns/index.tss Microsoft Data Patterns http://msdn.microsoft.com/architecture/patterns/default.aspx?pull=/library/en- us/dnpatterns/html/Dp.asp